Searcher related refactoring:

* Searcher moved form Plater to Gui_App
This commit is contained in:
YuSanka 2023-10-19 14:35:31 +02:00
parent 9926181008
commit fa86a3d047
14 changed files with 124 additions and 156 deletions

View File

@ -142,7 +142,7 @@ void Field::PostInitialize()
#else /* __APPLE__ */
case WXK_CONTROL_F:
#endif /* __APPLE__ */
case 'F': { wxGetApp().plater()->search(false); break; }
case 'F': { wxGetApp().show_search_dialog(); break; }
default: break;
}
if (tab_id >= 0)

View File

@ -4765,7 +4765,12 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x)
// Getter for the const char*[] for the search list
static bool search_string_getter(int idx, const char** label, const char** tooltip)
{
return wxGetApp().plater()->search_string_getter(idx, label, tooltip);
const Search::OptionsSearcher& search_list = wxGetApp().searcher();
if (0 <= idx && (size_t)idx < search_list.size()) {
search_list[idx].get_marked_label_and_tooltip(label, tooltip);
return true;
}
return false;
}
bool GLCanvas3D::_render_search_list(float pos_x)
@ -4784,14 +4789,16 @@ bool GLCanvas3D::_render_search_list(float pos_x)
em *= m_retina_helper->get_scale_factor();
#endif // ENABLE_RETINA_GL
Sidebar& sidebar = wxGetApp().sidebar();
// update searcher before show imGui search dialog on the plater, if printer technology or mode was changed
wxGetApp().check_and_update_searcher(wxGetApp().get_mode());
Search::OptionsSearcher& searcher = wxGetApp().searcher();
std::string& search_line = sidebar.get_search_line();
std::string& search_line = searcher.search_string();
char *s = new char[255];
strcpy(s, search_line.empty() ? _u8L("Enter a search term").c_str() : search_line.c_str());
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
sidebar.get_searcher().view_params,
wxGetApp().searcher().view_params,
selected, edited, m_mouse_wheel, wxGetApp().is_localized());
search_line = s;
@ -4800,7 +4807,7 @@ bool GLCanvas3D::_render_search_list(float pos_x)
search_line.clear();
if (edited)
sidebar.search();
searcher.search();
if (selected >= 0) {
// selected == 9999 means that Esc kye was pressed
@ -4811,7 +4818,7 @@ bool GLCanvas3D::_render_search_list(float pos_x)
sidebar.jump_to_option(selected);*/
if (selected != 9999) {
imgui->end(); // end imgui before the jump to option
sidebar.jump_to_option(selected);
wxGetApp().jump_to_option(selected);
return true;
}
action_taken = true;

View File

@ -1094,6 +1094,61 @@ bool GUI_App::OnInit()
}
}
void GUI_App::check_and_update_searcher(ConfigOptionMode mode /*= comExpert*/)
{
std::vector<Search::InputInfo> search_inputs{};
auto print_tech = preset_bundle->printers.get_selected_preset().printer_technology();
for (auto tab : tabs_list)
if (tab->supports_printer_technology(print_tech))
search_inputs.emplace_back(Search::InputInfo{ tab->get_config(), tab->type() });
m_searcher.check_and_update(print_tech, mode, search_inputs);
}
void GUI_App::jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category)
{
get_tab(type)->activate_option(opt_key, category);
}
void GUI_App::jump_to_option(size_t selected)
{
const Search::Option& opt = m_searcher.get_option(selected);
if (opt.type == Preset::TYPE_PREFERENCES)
open_preferences(opt.opt_key(), boost::nowide::narrow(opt.group));
else
get_tab(opt.type)->activate_option(opt.opt_key(), boost::nowide::narrow(opt.category));
}
void GUI_App::jump_to_option(const std::string& composite_key)
{
const auto separator_pos = composite_key.find(";");
const std::string opt_key = composite_key.substr(0, separator_pos);
const std::string tab_name = composite_key.substr(separator_pos + 1, composite_key.length());
for (Tab* tab : tabs_list) {
if (tab->name() == tab_name) {
check_and_update_searcher();
// Regularly searcher is sorted in respect to the options labels,
// so resort searcher before get an option
m_searcher.sort_options_by_key();
const Search::Option& opt = m_searcher.get_option(opt_key, tab->type());
tab->activate_option(opt_key, boost::nowide::narrow(opt.category));
// Revert sort of searcher back
m_searcher.sort_options_by_label();
break;
}
}
}
void GUI_App::show_search_dialog()
{
check_and_update_searcher(get_mode());
m_searcher.show_dialog();
}
static int get_app_font_pt_size(const AppConfig* app_config)
{
if (!app_config->has("font_pt_size"))

View File

@ -12,6 +12,7 @@
#include "ConfigWizard.hpp"
#include "OpenGLManager.hpp"
#include "libslic3r/Preset.hpp"
#include "Search.hpp"
#include <wx/app.h>
#include <wx/colour.h>
@ -175,6 +176,8 @@ private:
std::string m_instance_hash_string;
size_t m_instance_hash_int;
Search::OptionsSearcher m_searcher;
public:
bool OnInit() override;
bool initialized() const { return m_initialized; }
@ -188,6 +191,14 @@ public:
bool is_recreating_gui() const { return m_is_recreating_gui; }
std::string logo_name() const { return is_editor() ? "PrusaSlicer" : "PrusaSlicer-gcodeviewer"; }
Search::OptionsSearcher& searcher() noexcept { return m_searcher; }
void check_and_update_searcher(ConfigOptionMode mode = comExpert);
void jump_to_option(size_t selected);
void jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category);
// jump to option which is represented by composite key : "opt_key;tab_name"
void jump_to_option(const std::string& composite_key);
void show_search_dialog();
// To be called after the GUI is fully built up.
// Process command line parameters cached in this->init_params,
// load configs, STLs etc.

View File

@ -13,6 +13,7 @@
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#include "slic3r/GUI/format.hpp"
#include "slic3r/GUI/Field.hpp"
#include "slic3r/Utils/UndoRedo.hpp"
#include "libslic3r/AppConfig.hpp"
#include "libslic3r/TriangleMeshSlicer.hpp"

View File

@ -424,7 +424,7 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
std::string opt = dict["hypertext_settings_opt"];
Preset::Type type = static_cast<Preset::Type>(std::atoi(dict["hypertext_settings_type"].c_str()));
std::wstring category = boost::nowide::widen(dict["hypertext_settings_category"]);
HintData hint_data{ id_string, text1, weight, was_displayed, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } };
HintData hint_data{ id_string, text1, weight, was_displayed, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().jump_to_option(opt, type, category); } };
m_loaded_hints.emplace_back(hint_data);
// open preferences
} else if(dict["hypertext_type"] == "preferences") {

View File

@ -288,6 +288,11 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
preferences_dialog = new PreferencesDialog(this);
}
if (wxGetApp().is_editor()) {
// jump to found option from SearchDialog
Bind(wxCUSTOMEVT_JUMP_TO_OPTION, [this](wxCommandEvent& evt) { wxGetApp().jump_to_option(evt.GetInt()); });
}
}
#ifdef _MSW_DARK_MODE
@ -1054,6 +1059,8 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
this->SetSize(sz);
this->Maximize(is_maximized);
wxGetApp().searcher().dlg_msw_rescale();
}
void MainFrame::on_sys_color_changed()
@ -1083,6 +1090,8 @@ void MainFrame::on_sys_color_changed()
MenuFactory::sys_color_changed(m_menubar);
this->Refresh();
wxGetApp().searcher().dlg_sys_color_changed();
}
void MainFrame::update_mode_markers()
@ -1437,7 +1446,7 @@ void MainFrame::init_menubar_as_editor()
editMenu->AppendSeparator();
append_menu_item(editMenu, wxID_ANY, _L("Searc&h") + "\tCtrl+F",
_L("Search in settings"), [this](wxCommandEvent&) { m_plater->search(m_plater->IsShown()); },
_L("Search in settings"), [this](wxCommandEvent&) { m_plater->IsShown() ? m_plater->search() : wxGetApp().show_search_dialog(); },
"search", nullptr, []() {return true; }, this);
}
@ -2138,7 +2147,7 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
#else /* __APPLE__ */
case WXK_CONTROL_F:
#endif /* __APPLE__ */
case 'F': { m_main_frame->plater()->search(false); break; }
case 'F': { wxGetApp().show_search_dialog(); break; }
default:break;
}
}

View File

@ -708,7 +708,7 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index
m_opt_map.emplace(opt_id, pair);
if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab
wxGetApp().sidebar().get_searcher().add_key(opt_id, static_cast<Preset::Type>(this->config_type()), title, this->config_category());
wxGetApp().searcher().add_key(opt_id, static_cast<Preset::Type>(this->config_type()), title, this->config_category());
return Option(*m_config->def()->get(opt_key), opt_id);
}

View File

@ -704,7 +704,6 @@ struct Sidebar::priv
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
bool is_collapsed {false};
Search::OptionsSearcher searcher;
priv(Plater *plater) : plater(plater) {}
~priv();
@ -1187,8 +1186,6 @@ void Sidebar::msw_rescale()
p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height));
p->scrolled->Layout();
p->searcher.dlg_msw_rescale();
}
void Sidebar::sys_color_changed()
@ -1228,8 +1225,6 @@ void Sidebar::sys_color_changed()
p->scrolled->Layout();
p->scrolled->Refresh();
p->searcher.dlg_sys_color_changed();
}
void Sidebar::update_mode_markers()
@ -1238,49 +1233,6 @@ void Sidebar::update_mode_markers()
p->mode_sizer->update_mode_markers();
}
void Sidebar::search()
{
p->searcher.search();
}
void Sidebar::jump_to_option(const std::string& composite_key)
{
const auto separator_pos = composite_key.find(";");
const std::string opt_key = composite_key.substr(0, separator_pos);
const std::string tab_name = composite_key.substr(separator_pos + 1, composite_key.length());
for (Tab* tab : wxGetApp().tabs_list) {
if (tab->name() == tab_name) {
check_and_update_searcher(true);
// Regularly searcher is sorted in respect to the options labels,
// so resort searcher before get an option
p->searcher.sort_options_by_key();
const Search::Option& opt = p->searcher.get_option(opt_key, tab->type());
tab->activate_option(opt_key, boost::nowide::narrow(opt.category));
// Revert sort of searcher back
p->searcher.sort_options_by_label();
break;
}
}
}
void Sidebar::jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category)
{
//const Search::Option& opt = p->searcher.get_option(opt_key, type);
wxGetApp().get_tab(type)->activate_option(opt_key, category);
}
void Sidebar::jump_to_option(size_t selected)
{
const Search::Option& opt = p->searcher.get_option(selected);
if (opt.type == Preset::TYPE_PREFERENCES)
wxGetApp().open_preferences(opt.opt_key(), boost::nowide::narrow(opt.group));
else
wxGetApp().get_tab(opt.type)->activate_option(opt.opt_key(), boost::nowide::narrow(opt.category));
}
ObjectManipulation* Sidebar::obj_manipul()
{
return p->object_manipulation;
@ -1568,20 +1520,6 @@ bool Sidebar::is_multifilament()
return p->combos_filament.size() > 1;
}
void Sidebar::check_and_update_searcher(bool respect_mode /*= false*/)
{
std::vector<Search::InputInfo> search_inputs{};
auto& tabs_list = wxGetApp().tabs_list;
auto print_tech = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
for (auto tab : tabs_list)
if (tab->supports_printer_technology(print_tech))
search_inputs.emplace_back(Search::InputInfo{ tab->get_config(), tab->type() });
p->searcher.check_and_update(wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(),
respect_mode ? m_mode : comExpert, search_inputs);
}
void Sidebar::update_mode()
{
m_mode = wxGetApp().get_mode();
@ -1640,18 +1578,6 @@ std::vector<PlaterPresetComboBox*>& Sidebar::combos_filament()
return p->combos_filament;
}
Search::OptionsSearcher& Sidebar::get_searcher()
{
return p->searcher;
}
std::string& Sidebar::get_search_line()
{
// update searcher before show imGui search dialog on the plater, if printer technology or mode was changed
check_and_update_searcher(true);
return p->searcher.search_string();
}
// Plater::DropTarget
class PlaterDropTarget : public wxFileDropTarget
@ -2171,8 +2097,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
sidebar->Bind(wxEVT_COMBOBOX, &priv::on_select_preset, this);
sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); });
sidebar->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); });
// jump to found option from SearchDialog
q->Bind(wxCUSTOMEVT_JUMP_TO_OPTION, [this](wxCommandEvent& evt) { sidebar->jump_to_option(evt.GetInt()); });
}
wxGLCanvas* view3D_canvas = view3D->get_wxglcanvas();
@ -6803,7 +6727,7 @@ void Plater::export_gcode(bool prefer_removable)
wxString error_str;
if (check_for_error(output_path, error_str)) {
ErrorDialog(this, error_str, [this](const std::string& key) -> void { sidebar().jump_to_option(key); }).ShowModal();
ErrorDialog(this, error_str, [](const std::string& key) -> void { wxGetApp().jump_to_option(key); }).ShowModal();
output_path.clear();
} else {
alert_when_exporting_binary_gcode(wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary"),
@ -7361,7 +7285,7 @@ void Plater::send_gcode()
const bool binary_output = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary");
const wxString error_str = check_binary_vs_ascii_gcode_extension(printer_technology(), ext, binary_output);
if (! error_str.IsEmpty()) {
ErrorDialog(this, error_str, t_kill_focus([](const std::string& key) -> void { wxGetApp().sidebar().jump_to_option(key); })).ShowModal();
ErrorDialog(this, error_str, t_kill_focus([](const std::string& key) -> void { wxGetApp().jump_to_option(key); })).ShowModal();
return;
}
}
@ -7446,18 +7370,6 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
out_text = "";
}
bool Plater::search_string_getter(int idx, const char** label, const char** tooltip)
{
const Search::OptionsSearcher& search_list = p->sidebar->get_searcher();
if (0 <= idx && (size_t)idx < search_list.size()) {
search_list[idx].get_marked_label_and_tooltip(label, tooltip);
return true;
}
return false;
}
void Plater::on_extruders_change(size_t num_extruders)
{
auto& choices = sidebar().combos_filament();
@ -8014,9 +7926,8 @@ void Plater::paste_from_clipboard()
p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
}
void Plater::search(bool plater_is_active)
void Plater::search()
{
if (plater_is_active) {
if (is_preview_shown())
return;
// plater should be focused for correct navigation inside search window
@ -8031,11 +7942,6 @@ void Plater::search(bool plater_is_active)
evt.SetControlDown(true);
canvas3D()->on_char(evt);
}
else {
p->sidebar->check_and_update_searcher(true);
p->sidebar->get_searcher().show_dialog();
}
}
void Plater::msw_rescale()
{

View File

@ -31,7 +31,8 @@
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "Jobs/Job.hpp"
#include "Jobs/Worker.hpp"
#include "Search.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
class wxButton;
class ScalableButton;
@ -99,11 +100,6 @@ public:
void msw_rescale();
void sys_color_changed();
void update_mode_markers();
void search();
void jump_to_option(size_t selected);
void jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category);
// jump to option which is represented by composite key : "opt_key;tab_name"
void jump_to_option(const std::string& composite_key);
ObjectManipulation* obj_manipul();
ObjectList* obj_list();
@ -130,7 +126,6 @@ public:
void update_mode();
bool is_collapsed();
void collapse(bool collapse);
void check_and_update_searcher(bool respect_mode = false);
void update_ui_from_settings();
#ifdef _MSW_DARK_MODE
@ -138,8 +133,6 @@ public:
#endif
std::vector<PlaterPresetComboBox*>& combos_filament();
Search::OptionsSearcher& get_searcher();
std::string& get_search_line();
private:
struct priv;
@ -320,7 +313,6 @@ public:
void redo_to(int selection);
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
bool search_string_getter(int idx, const char** label, const char** tooltip);
// For the memory statistics.
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
void clear_undo_redo_stack_main();
@ -368,7 +360,7 @@ public:
void copy_selection_to_clipboard();
void paste_from_clipboard();
void search(bool plater_is_active);
void search();
void mirror(Axis axis);
void split_object();
void split_volume();

View File

@ -191,7 +191,7 @@ static void activate_options_tab(std::shared_ptr<ConfigOptionsGroup> optgroup)
optgroup->parent()->Layout();
// apply sercher
wxGetApp().sidebar().get_searcher().append_preferences_options(optgroup->get_lines());
wxGetApp().searcher().append_preferences_options(optgroup->get_lines());
}
static void append_bool_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
@ -210,7 +210,7 @@ static void append_bool_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
optgroup->append_single_option_line(option);
// fill data to the Search Dialog
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
wxGetApp().searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
}
template<typename EnumType>
@ -233,17 +233,18 @@ static void append_enum_option( std::shared_ptr<ConfigOptionsGroup> optgroup,
optgroup->append_single_option_line(option);
// fill data to the Search Dialog
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
wxGetApp().searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
}
static void append_preferences_option_to_searcher(std::shared_ptr<ConfigOptionsGroup> optgroup,
const std::string& opt_key,
const wxString& label)
{
Search::OptionsSearcher& searcher = wxGetApp().searcher();
// fill data to the Search Dialog
wxGetApp().sidebar().get_searcher().add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
searcher.add_key(opt_key, Preset::TYPE_PREFERENCES, optgroup->config_category(), L("Preferences"));
// apply sercher
wxGetApp().sidebar().get_searcher().append_preferences_option(Line(opt_key, label, ""));
searcher.append_preferences_option(Line(opt_key, label, ""));
}
void PreferencesDialog::build()

View File

@ -16,7 +16,7 @@
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "Mainframe.hpp"
#include "Tab.hpp"
#define FTS_FUZZY_MATCH_IMPLEMENTATION
@ -352,24 +352,10 @@ void OptionsSearcher::append_preferences_option(const GUI::Line& opt_line)
void OptionsSearcher::append_preferences_options(const std::vector<GUI::Line>& opt_lines)
{
//Preset::Type type = Preset::TYPE_PREFERENCES;
for (const GUI::Line& line : opt_lines) {
if (line.is_separator())
continue;
append_preferences_option(line);
//wxString label = line.label;
//if (label.IsEmpty())
// continue;
//std::string key = get_key(line.get_options().front().opt_id, type);
//const GroupAndCategory& gc = groups_and_categories[key];
//if (gc.group.IsEmpty() || gc.category.IsEmpty())
// continue;
//
//preferences_options.emplace_back(Search::Option{ boost::nowide::widen(key), type,
// label.ToStdWstring(), _(label).ToStdWstring(),
// gc.group.ToStdWstring(), _(gc.group).ToStdWstring(),
// gc.category.ToStdWstring(), _(gc.category).ToStdWstring() });
}
}
@ -617,7 +603,7 @@ void SearchDialog::ProcessSelection(wxDataViewItem selection)
// So, post event to plater:
wxCommandEvent event(wxCUSTOMEVT_JUMP_TO_OPTION);
event.SetInt(search_list_model->GetRow(selection));
wxPostEvent(GUI::wxGetApp().plater(), event);
wxPostEvent(GUI::wxGetApp().mainframe, event);
}
void SearchDialog::OnInputText(wxCommandEvent&)

View File

@ -229,7 +229,7 @@ void Tab::create_preset_tab()
if (dlg.ShowModal() == wxID_OK)
wxGetApp().update_label_colours();
});
m_search_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent) { wxGetApp().plater()->search(false); });
m_search_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent) { wxGetApp().show_search_dialog(); });
// Colors for ui "decoration"
m_sys_label_clr = wxGetApp().get_label_clr_sys();
@ -4980,7 +4980,7 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
// may be it is not a best place, but
// add information about Category/Grope for "bed_custom_texture" and "bed_custom_model" as a copy from "bed_shape" option
{
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
Search::OptionsSearcher& searcher = wxGetApp().searcher();
const Search::GroupAndCategory& gc = searcher.get_group_and_category("bed_shape");
searcher.add_key("bed_custom_texture", m_type, gc.group, gc.category);
searcher.add_key("bed_custom_model", m_type, gc.group, gc.category);

View File

@ -1254,8 +1254,8 @@ void UnsavedChangesDialog::update(Preset::Type type, PresetCollection* dependent
void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* presets_, const std::string& new_selected_preset)
{
// update searcher befofre update of tree
wxGetApp().sidebar().check_and_update_searcher();
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
wxGetApp().check_and_update_searcher();
Search::OptionsSearcher& searcher = wxGetApp().searcher();
searcher.sort_options_by_key();
// list of the presets with unsaved changes
@ -1774,8 +1774,8 @@ void DiffPresetDialog::update_bottom_info(wxString bottom_info)
void DiffPresetDialog::update_tree()
{
// update searcher before update of tree
wxGetApp().sidebar().check_and_update_searcher();
Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher();
wxGetApp().check_and_update_searcher();
Search::OptionsSearcher& searcher = wxGetApp().searcher();
searcher.sort_options_by_key();
m_tree->Clear();