+ _dkdm->DeleteAllItems();
+ _dkdm_id.clear();
+ add_dkdm_to_view(Config::instance()->dkdms());
+ if (_selected_dkdm) {
+ auto selection_in_id_map = std::find_if(_dkdm_id.begin(), _dkdm_id.end(), [this](pair<wxTreeItemId, shared_ptr<DKDMBase>> const& entry) {
+ return entry.second == _selected_dkdm;
+ });
+ if (selection_in_id_map != _dkdm_id.end()) {
+ _dkdm->SelectItem(selection_in_id_map->first);
+ }
+ }
+ }
+
+ /** @return true if this thing or any of its children match a search string */
+ bool matches(shared_ptr<DKDMBase> base, string const& search)
+ {
+ if (search.empty()) {
+ return true;
+ }
+
+ auto name = base->name();
+ transform(name.begin(), name.end(), name.begin(), ::tolower);
+ if (name.find(search) != string::npos) {
+ return true;
+ }
+
+ auto group = dynamic_pointer_cast<DKDMGroup>(base);
+ if (!group) {
+ return false;
+ }
+
+ auto const children = group->children();
+ return std::any_of(children.begin(), children.end(), [this, search](shared_ptr<DKDMBase> child) {
+ return matches(child, search);
+ });
+ }
+
+ /** Add DKDMs to the view that match the current search */
+ void add_dkdm_to_view(shared_ptr<DKDMBase> base)
+ {
+ auto search = wx_to_std(_dkdm_search->GetValue());
+ transform(search.begin(), search.end(), search.begin(), ::tolower);
+
+ optional<wxTreeItemId> group_to_expand;
+