3434#include " core/string/fuzzy_search.h"
3535#include " editor/editor_file_system.h"
3636#include " editor/editor_node.h"
37+ #include " editor/editor_paths.h"
3738#include " editor/editor_resource_preview.h"
3839#include " editor/editor_settings.h"
3940#include " editor/editor_string_names.h"
@@ -187,6 +188,7 @@ QuickOpenResultContainer::QuickOpenResultContainer() {
187188 set_h_size_flags (Control::SIZE_EXPAND_FILL);
188189 set_v_size_flags (Control::SIZE_EXPAND_FILL);
189190 add_theme_constant_override (" separation" , 0 );
191+ history_file.instantiate ();
190192
191193 {
192194 // Results section
@@ -316,6 +318,7 @@ void QuickOpenResultContainer::init(const Vector<StringName> &p_base_types) {
316318
317319 const int display_mode_behavior = EDITOR_GET (" filesystem/quick_open_dialog/default_display_mode" );
318320 const bool adaptive_display_mode = (display_mode_behavior == 0 );
321+ const bool first_open = never_opened;
319322
320323 if (adaptive_display_mode) {
321324 _set_display_mode (get_adaptive_display_mode (p_base_types));
@@ -335,12 +338,38 @@ void QuickOpenResultContainer::init(const Vector<StringName> &p_base_types) {
335338 E->enable_highlights = enable_highlights;
336339 }
337340
341+ if (first_open && history_file->load (_get_cache_file_path ()) == OK) {
342+ // Load history when opening for the first time.
343+ file_type_icons.insert (SNAME (" __default_icon" ), get_editor_theme_icon (SNAME (" Object" )));
344+
345+ List<String> history_keys;
346+ history_file->get_section_keys (" selected_history" , &history_keys);
347+ for (const String &type : history_keys) {
348+ const StringName type_name = type;
349+ const PackedStringArray paths = history_file->get_value (" selected_history" , type);
350+
351+ Vector<QuickOpenResultCandidate> loaded_candidates;
352+ loaded_candidates.resize (paths.size ());
353+ {
354+ QuickOpenResultCandidate *candidates_write = loaded_candidates.ptrw ();
355+ int i = 0 ;
356+ for (const String &path : paths) {
357+ filetypes.insert (path, type_name);
358+ QuickOpenResultCandidate candidate;
359+ _setup_candidate (candidate, path);
360+ candidates_write[i] = candidate;
361+ i++;
362+ }
363+ selected_history.insert (type, loaded_candidates);
364+ }
365+ }
366+ }
338367 _create_initial_results ();
339368}
340369
341370void QuickOpenResultContainer::_create_initial_results () {
342371 file_type_icons.clear ();
343- file_type_icons.insert (" __default_icon" , get_editor_theme_icon (SNAME (" Object" )));
372+ file_type_icons.insert (SNAME ( " __default_icon" ) , get_editor_theme_icon (SNAME (" Object" )));
344373 filepaths.clear ();
345374 filetypes.clear ();
346375 _find_filepaths_in_folder (EditorFileSystem::get_singleton ()->get_filesystem (), include_addons_toggle->is_pressed ());
@@ -381,21 +410,29 @@ void QuickOpenResultContainer::set_query_and_update(const String &p_query) {
381410 update_results ();
382411}
383412
384- void QuickOpenResultContainer::_setup_candidate (QuickOpenResultCandidate &candidate, const String &filepath) {
385- StringName actual_type = *filetypes.lookup_ptr (filepath);
386- candidate.file_path = filepath;
387- candidate.result = nullptr ;
413+ void QuickOpenResultContainer::_setup_candidate (QuickOpenResultCandidate &p_candidate, const String &p_filepath) {
414+ p_candidate.file_path = p_filepath;
415+ p_candidate.result = nullptr ;
388416
389- EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton ()->get_resource_preview_if_available (filepath);
417+ StringName actual_type;
418+ {
419+ StringName *actual_type_ptr = filetypes.lookup_ptr (p_filepath);
420+ if (actual_type_ptr) {
421+ actual_type = *actual_type_ptr;
422+ } else {
423+ ERR_PRINT (vformat (" EditorQuickOpenDialog: No type for path %s." , p_filepath));
424+ }
425+ }
426+ EditorResourcePreview::PreviewItem item = EditorResourcePreview::get_singleton ()->get_resource_preview_if_available (p_filepath);
390427 if (item.preview .is_valid ()) {
391- candidate .thumbnail = item.preview ;
428+ p_candidate .thumbnail = item.preview ;
392429 } else if (file_type_icons.has (actual_type)) {
393- candidate .thumbnail = *file_type_icons.lookup_ptr (actual_type);
430+ p_candidate .thumbnail = *file_type_icons.lookup_ptr (actual_type);
394431 } else if (has_theme_icon (actual_type, EditorStringName (EditorIcons))) {
395- candidate .thumbnail = get_editor_theme_icon (actual_type);
396- file_type_icons.insert (actual_type, candidate .thumbnail );
432+ p_candidate .thumbnail = get_editor_theme_icon (actual_type);
433+ file_type_icons.insert (actual_type, p_candidate .thumbnail );
397434 } else {
398- candidate .thumbnail = *file_type_icons.lookup_ptr (" __default_icon" );
435+ p_candidate .thumbnail = *file_type_icons.lookup_ptr (SNAME ( " __default_icon" ) );
399436 }
400437}
401438
@@ -611,6 +648,10 @@ void QuickOpenResultContainer::_toggle_fuzzy_search(bool p_pressed) {
611648 update_results ();
612649}
613650
651+ String QuickOpenResultContainer::_get_cache_file_path () const {
652+ return EditorPaths::get_singleton ()->get_project_settings_dir ().path_join (" quick_open_dialog_cache.cfg" );
653+ }
654+
614655void QuickOpenResultContainer::_toggle_include_addons (bool p_pressed) {
615656 EditorSettings::get_singleton ()->set (" filesystem/quick_open_dialog/include_addons" , p_pressed);
616657 cleanup ();
@@ -705,7 +746,7 @@ void QuickOpenResultContainer::save_selected_item() {
705746 }
706747
707748 const StringName &base_type = base_types[0 ];
708- const QuickOpenResultCandidate &selected = candidates[selection_index];
749+ QuickOpenResultCandidate &selected = candidates. write [selection_index];
709750 Vector<QuickOpenResultCandidate> *type_history = selected_history.lookup_ptr (base_type);
710751
711752 if (!type_history) {
@@ -720,11 +761,25 @@ void QuickOpenResultContainer::save_selected_item() {
720761 }
721762 }
722763
764+ selected.result = nullptr ;
723765 type_history->insert (0 , selected);
724- type_history->ptrw ()->result = nullptr ;
725766 if (type_history->size () > MAX_HISTORY_SIZE) {
726767 type_history->resize (MAX_HISTORY_SIZE);
727768 }
769+
770+ PackedStringArray paths;
771+ paths.resize (type_history->size ());
772+ {
773+ String *paths_write = paths.ptrw ();
774+
775+ int i = 0 ;
776+ for (const QuickOpenResultCandidate &candidate : *type_history) {
777+ paths_write[i] = candidate.file_path ;
778+ i++;
779+ }
780+ }
781+ history_file->set_value (" selected_history" , base_type, paths);
782+ history_file->save (_get_cache_file_path ());
728783}
729784
730785void QuickOpenResultContainer::cleanup () {
0 commit comments