2023-01-05 20:25:55 +08:00
/**************************************************************************/
/* editor_file_dialog.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 07:50:27 +08:00
2015-05-31 12:59:42 +08:00
# include "editor_file_dialog.h"
2019-07-25 17:09:57 +08:00
2022-02-12 09:46:22 +08:00
# include "core/config/project_settings.h"
2021-06-11 20:51:48 +08:00
# include "core/io/file_access.h"
2018-09-12 00:13:45 +08:00
# include "core/os/keyboard.h"
# include "core/os/os.h"
2017-12-02 08:37:32 +08:00
# include "dependency_editor.h"
2022-02-12 09:46:22 +08:00
# include "editor/editor_file_system.h"
2022-07-28 02:51:03 +08:00
# include "editor/editor_node.h"
2022-02-12 09:46:22 +08:00
# include "editor/editor_resource_preview.h"
# include "editor/editor_scale.h"
# include "editor/editor_settings.h"
2016-05-30 11:28:29 +08:00
# include "scene/gui/center_container.h"
2015-05-31 12:59:42 +08:00
# include "scene/gui/label.h"
# include "scene/gui/margin_container.h"
2022-11-19 19:45:49 +08:00
# include "scene/gui/option_button.h"
# include "scene/gui/separator.h"
# include "scene/gui/split_container.h"
# include "scene/gui/texture_rect.h"
2020-03-03 21:36:29 +08:00
# include "servers/display_server.h"
2015-05-31 12:59:42 +08:00
2020-04-02 07:20:12 +08:00
EditorFileDialog : : GetIconFunc EditorFileDialog : : get_icon_func = nullptr ;
EditorFileDialog : : GetIconFunc EditorFileDialog : : get_large_icon_func = nullptr ;
2015-05-31 12:59:42 +08:00
2020-04-02 07:20:12 +08:00
EditorFileDialog : : RegisterFunc EditorFileDialog : : register_func = nullptr ;
EditorFileDialog : : RegisterFunc EditorFileDialog : : unregister_func = nullptr ;
2015-05-31 12:59:42 +08:00
2020-07-12 00:45:19 +08:00
void EditorFileDialog : : popup_file_dialog ( ) {
popup_centered_clamped ( Size2 ( 1050 , 700 ) * EDSCALE , 0.8 ) ;
2022-01-03 17:08:03 +08:00
_focus_file_text ( ) ;
}
void EditorFileDialog : : _focus_file_text ( ) {
int lp = file - > get_text ( ) . rfind ( " . " ) ;
if ( lp ! = - 1 ) {
file - > select ( 0 , lp ) ;
file - > grab_focus ( ) ;
}
2020-07-12 00:45:19 +08:00
}
2015-05-31 12:59:42 +08:00
VBoxContainer * EditorFileDialog : : get_vbox ( ) {
return vbox ;
}
2022-09-01 23:52:49 +08:00
void EditorFileDialog : : _update_theme_item_cache ( ) {
ConfirmationDialog : : _update_theme_item_cache ( ) ;
theme_cache . parent_folder = get_theme_icon ( SNAME ( " ArrowUp " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . forward_folder = get_theme_icon ( SNAME ( " Forward " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . back_folder = get_theme_icon ( SNAME ( " Back " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . reload = get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . toggle_hidden = get_theme_icon ( SNAME ( " GuiVisibilityVisible " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . favorite = get_theme_icon ( SNAME ( " Favorites " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . mode_thumbnails = get_theme_icon ( SNAME ( " FileThumbnail " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . mode_list = get_theme_icon ( SNAME ( " FileList " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . favorites_up = get_theme_icon ( SNAME ( " MoveUp " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . favorites_down = get_theme_icon ( SNAME ( " MoveDown " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . folder = get_theme_icon ( SNAME ( " Folder " ) , SNAME ( " EditorIcons " ) ) ;
2022-09-07 01:09:32 +08:00
theme_cache . folder_icon_color = get_theme_color ( SNAME ( " folder_icon_color " ) , SNAME ( " FileDialog " ) ) ;
2022-09-01 23:52:49 +08:00
theme_cache . action_copy = get_theme_icon ( SNAME ( " ActionCopy " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . action_delete = get_theme_icon ( SNAME ( " Remove " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . filesystem = get_theme_icon ( SNAME ( " Filesystem " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . folder_medium_thumbnail = get_theme_icon ( SNAME ( " FolderMediumThumb " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . file_medium_thumbnail = get_theme_icon ( SNAME ( " FileMediumThumb " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . folder_big_thumbnail = get_theme_icon ( SNAME ( " FolderBigThumb " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . file_big_thumbnail = get_theme_icon ( SNAME ( " FileBigThumb " ) , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 0 ] = get_theme_icon ( " Progress1 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 1 ] = get_theme_icon ( " Progress2 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 2 ] = get_theme_icon ( " Progress3 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 3 ] = get_theme_icon ( " Progress4 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 4 ] = get_theme_icon ( " Progress5 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 5 ] = get_theme_icon ( " Progress6 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 6 ] = get_theme_icon ( " Progress7 " , SNAME ( " EditorIcons " ) ) ;
theme_cache . progress [ 7 ] = get_theme_icon ( " Progress8 " , SNAME ( " EditorIcons " ) ) ;
}
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : _notification ( int p_what ) {
2022-02-16 07:52:32 +08:00
switch ( p_what ) {
case NOTIFICATION_THEME_CHANGED :
case Control : : NOTIFICATION_LAYOUT_DIRECTION_CHANGED :
case NOTIFICATION_TRANSLATION_CHANGED : {
_update_icons ( ) ;
2022-09-01 23:52:49 +08:00
invalidate ( ) ;
2022-02-16 07:52:32 +08:00
} break ;
case NOTIFICATION_PROCESS : {
if ( preview_waiting ) {
preview_wheel_timeout - = get_process_delta_time ( ) ;
if ( preview_wheel_timeout < = 0 ) {
preview_wheel_index + + ;
if ( preview_wheel_index > = 8 ) {
preview_wheel_index = 0 ;
}
2022-09-01 23:52:49 +08:00
Ref < Texture2D > frame = theme_cache . progress [ preview_wheel_index ] ;
2022-02-16 07:52:32 +08:00
preview - > set_texture ( frame ) ;
preview_wheel_timeout = 0.1 ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
2022-02-16 07:52:32 +08:00
} break ;
case EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED : {
2022-10-18 22:43:37 +08:00
bool is_showing_hidden = EDITOR_GET ( " filesystem/file_dialog/show_hidden_files " ) ;
2022-02-16 07:52:32 +08:00
if ( show_hidden_files ! = is_showing_hidden ) {
set_show_hidden_files ( is_showing_hidden ) ;
}
2022-10-18 22:43:37 +08:00
set_display_mode ( ( DisplayMode ) EDITOR_GET ( " filesystem/file_dialog/display_mode " ) . operator int ( ) ) ;
2022-02-16 07:52:32 +08:00
// DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD
invalidate ( ) ;
} break ;
case NOTIFICATION_VISIBILITY_CHANGED : {
if ( ! is_visible ( ) ) {
2022-01-11 21:59:52 +08:00
set_process_shortcut_input ( false ) ;
2022-02-16 07:52:32 +08:00
}
2022-09-06 08:54:34 +08:00
invalidate ( ) ; // For consistency with the standard FileDialog.
2022-02-16 07:52:32 +08:00
} break ;
case NOTIFICATION_WM_WINDOW_FOCUS_IN : {
// Check if the current directory was removed externally (much less likely to happen while editor window is focused).
String previous_dir = get_current_dir ( ) ;
while ( ! dir_access - > dir_exists ( get_current_dir ( ) ) ) {
_go_up ( ) ;
// In case we can't go further up, use some fallback and break.
if ( get_current_dir ( ) = = previous_dir ) {
_dir_submitted ( OS : : get_singleton ( ) - > get_user_data_dir ( ) ) ;
break ;
}
2022-01-12 07:53:52 +08:00
}
2022-02-16 07:52:32 +08:00
} break ;
2015-05-31 12:59:42 +08:00
}
}
2022-01-11 21:59:52 +08:00
void EditorFileDialog : : shortcut_input ( const Ref < InputEvent > & p_event ) {
2021-04-05 14:52:21 +08:00
ERR_FAIL_COND ( p_event . is_null ( ) ) ;
2017-05-20 23:38:03 +08:00
Ref < InputEventKey > k = p_event ;
2015-12-29 07:36:48 +08:00
2020-03-07 01:00:16 +08:00
if ( k . is_valid ( ) ) {
2017-05-20 23:38:03 +08:00
if ( k - > is_pressed ( ) ) {
2016-06-19 01:32:04 +08:00
bool handled = false ;
2015-12-29 07:36:48 +08:00
2016-06-19 01:32:04 +08:00
if ( ED_IS_SHORTCUT ( " file_dialog/go_back " , p_event ) ) {
_go_back ( ) ;
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/go_forward " , p_event ) ) {
_go_forward ( ) ;
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/go_up " , p_event ) ) {
_go_up ( ) ;
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/refresh " , p_event ) ) {
invalidate ( ) ;
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/toggle_hidden_files " , p_event ) ) {
2020-10-06 21:42:25 +08:00
set_show_hidden_files ( ! show_hidden_files ) ;
2016-06-19 01:32:04 +08:00
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/toggle_favorite " , p_event ) ) {
2019-06-10 04:41:45 +08:00
_favorite_pressed ( ) ;
2016-06-19 01:32:04 +08:00
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/toggle_mode " , p_event ) ) {
if ( mode_thumbnails - > is_pressed ( ) ) {
set_display_mode ( DISPLAY_LIST ) ;
} else {
set_display_mode ( DISPLAY_THUMBNAILS ) ;
}
handled = true ;
}
if ( ED_IS_SHORTCUT ( " file_dialog/create_folder " , p_event ) ) {
_make_dir ( ) ;
handled = true ;
}
2017-12-02 08:37:32 +08:00
if ( ED_IS_SHORTCUT ( " file_dialog/delete " , p_event ) ) {
_delete_items ( ) ;
handled = true ;
}
2016-06-19 01:32:04 +08:00
if ( ED_IS_SHORTCUT ( " file_dialog/focus_path " , p_event ) ) {
dir - > grab_focus ( ) ;
handled = true ;
}
2016-06-28 22:12:07 +08:00
if ( ED_IS_SHORTCUT ( " file_dialog/move_favorite_up " , p_event ) ) {
2016-06-19 01:32:04 +08:00
_favorite_move_up ( ) ;
handled = true ;
}
2016-06-28 22:12:07 +08:00
if ( ED_IS_SHORTCUT ( " file_dialog/move_favorite_down " , p_event ) ) {
2016-06-19 01:32:04 +08:00
_favorite_move_down ( ) ;
handled = true ;
2015-12-29 07:36:48 +08:00
}
2016-06-19 01:32:04 +08:00
if ( handled ) {
2020-03-07 01:00:16 +08:00
set_input_as_handled ( ) ;
2016-06-19 01:32:04 +08:00
}
2015-12-29 07:36:48 +08:00
}
}
}
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : set_enable_multiple_selection ( bool p_enable ) {
2015-06-06 20:44:38 +08:00
item_list - > set_select_mode ( p_enable ? ItemList : : SELECT_MULTI : ItemList : : SELECT_SINGLE ) ;
2015-05-31 12:59:42 +08:00
} ;
Vector < String > EditorFileDialog : : get_selected_files ( ) const {
Vector < String > list ;
2015-06-06 20:44:38 +08:00
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
2020-05-14 22:41:43 +08:00
if ( item_list - > is_selected ( i ) ) {
2015-06-06 20:44:38 +08:00
list . push_back ( item_list - > get_item_text ( i ) ) ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
}
2015-05-31 12:59:42 +08:00
return list ;
} ;
void EditorFileDialog : : update_dir ( ) {
2020-02-10 16:19:29 +08:00
if ( drives - > is_visible ( ) ) {
2022-01-24 19:12:46 +08:00
if ( dir_access - > get_current_dir ( ) . is_network_share_path ( ) ) {
_update_drives ( false ) ;
drives - > add_item ( RTR ( " Network " ) ) ;
2022-03-12 08:06:45 +08:00
drives - > set_item_disabled ( - 1 , true ) ;
2022-01-24 19:12:46 +08:00
drives - > select ( drives - > get_item_count ( ) - 1 ) ;
} else {
drives - > select ( dir_access - > get_current_drive ( ) ) ;
}
2020-02-10 16:19:29 +08:00
}
dir - > set_text ( dir_access - > get_current_dir ( false ) ) ;
2017-11-25 02:12:18 +08:00
2018-09-11 14:32:14 +08:00
// Disable "Open" button only when selecting file(s) mode.
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( _is_open_should_be_disabled ( ) ) ;
2018-09-11 14:32:14 +08:00
switch ( mode ) {
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_FILE :
case FILE_MODE_OPEN_FILES :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2018-09-11 14:32:14 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_DIR :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Select Current Folder " ) ) ;
2018-09-11 14:32:14 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_ANY :
case FILE_MODE_SAVE_FILE :
2018-09-26 19:13:56 +08:00
// FIXME: Implement, or refactor to avoid duplication with set_mode
break ;
2018-09-11 14:32:14 +08:00
}
2015-05-31 12:59:42 +08:00
}
2021-06-17 00:43:34 +08:00
void EditorFileDialog : : _dir_submitted ( String p_dir ) {
2015-05-31 12:59:42 +08:00
dir_access - > change_dir ( p_dir ) ;
invalidate ( ) ;
update_dir ( ) ;
2015-06-06 20:44:38 +08:00
_push_history ( ) ;
2015-05-31 12:59:42 +08:00
}
2021-06-17 00:43:34 +08:00
void EditorFileDialog : : _file_submitted ( const String & p_file ) {
2015-05-31 12:59:42 +08:00
_action_pressed ( ) ;
}
void EditorFileDialog : : _save_confirm_pressed ( ) {
2022-08-30 08:34:01 +08:00
String f = dir_access - > get_current_dir ( ) . path_join ( file - > get_text ( ) ) ;
2015-06-06 20:44:38 +08:00
_save_to_recent ( ) ;
2015-05-31 12:59:42 +08:00
hide ( ) ;
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " file_selected " ) , f ) ;
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : _post_popup ( ) {
ConfirmationDialog : : _post_popup ( ) ;
2020-10-14 02:28:45 +08:00
// Check if the current path doesn't exist and correct it.
String current = dir_access - > get_current_dir ( ) ;
while ( ! dir_access - > dir_exists ( current ) ) {
current = current . get_base_dir ( ) ;
}
set_current_dir ( current ) ;
2020-05-14 22:41:43 +08:00
if ( mode = = FILE_MODE_SAVE_FILE ) {
2015-05-31 12:59:42 +08:00
file - > grab_focus ( ) ;
2020-05-14 22:41:43 +08:00
} else {
2015-06-06 20:44:38 +08:00
item_list - > grab_focus ( ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
2020-03-07 01:00:16 +08:00
if ( mode = = FILE_MODE_OPEN_DIR ) {
2019-10-26 23:29:22 +08:00
file_box - > set_visible ( false ) ;
} else {
file_box - > set_visible ( true ) ;
}
2022-09-06 08:54:34 +08:00
if ( ! get_current_file ( ) . is_empty ( ) ) {
2022-08-30 08:34:01 +08:00
_request_single_thumbnail ( get_current_dir ( ) . path_join ( get_current_file ( ) ) ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
2022-09-06 08:54:34 +08:00
local_history . clear ( ) ;
local_history_pos = - 1 ;
_push_history ( ) ;
2015-06-06 20:44:38 +08:00
2022-01-11 21:59:52 +08:00
set_process_shortcut_input ( true ) ;
2015-06-06 20:44:38 +08:00
}
2019-06-12 02:43:37 +08:00
void EditorFileDialog : : _thumbnail_result ( const String & p_path , const Ref < Texture2D > & p_preview , const Ref < Texture2D > & p_small_preview , const Variant & p_udata ) {
2020-05-14 22:41:43 +08:00
if ( display_mode = = DISPLAY_LIST | | p_preview . is_null ( ) ) {
2015-06-06 20:44:38 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
Dictionary d = item_list - > get_item_metadata ( i ) ;
String pname = d [ " path " ] ;
if ( pname = = p_path ) {
item_list - > set_item_icon ( i , p_preview ) ;
2019-06-12 02:43:37 +08:00
item_list - > set_item_tag_icon ( i , Ref < Texture2D > ( ) ) ;
2015-06-06 20:44:38 +08:00
}
}
2015-05-31 12:59:42 +08:00
}
2019-06-12 02:43:37 +08:00
void EditorFileDialog : : _thumbnail_done ( const String & p_path , const Ref < Texture2D > & p_preview , const Ref < Texture2D > & p_small_preview , const Variant & p_udata ) {
2015-05-31 12:59:42 +08:00
set_process ( false ) ;
preview_waiting = false ;
if ( p_preview . is_valid ( ) & & get_current_path ( ) = = p_path ) {
preview - > set_texture ( p_preview ) ;
2015-06-06 20:44:38 +08:00
if ( display_mode = = DISPLAY_THUMBNAILS ) {
preview_vb - > hide ( ) ;
} else {
preview_vb - > show ( ) ;
}
2015-05-31 12:59:42 +08:00
} else {
preview_vb - > hide ( ) ;
2019-06-12 02:43:37 +08:00
preview - > set_texture ( Ref < Texture2D > ( ) ) ;
2015-05-31 12:59:42 +08:00
}
}
void EditorFileDialog : : _request_single_thumbnail ( const String & p_path ) {
2022-02-03 08:21:52 +08:00
if ( ! FileAccess : : exists ( p_path ) | | ! previews_enabled ) {
2015-12-13 06:21:43 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-12-13 06:21:43 +08:00
2015-05-31 12:59:42 +08:00
set_process ( true ) ;
preview_waiting = true ;
preview_wheel_timeout = 0 ;
2019-03-02 20:33:54 +08:00
EditorResourcePreview : : get_singleton ( ) - > queue_resource_preview ( p_path , this , " _thumbnail_done " , p_path ) ;
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : _action_pressed ( ) {
2020-03-07 01:00:16 +08:00
if ( mode = = FILE_MODE_OPEN_FILES ) {
2015-05-31 12:59:42 +08:00
String fbase = dir_access - > get_current_dir ( ) ;
2020-02-18 05:06:54 +08:00
Vector < String > files ;
2015-06-06 20:44:38 +08:00
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
2020-05-14 22:41:43 +08:00
if ( item_list - > is_selected ( i ) ) {
2022-08-30 08:34:01 +08:00
files . push_back ( fbase . path_join ( item_list - > get_item_text ( i ) ) ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
if ( files . size ( ) ) {
2015-06-06 20:44:38 +08:00
_save_to_recent ( ) ;
2015-05-31 12:59:42 +08:00
hide ( ) ;
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " files_selected " ) , files ) ;
2015-05-31 12:59:42 +08:00
}
return ;
}
2022-03-02 03:29:19 +08:00
String file_text = file - > get_text ( ) ;
2022-08-30 08:34:01 +08:00
String f = file_text . is_absolute_path ( ) ? file_text : dir_access - > get_current_dir ( ) . path_join ( file_text ) ;
2015-05-31 12:59:42 +08:00
2020-03-07 01:00:16 +08:00
if ( ( mode = = FILE_MODE_OPEN_ANY | | mode = = FILE_MODE_OPEN_FILE ) & & dir_access - > file_exists ( f ) ) {
2015-06-06 20:44:38 +08:00
_save_to_recent ( ) ;
2015-05-31 12:59:42 +08:00
hide ( ) ;
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " file_selected " ) , f ) ;
2020-03-07 01:00:16 +08:00
} else if ( mode = = FILE_MODE_OPEN_ANY | | mode = = FILE_MODE_OPEN_DIR ) {
2015-05-31 12:59:42 +08:00
String path = dir_access - > get_current_dir ( ) ;
2016-09-26 15:43:10 +08:00
2015-05-31 12:59:42 +08:00
path = path . replace ( " \\ " , " / " ) ;
2016-09-26 15:43:10 +08:00
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
if ( item_list - > is_selected ( i ) ) {
Dictionary d = item_list - > get_item_metadata ( i ) ;
if ( d [ " dir " ] ) {
2022-08-30 08:34:01 +08:00
path = path . path_join ( d [ " name " ] ) ;
2016-09-26 15:43:10 +08:00
break ;
}
}
}
2015-06-06 20:44:38 +08:00
_save_to_recent ( ) ;
2015-05-31 12:59:42 +08:00
hide ( ) ;
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " dir_selected " ) , path ) ;
2015-05-31 12:59:42 +08:00
}
2020-03-07 01:00:16 +08:00
if ( mode = = FILE_MODE_SAVE_FILE ) {
2015-05-31 12:59:42 +08:00
bool valid = false ;
if ( filter - > get_selected ( ) = = filter - > get_item_count ( ) - 1 ) {
2017-12-25 12:29:00 +08:00
valid = true ; // match none
2015-05-31 12:59:42 +08:00
} else if ( filters . size ( ) > 1 & & filter - > get_selected ( ) = = 0 ) {
// match all filters
for ( int i = 0 ; i < filters . size ( ) ; i + + ) {
String flt = filters [ i ] . get_slice ( " ; " , 0 ) ;
for ( int j = 0 ; j < flt . get_slice_count ( " , " ) ; j + + ) {
String str = flt . get_slice ( " , " , j ) . strip_edges ( ) ;
if ( f . match ( str ) ) {
valid = true ;
break ;
}
}
2020-05-14 22:41:43 +08:00
if ( valid ) {
2015-05-31 12:59:42 +08:00
break ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
} else {
int idx = filter - > get_selected ( ) ;
2020-05-14 22:41:43 +08:00
if ( filters . size ( ) > 1 ) {
2015-05-31 12:59:42 +08:00
idx - - ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
if ( idx > = 0 & & idx < filters . size ( ) ) {
String flt = filters [ idx ] . get_slice ( " ; " , 0 ) ;
int filterSliceCount = flt . get_slice_count ( " , " ) ;
for ( int j = 0 ; j < filterSliceCount ; j + + ) {
String str = ( flt . get_slice ( " , " , j ) . strip_edges ( ) ) ;
if ( f . match ( str ) ) {
valid = true ;
break ;
}
}
if ( ! valid & & filterSliceCount > 0 ) {
String str = ( flt . get_slice ( " , " , 0 ) . strip_edges ( ) ) ;
f + = str . substr ( 1 , str . length ( ) - 1 ) ;
2022-08-30 08:34:01 +08:00
_request_single_thumbnail ( get_current_dir ( ) . path_join ( f . get_file ( ) ) ) ;
2015-05-31 12:59:42 +08:00
file - > set_text ( f . get_file ( ) ) ;
valid = true ;
}
} else {
valid = true ;
}
}
2020-10-14 02:28:45 +08:00
// Add first extension of filter if no valid extension is found.
2015-05-31 12:59:42 +08:00
if ( ! valid ) {
2020-10-14 02:28:45 +08:00
int idx = filter - > get_selected ( ) ;
String flt = filters [ idx ] . get_slice ( " ; " , 0 ) ;
String ext = flt . get_slice ( " , " , 0 ) . strip_edges ( ) . get_extension ( ) ;
f + = " . " + ext ;
2015-05-31 12:59:42 +08:00
}
2016-06-20 11:38:13 +08:00
if ( dir_access - > file_exists ( f ) & & ! disable_overwrite_warning ) {
2020-04-22 02:02:36 +08:00
confirm_save - > set_text ( TTR ( " File exists, overwrite? " ) ) ;
2015-05-31 12:59:42 +08:00
confirm_save - > popup_centered ( Size2 ( 200 , 80 ) ) ;
} else {
2015-06-06 20:44:38 +08:00
_save_to_recent ( ) ;
2015-05-31 12:59:42 +08:00
hide ( ) ;
2021-07-18 05:22:52 +08:00
emit_signal ( SNAME ( " file_selected " ) , f ) ;
2015-05-31 12:59:42 +08:00
}
}
}
void EditorFileDialog : : _cancel_pressed ( ) {
file - > set_text ( " " ) ;
invalidate ( ) ;
hide ( ) ;
}
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _item_selected ( int p_item ) {
int current = p_item ;
2020-05-14 22:41:43 +08:00
if ( current < 0 | | current > = item_list - > get_item_count ( ) ) {
2015-05-31 12:59:42 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
Dictionary d = item_list - > get_item_metadata ( current ) ;
2015-05-31 12:59:42 +08:00
if ( ! d [ " dir " ] ) {
file - > set_text ( d [ " name " ] ) ;
2022-08-30 08:34:01 +08:00
_request_single_thumbnail ( get_current_dir ( ) . path_join ( get_current_file ( ) ) ) ;
2020-03-07 01:00:16 +08:00
} else if ( mode = = FILE_MODE_OPEN_DIR ) {
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Select This Folder " ) ) ;
2015-05-31 12:59:42 +08:00
}
2017-11-25 02:12:18 +08:00
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( _is_open_should_be_disabled ( ) ) ;
2017-11-25 02:12:18 +08:00
}
2018-02-01 02:25:42 +08:00
void EditorFileDialog : : _multi_selected ( int p_item , bool p_selected ) {
int current = p_item ;
2020-05-14 22:41:43 +08:00
if ( current < 0 | | current > = item_list - > get_item_count ( ) ) {
2018-02-01 02:25:42 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2018-02-01 02:25:42 +08:00
Dictionary d = item_list - > get_item_metadata ( current ) ;
if ( ! d [ " dir " ] & & p_selected ) {
file - > set_text ( d [ " name " ] ) ;
2022-08-30 08:34:01 +08:00
_request_single_thumbnail ( get_current_dir ( ) . path_join ( get_current_file ( ) ) ) ;
2018-02-01 02:25:42 +08:00
}
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( _is_open_should_be_disabled ( ) ) ;
2018-02-01 02:25:42 +08:00
}
2022-05-10 02:17:04 +08:00
void EditorFileDialog : : _items_clear_selection ( const Vector2 & p_pos , MouseButton p_mouse_button_index ) {
2021-11-26 07:53:27 +08:00
if ( p_mouse_button_index ! = MouseButton : : LEFT ) {
return ;
}
2020-12-21 18:26:41 +08:00
item_list - > deselect_all ( ) ;
2017-11-25 02:12:18 +08:00
// If nothing is selected, then block Open button.
switch ( mode ) {
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_FILE :
case FILE_MODE_OPEN_FILES :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( ! item_list - > is_anything_selected ( ) ) ;
2017-11-25 02:12:18 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_DIR :
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( false ) ;
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Select Current Folder " ) ) ;
2017-11-25 02:12:18 +08:00
break ;
2018-09-26 19:13:56 +08:00
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_ANY :
case FILE_MODE_SAVE_FILE :
2018-09-26 19:13:56 +08:00
// FIXME: Implement, or refactor to avoid duplication with set_mode
break ;
2017-11-25 02:12:18 +08:00
}
2015-05-31 12:59:42 +08:00
}
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _push_history ( ) {
local_history . resize ( local_history_pos + 1 ) ;
String new_path = dir_access - > get_current_dir ( ) ;
if ( local_history . size ( ) = = 0 | | new_path ! = local_history [ local_history_pos ] ) {
local_history . push_back ( new_path ) ;
local_history_pos + + ;
dir_prev - > set_disabled ( local_history_pos = = 0 ) ;
dir_next - > set_disabled ( true ) ;
}
}
2020-05-14 20:29:06 +08:00
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _item_dc_selected ( int p_item ) {
int current = p_item ;
2020-05-14 22:41:43 +08:00
if ( current < 0 | | current > = item_list - > get_item_count ( ) ) {
2015-05-31 12:59:42 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
2015-06-06 20:44:38 +08:00
Dictionary d = item_list - > get_item_metadata ( current ) ;
2015-05-31 12:59:42 +08:00
if ( d [ " dir " ] ) {
dir_access - > change_dir ( d [ " name " ] ) ;
2021-07-18 05:22:52 +08:00
call_deferred ( SNAME ( " _update_file_list " ) ) ;
call_deferred ( SNAME ( " _update_dir " ) ) ;
2015-06-06 20:44:38 +08:00
_push_history ( ) ;
2015-05-31 12:59:42 +08:00
} else {
_action_pressed ( ) ;
}
}
2021-11-26 07:53:27 +08:00
void EditorFileDialog : : _item_list_item_rmb_clicked ( int p_item , const Vector2 & p_pos , MouseButton p_mouse_button_index ) {
if ( p_mouse_button_index ! = MouseButton : : RIGHT ) {
return ;
}
2017-12-02 08:37:32 +08:00
// Right click on specific file(s) or folder(s).
item_menu - > clear ( ) ;
2021-11-20 16:04:57 +08:00
item_menu - > reset_size ( ) ;
2017-12-02 08:37:32 +08:00
// Allow specific actions only on one item.
bool single_item_selected = item_list - > get_selected_items ( ) . size ( ) = = 1 ;
// Disallow deleting the .import folder, Godot kills a cat if you do and it is possibly a senseless novice action.
bool allow_delete = true ;
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
if ( ! item_list - > is_selected ( i ) ) {
continue ;
}
Dictionary item_meta = item_list - > get_item_metadata ( i ) ;
2021-09-10 23:32:29 +08:00
if ( String ( item_meta [ " path " ] ) . begins_with ( ProjectSettings : : get_singleton ( ) - > get_project_data_path ( ) ) ) {
2017-12-02 08:37:32 +08:00
allow_delete = false ;
break ;
}
}
if ( single_item_selected ) {
2022-09-01 23:52:49 +08:00
item_menu - > add_icon_item ( theme_cache . action_copy , TTR ( " Copy Path " ) , ITEM_MENU_COPY_PATH ) ;
2017-12-02 08:37:32 +08:00
}
if ( allow_delete ) {
2022-09-01 23:52:49 +08:00
item_menu - > add_icon_item ( theme_cache . action_delete , TTR ( " Delete " ) , ITEM_MENU_DELETE , Key : : KEY_DELETE ) ;
2017-12-02 08:37:32 +08:00
}
if ( single_item_selected ) {
item_menu - > add_separator ( ) ;
2018-08-11 20:43:00 +08:00
Dictionary item_meta = item_list - > get_item_metadata ( p_item ) ;
2018-10-27 03:11:36 +08:00
String item_text = item_meta [ " dir " ] ? TTR ( " Open in File Manager " ) : TTR ( " Show in File Manager " ) ;
2022-09-01 23:52:49 +08:00
item_menu - > add_icon_item ( theme_cache . filesystem , item_text , ITEM_MENU_SHOW_IN_EXPLORER ) ;
2017-12-02 08:37:32 +08:00
}
if ( item_menu - > get_item_count ( ) > 0 ) {
2021-08-31 23:43:35 +08:00
item_menu - > set_position ( item_list - > get_screen_position ( ) + p_pos ) ;
item_menu - > reset_size ( ) ;
2017-12-02 08:37:32 +08:00
item_menu - > popup ( ) ;
}
}
2021-11-26 07:53:27 +08:00
void EditorFileDialog : : _item_list_empty_clicked ( const Vector2 & p_pos , MouseButton p_mouse_button_index ) {
if ( p_mouse_button_index ! = MouseButton : : RIGHT & & p_mouse_button_index ! = MouseButton : : LEFT ) {
return ;
}
// Left or right click on folder background. Deselect all files so that actions are applied on the current folder.
2017-12-02 08:37:32 +08:00
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
2020-12-21 18:26:41 +08:00
item_list - > deselect ( i ) ;
2017-12-02 08:37:32 +08:00
}
2021-11-26 07:53:27 +08:00
if ( p_mouse_button_index ! = MouseButton : : RIGHT ) {
return ;
}
2017-12-02 08:37:32 +08:00
item_menu - > clear ( ) ;
2021-11-20 16:04:57 +08:00
item_menu - > reset_size ( ) ;
2017-12-02 08:37:32 +08:00
if ( can_create_dir ) {
2022-09-02 17:37:48 +08:00
item_menu - > add_icon_item ( theme_cache . folder , TTR ( " New Folder... " ) , ITEM_MENU_NEW_FOLDER , KeyModifierMask : : CMD_OR_CTRL | Key : : N ) ;
2017-12-02 08:37:32 +08:00
}
2022-09-01 23:52:49 +08:00
item_menu - > add_icon_item ( theme_cache . reload , TTR ( " Refresh " ) , ITEM_MENU_REFRESH , Key : : F5 ) ;
2017-12-02 08:37:32 +08:00
item_menu - > add_separator ( ) ;
2022-09-01 23:52:49 +08:00
item_menu - > add_icon_item ( theme_cache . filesystem , TTR ( " Open in File Manager " ) , ITEM_MENU_SHOW_IN_EXPLORER ) ;
2017-12-02 08:37:32 +08:00
2021-08-31 23:43:35 +08:00
item_menu - > set_position ( item_list - > get_screen_position ( ) + p_pos ) ;
item_menu - > reset_size ( ) ;
2017-12-02 08:37:32 +08:00
item_menu - > popup ( ) ;
}
void EditorFileDialog : : _item_menu_id_pressed ( int p_option ) {
switch ( p_option ) {
case ITEM_MENU_COPY_PATH : {
Dictionary item_meta = item_list - > get_item_metadata ( item_list - > get_current ( ) ) ;
2020-03-03 21:36:29 +08:00
DisplayServer : : get_singleton ( ) - > clipboard_set ( item_meta [ " path " ] ) ;
2017-12-02 08:37:32 +08:00
} break ;
case ITEM_MENU_DELETE : {
_delete_items ( ) ;
} break ;
case ITEM_MENU_REFRESH : {
invalidate ( ) ;
} break ;
case ITEM_MENU_NEW_FOLDER : {
_make_dir ( ) ;
} break ;
case ITEM_MENU_SHOW_IN_EXPLORER : {
String path ;
int idx = item_list - > get_current ( ) ;
if ( idx = = - 1 | | item_list - > get_selected_items ( ) . size ( ) = = 0 ) {
// Folder background was clicked. Open this folder.
path = ProjectSettings : : get_singleton ( ) - > globalize_path ( dir_access - > get_current_dir ( ) ) ;
} else {
// Specific item was clicked. Open folders directly, or the folder containing a selected file.
Dictionary item_meta = item_list - > get_item_metadata ( idx ) ;
path = ProjectSettings : : get_singleton ( ) - > globalize_path ( item_meta [ " path " ] ) ;
if ( ! item_meta [ " dir " ] ) {
path = path . get_base_dir ( ) ;
}
}
OS : : get_singleton ( ) - > shell_open ( String ( " file:// " ) + path ) ;
} break ;
}
}
2017-11-25 02:12:18 +08:00
bool EditorFileDialog : : _is_open_should_be_disabled ( ) {
2020-05-14 22:41:43 +08:00
if ( mode = = FILE_MODE_OPEN_ANY | | mode = = FILE_MODE_SAVE_FILE ) {
2017-11-25 02:12:18 +08:00
return false ;
2020-05-14 22:41:43 +08:00
}
2017-11-25 02:12:18 +08:00
Vector < int > items = item_list - > get_selected_items ( ) ;
2020-05-14 22:41:43 +08:00
if ( items . size ( ) = = 0 ) {
2020-03-07 01:00:16 +08:00
return mode ! = FILE_MODE_OPEN_DIR ; // In "Open folder" mode, having nothing selected picks the current folder.
2020-05-14 22:41:43 +08:00
}
2017-11-25 02:12:18 +08:00
for ( int i = 0 ; i < items . size ( ) ; i + + ) {
Dictionary d = item_list - > get_item_metadata ( items . get ( i ) ) ;
2020-05-14 22:41:43 +08:00
if ( ( ( mode = = FILE_MODE_OPEN_FILE | | mode = = FILE_MODE_OPEN_FILES ) & & d [ " dir " ] ) | | ( mode = = FILE_MODE_OPEN_DIR & & ! d [ " dir " ] ) ) {
2017-11-25 02:12:18 +08:00
return true ;
2020-05-14 22:41:43 +08:00
}
2017-11-25 02:12:18 +08:00
}
return false ;
}
2019-06-28 15:29:50 +08:00
void EditorFileDialog : : update_file_name ( ) {
int idx = filter - > get_selected ( ) - 1 ;
if ( ( idx = = - 1 & & filter - > get_item_count ( ) = = 2 ) | | ( filter - > get_item_count ( ) > 2 & & idx > = 0 & & idx < filter - > get_item_count ( ) - 2 ) ) {
2020-05-14 22:41:43 +08:00
if ( idx = = - 1 ) {
2019-06-28 15:29:50 +08:00
idx + = 1 ;
2020-05-14 22:41:43 +08:00
}
2019-06-28 15:29:50 +08:00
String filter_str = filters [ idx ] ;
String file_str = file - > get_text ( ) ;
String base_name = file_str . get_basename ( ) ;
2019-07-29 18:43:08 +08:00
Vector < String > filter_substr = filter_str . split ( " ; " ) ;
if ( filter_substr . size ( ) > = 2 ) {
2020-04-28 22:03:46 +08:00
file_str = base_name + " . " + filter_substr [ 0 ] . strip_edges ( ) . get_extension ( ) . to_lower ( ) ;
2019-07-29 18:43:08 +08:00
} else {
2020-04-28 22:03:46 +08:00
file_str = base_name + " . " + filter_str . strip_edges ( ) . get_extension ( ) . to_lower ( ) ;
2019-07-29 18:43:08 +08:00
}
2019-06-28 15:29:50 +08:00
file - > set_text ( file_str ) ;
}
}
2017-12-19 23:57:46 +08:00
// DO NOT USE THIS FUNCTION UNLESS NEEDED, CALL INVALIDATE() INSTEAD.
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : update_file_list ( ) {
2022-10-18 22:43:37 +08:00
int thumbnail_size = EDITOR_GET ( " filesystem/file_dialog/thumbnail_size " ) ;
2016-05-30 11:28:29 +08:00
thumbnail_size * = EDSCALE ;
2019-06-12 02:43:37 +08:00
Ref < Texture2D > folder_thumbnail ;
Ref < Texture2D > file_thumbnail ;
2015-06-06 20:44:38 +08:00
item_list - > clear ( ) ;
2019-10-24 21:31:31 +08:00
// Scroll back to the top after opening a directory
2021-12-01 00:46:36 +08:00
item_list - > get_v_scroll_bar ( ) - > set_value ( 0 ) ;
2019-10-24 21:31:31 +08:00
2015-06-06 20:44:38 +08:00
if ( display_mode = = DISPLAY_THUMBNAILS ) {
item_list - > set_max_columns ( 0 ) ;
item_list - > set_icon_mode ( ItemList : : ICON_MODE_TOP ) ;
item_list - > set_fixed_column_width ( thumbnail_size * 3 / 2 ) ;
item_list - > set_max_text_lines ( 2 ) ;
2022-06-15 16:01:45 +08:00
item_list - > set_text_overrun_behavior ( TextServer : : OVERRUN_TRIM_ELLIPSIS ) ;
2016-06-13 03:51:27 +08:00
item_list - > set_fixed_icon_size ( Size2 ( thumbnail_size , thumbnail_size ) ) ;
2015-06-06 20:44:38 +08:00
2017-09-13 03:32:04 +08:00
if ( thumbnail_size < 64 ) {
2022-09-01 23:52:49 +08:00
folder_thumbnail = theme_cache . folder_medium_thumbnail ;
file_thumbnail = theme_cache . file_medium_thumbnail ;
2017-09-13 03:32:04 +08:00
} else {
2022-09-01 23:52:49 +08:00
folder_thumbnail = theme_cache . folder_big_thumbnail ;
file_thumbnail = theme_cache . file_big_thumbnail ;
2015-06-06 20:44:38 +08:00
}
preview_vb - > hide ( ) ;
} else {
item_list - > set_icon_mode ( ItemList : : ICON_MODE_LEFT ) ;
item_list - > set_max_columns ( 1 ) ;
item_list - > set_max_text_lines ( 1 ) ;
item_list - > set_fixed_column_width ( 0 ) ;
2016-06-13 03:51:27 +08:00
item_list - > set_fixed_icon_size ( Size2 ( ) ) ;
2020-05-14 22:41:43 +08:00
if ( preview - > get_texture ( ) . is_valid ( ) ) {
2015-06-06 20:44:38 +08:00
preview_vb - > show ( ) ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
}
2015-12-11 20:37:34 +08:00
String cdir = dir_access - > get_current_dir ( ) ;
2015-06-06 20:44:38 +08:00
2015-05-31 12:59:42 +08:00
dir_access - > list_dir_begin ( ) ;
List < String > files ;
List < String > dirs ;
2021-11-30 22:19:26 +08:00
String item = dir_access - > get_next ( ) ;
2015-05-31 12:59:42 +08:00
2021-11-30 22:19:26 +08:00
while ( ! item . is_empty ( ) ) {
2020-05-14 22:41:43 +08:00
if ( item = = " . " | | item = = " .. " ) {
2021-11-30 22:19:26 +08:00
item = dir_access - > get_next ( ) ;
2017-11-21 07:58:07 +08:00
continue ;
2020-05-14 22:41:43 +08:00
}
2017-11-21 07:58:07 +08:00
2021-03-03 22:33:34 +08:00
if ( show_hidden_files ) {
2020-05-14 22:41:43 +08:00
if ( ! dir_access - > current_is_dir ( ) ) {
2015-05-31 12:59:42 +08:00
files . push_back ( item ) ;
2020-05-14 22:41:43 +08:00
} else {
2015-05-31 12:59:42 +08:00
dirs . push_back ( item ) ;
2020-05-14 22:41:43 +08:00
}
2021-03-03 22:33:34 +08:00
} else if ( ! dir_access - > current_is_hidden ( ) ) {
String full_path = cdir = = " res:// " ? item : dir_access - > get_current_dir ( ) + " / " + item ;
2022-04-07 05:37:33 +08:00
if ( dir_access - > current_is_dir ( ) & & ( ! EditorFileSystem : : _should_skip_directory ( full_path ) | | Engine : : get_singleton ( ) - > is_project_manager_hint ( ) ) ) {
2021-03-03 22:33:34 +08:00
dirs . push_back ( item ) ;
} else {
files . push_back ( item ) ;
}
2015-05-31 12:59:42 +08:00
}
2021-11-30 22:19:26 +08:00
item = dir_access - > get_next ( ) ;
2015-05-31 12:59:42 +08:00
}
2017-05-12 03:07:59 +08:00
dirs . sort_custom < NaturalNoCaseComparator > ( ) ;
files . sort_custom < NaturalNoCaseComparator > ( ) ;
2015-05-31 12:59:42 +08:00
2020-12-15 20:04:21 +08:00
while ( ! dirs . is_empty ( ) ) {
2016-09-26 15:38:15 +08:00
const String & dir_name = dirs . front ( ) - > get ( ) ;
2015-05-31 12:59:42 +08:00
2017-11-21 07:58:07 +08:00
item_list - > add_item ( dir_name ) ;
2015-06-06 20:44:38 +08:00
2016-09-26 15:38:15 +08:00
if ( display_mode = = DISPLAY_THUMBNAILS ) {
2022-03-12 08:06:45 +08:00
item_list - > set_item_icon ( - 1 , folder_thumbnail ) ;
2016-09-26 15:38:15 +08:00
} else {
2022-09-01 23:52:49 +08:00
item_list - > set_item_icon ( - 1 , theme_cache . folder ) ;
2015-05-31 12:59:42 +08:00
}
2016-09-26 15:38:15 +08:00
Dictionary d ;
d [ " name " ] = dir_name ;
2022-08-30 08:34:01 +08:00
d [ " path " ] = cdir . path_join ( dir_name ) ;
2016-09-26 15:38:15 +08:00
d [ " dir " ] = true ;
2022-03-12 08:06:45 +08:00
item_list - > set_item_metadata ( - 1 , d ) ;
2022-09-07 01:09:32 +08:00
item_list - > set_item_icon_modulate ( - 1 , theme_cache . folder_icon_color ) ;
2016-09-26 15:38:15 +08:00
dirs . pop_front ( ) ;
2015-05-31 12:59:42 +08:00
}
List < String > patterns ;
// build filter
if ( filter - > get_selected ( ) = = filter - > get_item_count ( ) - 1 ) {
// match all
} else if ( filters . size ( ) > 1 & & filter - > get_selected ( ) = = 0 ) {
// match all filters
for ( int i = 0 ; i < filters . size ( ) ; i + + ) {
String f = filters [ i ] . get_slice ( " ; " , 0 ) ;
for ( int j = 0 ; j < f . get_slice_count ( " , " ) ; j + + ) {
patterns . push_back ( f . get_slice ( " , " , j ) . strip_edges ( ) ) ;
}
}
} else {
int idx = filter - > get_selected ( ) ;
2020-05-14 22:41:43 +08:00
if ( filters . size ( ) > 1 ) {
2015-05-31 12:59:42 +08:00
idx - - ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
if ( idx > = 0 & & idx < filters . size ( ) ) {
String f = filters [ idx ] . get_slice ( " ; " , 0 ) ;
for ( int j = 0 ; j < f . get_slice_count ( " , " ) ; j + + ) {
patterns . push_back ( f . get_slice ( " , " , j ) . strip_edges ( ) ) ;
}
}
}
2020-12-15 20:04:21 +08:00
while ( ! files . is_empty ( ) ) {
bool match = patterns . is_empty ( ) ;
2015-05-31 12:59:42 +08:00
2021-07-24 21:46:25 +08:00
for ( const String & E : patterns ) {
2021-07-16 11:45:57 +08:00
if ( files . front ( ) - > get ( ) . matchn ( E ) ) {
2015-05-31 12:59:42 +08:00
match = true ;
break ;
}
}
if ( match ) {
2015-06-06 20:44:38 +08:00
item_list - > add_item ( files . front ( ) - > get ( ) ) ;
2015-05-31 12:59:42 +08:00
if ( get_icon_func ) {
2022-08-30 08:34:01 +08:00
Ref < Texture2D > icon = get_icon_func ( cdir . path_join ( files . front ( ) - > get ( ) ) ) ;
2015-06-06 20:44:38 +08:00
if ( display_mode = = DISPLAY_THUMBNAILS ) {
2022-03-12 08:06:45 +08:00
item_list - > set_item_icon ( - 1 , file_thumbnail ) ;
item_list - > set_item_tag_icon ( - 1 , icon ) ;
2015-06-06 20:44:38 +08:00
} else {
2022-03-12 08:06:45 +08:00
item_list - > set_item_icon ( - 1 , icon ) ;
2015-06-06 20:44:38 +08:00
}
2015-05-31 12:59:42 +08:00
}
Dictionary d ;
d [ " name " ] = files . front ( ) - > get ( ) ;
d [ " dir " ] = false ;
2022-08-30 08:34:01 +08:00
String fullpath = cdir . path_join ( files . front ( ) - > get ( ) ) ;
2018-12-06 23:02:40 +08:00
d [ " path " ] = fullpath ;
2022-03-12 08:06:45 +08:00
item_list - > set_item_metadata ( - 1 , d ) ;
2018-12-06 23:02:40 +08:00
2022-02-03 08:21:52 +08:00
if ( display_mode = = DISPLAY_THUMBNAILS & & previews_enabled ) {
2015-06-06 20:44:38 +08:00
EditorResourcePreview : : get_singleton ( ) - > queue_resource_preview ( fullpath , this , " _thumbnail_result " , fullpath ) ;
}
2015-05-31 12:59:42 +08:00
2020-05-14 22:41:43 +08:00
if ( file - > get_text ( ) = = files . front ( ) - > get ( ) ) {
2015-06-06 20:44:38 +08:00
item_list - > set_current ( item_list - > get_item_count ( ) - 1 ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
files . pop_front ( ) ;
}
2015-06-06 20:44:38 +08:00
if ( favorites - > get_current ( ) > = 0 ) {
2020-12-21 18:26:41 +08:00
favorites - > deselect ( favorites - > get_current ( ) ) ;
2015-06-06 20:44:38 +08:00
}
favorite - > set_pressed ( false ) ;
fav_up - > set_disabled ( true ) ;
fav_down - > set_disabled ( true ) ;
2020-12-15 02:37:30 +08:00
get_ok_button ( ) - > set_disabled ( _is_open_should_be_disabled ( ) ) ;
2015-06-06 20:44:38 +08:00
for ( int i = 0 ; i < favorites - > get_item_count ( ) ; i + + ) {
2019-03-08 08:48:12 +08:00
if ( favorites - > get_item_metadata ( i ) = = cdir | | favorites - > get_item_metadata ( i ) = = cdir + " / " ) {
2015-06-06 20:44:38 +08:00
favorites - > select ( i ) ;
favorite - > set_pressed ( true ) ;
if ( i > 0 ) {
fav_up - > set_disabled ( false ) ;
}
if ( i < favorites - > get_item_count ( ) - 1 ) {
fav_down - > set_disabled ( false ) ;
}
break ;
}
}
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : _filter_selected ( int ) {
2019-06-28 15:29:50 +08:00
update_file_name ( ) ;
2015-05-31 12:59:42 +08:00
update_file_list ( ) ;
}
void EditorFileDialog : : update_filters ( ) {
filter - > clear ( ) ;
if ( filters . size ( ) > 1 ) {
String all_filters ;
const int max_filters = 5 ;
for ( int i = 0 ; i < MIN ( max_filters , filters . size ( ) ) ; i + + ) {
2019-12-07 09:40:59 +08:00
String flt = filters [ i ] . get_slice ( " ; " , 0 ) . strip_edges ( ) ;
2020-05-14 22:41:43 +08:00
if ( i > 0 ) {
2019-12-07 09:40:59 +08:00
all_filters + = " , " ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
all_filters + = flt ;
}
2020-05-14 22:41:43 +08:00
if ( max_filters < filters . size ( ) ) {
2015-05-31 12:59:42 +08:00
all_filters + = " , ... " ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
2019-12-06 18:31:42 +08:00
filter - > add_item ( TTR ( " All Recognized " ) + " ( " + all_filters + " ) " ) ;
2015-05-31 12:59:42 +08:00
}
for ( int i = 0 ; i < filters . size ( ) ; i + + ) {
String flt = filters [ i ] . get_slice ( " ; " , 0 ) . strip_edges ( ) ;
String desc = filters [ i ] . get_slice ( " ; " , 1 ) . strip_edges ( ) ;
2020-05-14 22:41:43 +08:00
if ( desc . length ( ) ) {
2019-12-06 18:31:42 +08:00
filter - > add_item ( desc + " ( " + flt + " ) " ) ;
2020-05-14 22:41:43 +08:00
} else {
2019-12-06 18:31:42 +08:00
filter - > add_item ( " ( " + flt + " ) " ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
2016-05-04 09:25:37 +08:00
filter - > add_item ( TTR ( " All Files (*) " ) ) ;
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : clear_filters ( ) {
filters . clear ( ) ;
update_filters ( ) ;
invalidate ( ) ;
}
2020-05-14 20:29:06 +08:00
2022-07-05 05:26:26 +08:00
void EditorFileDialog : : add_filter ( const String & p_filter , const String & p_description ) {
if ( p_description . is_empty ( ) ) {
filters . push_back ( p_filter ) ;
} else {
filters . push_back ( vformat ( " %s ; %s " , p_filter , p_description ) ) ;
}
2015-05-31 12:59:42 +08:00
update_filters ( ) ;
invalidate ( ) ;
}
String EditorFileDialog : : get_current_dir ( ) const {
2020-02-10 16:19:29 +08:00
return dir_access - > get_current_dir ( ) ;
2015-05-31 12:59:42 +08:00
}
2020-05-14 20:29:06 +08:00
2015-05-31 12:59:42 +08:00
String EditorFileDialog : : get_current_file ( ) const {
return file - > get_text ( ) ;
}
2020-05-14 20:29:06 +08:00
2015-05-31 12:59:42 +08:00
String EditorFileDialog : : get_current_path ( ) const {
2022-08-30 08:34:01 +08:00
return dir_access - > get_current_dir ( ) . path_join ( file - > get_text ( ) ) ;
2015-05-31 12:59:42 +08:00
}
2020-05-14 20:29:06 +08:00
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : set_current_dir ( const String & p_dir ) {
2021-08-30 07:43:47 +08:00
if ( p_dir . is_relative_path ( ) ) {
2019-12-14 18:06:29 +08:00
dir_access - > change_dir ( OS : : get_singleton ( ) - > get_resource_dir ( ) ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
dir_access - > change_dir ( p_dir ) ;
update_dir ( ) ;
invalidate ( ) ;
}
2020-05-14 20:29:06 +08:00
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : set_current_file ( const String & p_file ) {
file - > set_text ( p_file ) ;
update_dir ( ) ;
invalidate ( ) ;
2022-01-03 17:08:03 +08:00
_focus_file_text ( ) ;
2015-05-31 12:59:42 +08:00
2020-05-14 22:41:43 +08:00
if ( is_visible ( ) ) {
2022-08-30 08:34:01 +08:00
_request_single_thumbnail ( get_current_dir ( ) . path_join ( get_current_file ( ) ) ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
2020-05-14 20:29:06 +08:00
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : set_current_path ( const String & p_path ) {
2020-05-14 22:41:43 +08:00
if ( ! p_path . size ( ) ) {
2015-05-31 12:59:42 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2020-07-03 21:26:22 +08:00
int pos = MAX ( p_path . rfind ( " / " ) , p_path . rfind ( " \\ " ) ) ;
2015-05-31 12:59:42 +08:00
if ( pos = = - 1 ) {
set_current_file ( p_path ) ;
} else {
2022-09-29 17:53:28 +08:00
String path_dir = p_path . substr ( 0 , pos ) ;
String path_file = p_path . substr ( pos + 1 , p_path . length ( ) ) ;
set_current_dir ( path_dir ) ;
set_current_file ( path_file ) ;
2015-05-31 12:59:42 +08:00
}
}
2020-03-07 01:00:16 +08:00
void EditorFileDialog : : set_file_mode ( FileMode p_mode ) {
2015-05-31 12:59:42 +08:00
mode = p_mode ;
switch ( mode ) {
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_FILE :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2017-08-24 04:25:14 +08:00
set_title ( TTR ( " Open a File " ) ) ;
2017-12-02 08:37:32 +08:00
can_create_dir = false ;
2016-05-04 09:25:37 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_FILES :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2017-08-24 04:25:14 +08:00
set_title ( TTR ( " Open File(s) " ) ) ;
2017-12-02 08:37:32 +08:00
can_create_dir = false ;
2016-05-04 09:25:37 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_DIR :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2017-08-24 04:25:14 +08:00
set_title ( TTR ( " Open a Directory " ) ) ;
2017-12-02 08:37:32 +08:00
can_create_dir = true ;
2016-05-04 09:25:37 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_OPEN_ANY :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Open " ) ) ;
2017-08-24 04:25:14 +08:00
set_title ( TTR ( " Open a File or Directory " ) ) ;
2017-12-02 08:37:32 +08:00
can_create_dir = true ;
2016-05-04 09:25:37 +08:00
break ;
2020-03-07 01:00:16 +08:00
case FILE_MODE_SAVE_FILE :
2022-07-08 08:31:19 +08:00
set_ok_button_text ( TTR ( " Save " ) ) ;
2017-08-24 04:25:14 +08:00
set_title ( TTR ( " Save a File " ) ) ;
2017-12-02 08:37:32 +08:00
can_create_dir = true ;
2016-05-04 09:25:37 +08:00
break ;
2015-05-31 12:59:42 +08:00
}
2020-03-07 01:00:16 +08:00
if ( mode = = FILE_MODE_OPEN_FILES ) {
2015-06-06 20:44:38 +08:00
item_list - > set_select_mode ( ItemList : : SELECT_MULTI ) ;
2015-05-31 12:59:42 +08:00
} else {
2015-06-06 20:44:38 +08:00
item_list - > set_select_mode ( ItemList : : SELECT_SINGLE ) ;
2015-05-31 12:59:42 +08:00
}
2017-12-02 08:37:32 +08:00
if ( can_create_dir ) {
makedir - > show ( ) ;
} else {
makedir - > hide ( ) ;
}
2015-05-31 12:59:42 +08:00
}
2020-03-07 01:00:16 +08:00
EditorFileDialog : : FileMode EditorFileDialog : : get_file_mode ( ) const {
2015-05-31 12:59:42 +08:00
return mode ;
}
void EditorFileDialog : : set_access ( Access p_access ) {
ERR_FAIL_INDEX ( p_access , 3 ) ;
2020-05-14 22:41:43 +08:00
if ( access = = p_access ) {
2015-05-31 12:59:42 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
switch ( p_access ) {
case ACCESS_FILESYSTEM : {
dir_access = DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ;
} break ;
case ACCESS_RESOURCES : {
dir_access = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
} break ;
case ACCESS_USERDATA : {
dir_access = DirAccess : : create ( DirAccess : : ACCESS_USERDATA ) ;
} break ;
}
access = p_access ;
_update_drives ( ) ;
invalidate ( ) ;
update_filters ( ) ;
update_dir ( ) ;
}
void EditorFileDialog : : invalidate ( ) {
2020-03-07 01:00:16 +08:00
if ( is_visible ( ) ) {
2015-05-31 12:59:42 +08:00
update_file_list ( ) ;
2018-02-26 15:59:49 +08:00
_update_favorites ( ) ;
2022-09-01 23:52:49 +08:00
_update_recent ( ) ;
2015-05-31 12:59:42 +08:00
invalidated = false ;
} else {
invalidated = true ;
}
}
EditorFileDialog : : Access EditorFileDialog : : get_access ( ) const {
return access ;
}
void EditorFileDialog : : _make_dir_confirm ( ) {
2022-04-06 01:09:52 +08:00
const String stripped_dirname = makedirname - > get_text ( ) . strip_edges ( ) ;
if ( dir_access - > dir_exists ( stripped_dirname ) ) {
2022-03-25 06:27:33 +08:00
error_dialog - > set_text ( TTR ( " Could not create folder. File with that name already exists. " ) ) ;
error_dialog - > popup_centered ( Size2 ( 250 , 50 ) * EDSCALE ) ;
makedirname - > set_text ( " " ) ; // Reset label.
return ;
}
2022-04-06 01:09:52 +08:00
Error err = dir_access - > make_dir ( stripped_dirname ) ;
2015-05-31 12:59:42 +08:00
if ( err = = OK ) {
2022-04-06 01:09:52 +08:00
dir_access - > change_dir ( stripped_dirname ) ;
2015-05-31 12:59:42 +08:00
invalidate ( ) ;
update_filters ( ) ;
update_dir ( ) ;
2015-06-06 20:44:38 +08:00
_push_history ( ) ;
2022-02-03 08:21:52 +08:00
if ( access ! = ACCESS_FILESYSTEM ) {
EditorFileSystem : : get_singleton ( ) - > scan_changes ( ) ; //we created a dir, so rescan changes
}
2015-05-31 12:59:42 +08:00
} else {
2022-02-03 08:21:52 +08:00
error_dialog - > set_text ( TTR ( " Could not create folder. " ) ) ;
error_dialog - > popup_centered ( Size2 ( 250 , 50 ) * EDSCALE ) ;
2015-05-31 12:59:42 +08:00
}
2016-05-01 17:38:24 +08:00
makedirname - > set_text ( " " ) ; // reset label
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : _make_dir ( ) {
2020-03-07 01:00:16 +08:00
makedialog - > popup_centered ( Size2 ( 250 , 80 ) * EDSCALE ) ;
2015-05-31 12:59:42 +08:00
makedirname - > grab_focus ( ) ;
}
2017-12-02 08:37:32 +08:00
void EditorFileDialog : : _delete_items ( ) {
// Collect the selected folders and files to delete and check them in the deletion dependency dialog.
Vector < String > folders ;
Vector < String > files ;
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
if ( ! item_list - > is_selected ( i ) ) {
continue ;
}
Dictionary item_meta = item_list - > get_item_metadata ( i ) ;
if ( item_meta [ " dir " ] ) {
folders . push_back ( item_meta [ " path " ] ) ;
} else {
files . push_back ( item_meta [ " path " ] ) ;
}
}
if ( folders . size ( ) + files . size ( ) > 0 ) {
2022-02-03 08:21:52 +08:00
if ( access = = ACCESS_FILESYSTEM ) {
global_remove_dialog - > popup_centered ( ) ;
} else {
dep_remove_dialog - > reset_size ( ) ;
dep_remove_dialog - > show ( folders , files ) ;
}
2017-12-02 08:37:32 +08:00
}
}
2022-02-03 08:21:52 +08:00
void EditorFileDialog : : _delete_files_global ( ) {
// Delete files outside of the project directory without dependency checks.
for ( int i = 0 ; i < item_list - > get_item_count ( ) ; i + + ) {
if ( ! item_list - > is_selected ( i ) ) {
continue ;
}
Dictionary item_meta = item_list - > get_item_metadata ( i ) ;
// Only delete empty directories for safety.
dir_access - > remove ( item_meta [ " path " ] ) ;
}
update_file_list ( ) ;
}
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : _select_drive ( int p_idx ) {
String d = drives - > get_item_text ( p_idx ) ;
dir_access - > change_dir ( d ) ;
file - > set_text ( " " ) ;
invalidate ( ) ;
update_dir ( ) ;
2015-06-06 20:44:38 +08:00
_push_history ( ) ;
2015-05-31 12:59:42 +08:00
}
2022-01-24 19:12:46 +08:00
void EditorFileDialog : : _update_drives ( bool p_select ) {
2015-05-31 12:59:42 +08:00
int dc = dir_access - > get_drive_count ( ) ;
if ( dc = = 0 | | access ! = ACCESS_FILESYSTEM ) {
drives - > hide ( ) ;
} else {
drives - > clear ( ) ;
2020-02-10 16:19:29 +08:00
Node * dp = drives - > get_parent ( ) ;
if ( dp ) {
dp - > remove_child ( drives ) ;
}
dp = dir_access - > drives_are_shortcuts ( ) ? shortcuts_container : drives_container ;
dp - > add_child ( drives ) ;
2015-05-31 12:59:42 +08:00
drives - > show ( ) ;
for ( int i = 0 ; i < dir_access - > get_drive_count ( ) ; i + + ) {
String d = dir_access - > get_drive ( i ) ;
drives - > add_item ( dir_access - > get_drive ( i ) ) ;
}
2022-01-24 19:12:46 +08:00
if ( p_select ) {
drives - > select ( dir_access - > get_current_drive ( ) ) ;
}
2015-05-31 12:59:42 +08:00
}
}
2022-02-03 08:21:52 +08:00
void EditorFileDialog : : _update_icons ( ) {
// Update icons.
2022-09-01 23:52:49 +08:00
mode_thumbnails - > set_icon ( theme_cache . mode_thumbnails ) ;
mode_list - > set_icon ( theme_cache . mode_list ) ;
2022-02-03 08:21:52 +08:00
if ( is_layout_rtl ( ) ) {
2022-09-01 23:52:49 +08:00
dir_prev - > set_icon ( theme_cache . forward_folder ) ;
dir_next - > set_icon ( theme_cache . back_folder ) ;
2022-02-03 08:21:52 +08:00
} else {
2022-09-01 23:52:49 +08:00
dir_prev - > set_icon ( theme_cache . back_folder ) ;
dir_next - > set_icon ( theme_cache . forward_folder ) ;
2022-02-03 08:21:52 +08:00
}
2022-09-01 23:52:49 +08:00
dir_up - > set_icon ( theme_cache . parent_folder ) ;
2022-02-03 08:21:52 +08:00
2022-09-01 23:52:49 +08:00
refresh - > set_icon ( theme_cache . reload ) ;
favorite - > set_icon ( theme_cache . favorite ) ;
show_hidden - > set_icon ( theme_cache . toggle_hidden ) ;
fav_up - > set_icon ( theme_cache . favorites_up ) ;
fav_down - > set_icon ( theme_cache . favorites_down ) ;
2022-02-03 08:21:52 +08:00
}
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _favorite_selected ( int p_idx ) {
2022-02-03 08:21:52 +08:00
Error change_dir_result = dir_access - > change_dir ( favorites - > get_item_metadata ( p_idx ) ) ;
if ( change_dir_result ! = OK ) {
error_dialog - > set_text ( TTR ( " Favorited folder does not exist anymore and will be removed. " ) ) ;
error_dialog - > popup_centered ( Size2 ( 250 , 50 ) * EDSCALE ) ;
bool res = ( access = = ACCESS_RESOURCES ) ;
Vector < String > favorited = EditorSettings : : get_singleton ( ) - > get_favorites ( ) ;
String dir_to_remove = favorites - > get_item_metadata ( p_idx ) ;
bool found = false ;
for ( int i = 0 ; i < favorited . size ( ) ; i + + ) {
bool cres = favorited [ i ] . begins_with ( " res:// " ) ;
if ( cres ! = res ) {
continue ;
}
if ( favorited [ i ] = = dir_to_remove ) {
found = true ;
break ;
}
}
if ( found ) {
favorited . erase ( favorites - > get_item_metadata ( p_idx ) ) ;
favorites - > remove_item ( p_idx ) ;
EditorSettings : : get_singleton ( ) - > set_favorites ( favorited ) ;
}
} else {
update_dir ( ) ;
invalidate ( ) ;
_push_history ( ) ;
}
2015-06-06 20:44:38 +08:00
}
void EditorFileDialog : : _favorite_move_up ( ) {
int current = favorites - > get_current ( ) ;
if ( current > 0 & & current < favorites - > get_item_count ( ) ) {
2018-09-18 20:02:59 +08:00
Vector < String > favorited = EditorSettings : : get_singleton ( ) - > get_favorites ( ) ;
2015-06-06 20:44:38 +08:00
2015-06-07 09:06:58 +08:00
int a_idx = favorited . find ( String ( favorites - > get_item_metadata ( current - 1 ) ) ) ;
int b_idx = favorited . find ( String ( favorites - > get_item_metadata ( current ) ) ) ;
2015-06-06 20:44:38 +08:00
2020-05-14 22:41:43 +08:00
if ( a_idx = = - 1 | | b_idx = = - 1 ) {
2015-06-06 20:44:38 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2018-07-25 09:11:03 +08:00
SWAP ( favorited . write [ a_idx ] , favorited . write [ b_idx ] ) ;
2015-06-06 20:44:38 +08:00
2018-09-18 20:02:59 +08:00
EditorSettings : : get_singleton ( ) - > set_favorites ( favorited ) ;
2015-06-06 20:44:38 +08:00
_update_favorites ( ) ;
update_file_list ( ) ;
}
}
2020-05-14 20:29:06 +08:00
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _favorite_move_down ( ) {
int current = favorites - > get_current ( ) ;
if ( current > = 0 & & current < favorites - > get_item_count ( ) - 1 ) {
2018-09-18 20:02:59 +08:00
Vector < String > favorited = EditorSettings : : get_singleton ( ) - > get_favorites ( ) ;
2015-06-06 20:44:38 +08:00
2015-06-07 09:06:58 +08:00
int a_idx = favorited . find ( String ( favorites - > get_item_metadata ( current + 1 ) ) ) ;
int b_idx = favorited . find ( String ( favorites - > get_item_metadata ( current ) ) ) ;
2015-06-06 20:44:38 +08:00
2020-05-14 22:41:43 +08:00
if ( a_idx = = - 1 | | b_idx = = - 1 ) {
2015-06-06 20:44:38 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2018-07-25 09:11:03 +08:00
SWAP ( favorited . write [ a_idx ] , favorited . write [ b_idx ] ) ;
2015-06-06 20:44:38 +08:00
2018-09-18 20:02:59 +08:00
EditorSettings : : get_singleton ( ) - > set_favorites ( favorited ) ;
2015-06-06 20:44:38 +08:00
_update_favorites ( ) ;
update_file_list ( ) ;
}
}
void EditorFileDialog : : _update_favorites ( ) {
2022-02-03 08:21:52 +08:00
bool res = ( access = = ACCESS_RESOURCES ) ;
2015-06-06 20:44:38 +08:00
String current = get_current_dir ( ) ;
favorites - > clear ( ) ;
favorite - > set_pressed ( false ) ;
2018-09-18 20:02:59 +08:00
Vector < String > favorited = EditorSettings : : get_singleton ( ) - > get_favorites ( ) ;
2022-07-28 02:51:03 +08:00
Vector < String > favorited_paths ;
Vector < String > favorited_names ;
2022-03-24 06:28:51 +08:00
bool fav_changed = false ;
2022-07-28 02:51:03 +08:00
int current_favorite = - 1 ;
2015-06-06 20:44:38 +08:00
for ( int i = 0 ; i < favorited . size ( ) ; i + + ) {
bool cres = favorited [ i ] . begins_with ( " res:// " ) ;
2020-05-14 22:41:43 +08:00
if ( cres ! = res ) {
2015-06-06 20:44:38 +08:00
continue ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
2022-07-28 02:51:03 +08:00
if ( ! dir_access - > dir_exists ( favorited [ i ] ) ) {
// Remove invalid directory from the list of Favorited directories.
favorited . remove_at ( i - - ) ;
fav_changed = true ;
continue ;
}
// Compute favorite display text.
String name = favorited [ i ] ;
2015-06-06 20:44:38 +08:00
if ( res & & name = = " res:// " ) {
2020-05-14 22:41:43 +08:00
if ( name = = current ) {
2022-07-28 02:51:03 +08:00
current_favorite = favorited_paths . size ( ) ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
name = " / " ;
2022-07-28 02:51:03 +08:00
favorited_paths . append ( favorited [ i ] ) ;
favorited_names . append ( name ) ;
2018-10-20 06:23:09 +08:00
} else if ( name . ends_with ( " / " ) ) {
2020-05-14 22:41:43 +08:00
if ( name = = current | | name = = current + " / " ) {
2022-07-28 02:51:03 +08:00
current_favorite = favorited_paths . size ( ) ;
2020-05-14 22:41:43 +08:00
}
2018-10-20 06:23:09 +08:00
name = name . substr ( 0 , name . length ( ) - 1 ) ;
name = name . get_file ( ) ;
2022-07-28 02:51:03 +08:00
favorited_paths . append ( favorited [ i ] ) ;
favorited_names . append ( name ) ;
2015-06-06 20:44:38 +08:00
} else {
2022-07-28 02:51:03 +08:00
// Ignore favorited files.
2015-06-06 20:44:38 +08:00
}
2022-07-28 02:51:03 +08:00
}
if ( fav_changed ) {
EditorSettings : : get_singleton ( ) - > set_favorites ( favorited ) ;
}
EditorNode : : disambiguate_filenames ( favorited_paths , favorited_names ) ;
2015-06-06 20:44:38 +08:00
2022-07-28 02:51:03 +08:00
for ( int i = 0 ; i < favorited_paths . size ( ) ; i + + ) {
2022-09-01 23:52:49 +08:00
favorites - > add_item ( favorited_names [ i ] , theme_cache . folder ) ;
2022-07-28 02:51:03 +08:00
favorites - > set_item_metadata ( - 1 , favorited_paths [ i ] ) ;
2022-09-07 01:09:32 +08:00
favorites - > set_item_icon_modulate ( - 1 , theme_cache . folder_icon_color ) ;
2015-06-06 20:44:38 +08:00
2022-07-28 02:51:03 +08:00
if ( i = = current_favorite ) {
2015-06-06 20:44:38 +08:00
favorite - > set_pressed ( true ) ;
favorites - > set_current ( favorites - > get_item_count ( ) - 1 ) ;
2020-12-21 18:26:41 +08:00
recent - > deselect_all ( ) ;
2015-06-06 20:44:38 +08:00
}
}
}
2019-06-10 04:41:45 +08:00
void EditorFileDialog : : _favorite_pressed ( ) {
2022-02-03 08:21:52 +08:00
bool res = ( access = = ACCESS_RESOURCES ) ;
2015-06-06 20:44:38 +08:00
String cd = get_current_dir ( ) ;
2020-05-14 22:41:43 +08:00
if ( ! cd . ends_with ( " / " ) ) {
2019-03-05 14:55:08 +08:00
cd + = " / " ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
2018-09-18 20:02:59 +08:00
Vector < String > favorited = EditorSettings : : get_singleton ( ) - > get_favorites ( ) ;
2015-06-06 20:44:38 +08:00
bool found = false ;
for ( int i = 0 ; i < favorited . size ( ) ; i + + ) {
bool cres = favorited [ i ] . begins_with ( " res:// " ) ;
2020-05-14 22:41:43 +08:00
if ( cres ! = res ) {
2015-06-06 20:44:38 +08:00
continue ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
if ( favorited [ i ] = = cd ) {
found = true ;
break ;
}
}
2020-05-14 22:41:43 +08:00
if ( found ) {
2015-06-06 20:44:38 +08:00
favorited . erase ( cd ) ;
2020-05-14 22:41:43 +08:00
} else {
2015-06-06 20:44:38 +08:00
favorited . push_back ( cd ) ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
2018-09-18 20:02:59 +08:00
EditorSettings : : get_singleton ( ) - > set_favorites ( favorited ) ;
2015-06-06 20:44:38 +08:00
_update_favorites ( ) ;
}
2022-09-01 23:52:49 +08:00
void EditorFileDialog : : _update_recent ( ) {
recent - > clear ( ) ;
bool res = ( access = = ACCESS_RESOURCES ) ;
Vector < String > recentd = EditorSettings : : get_singleton ( ) - > get_recent_dirs ( ) ;
Vector < String > recentd_paths ;
Vector < String > recentd_names ;
for ( int i = 0 ; i < recentd . size ( ) ; i + + ) {
bool cres = recentd [ i ] . begins_with ( " res:// " ) ;
if ( cres ! = res ) {
continue ;
}
if ( ! dir_access - > dir_exists ( recentd [ i ] ) ) {
// Remove invalid directory from the list of Recent directories.
recentd . remove_at ( i - - ) ;
continue ;
}
// Compute recent directory display text.
String name = recentd [ i ] ;
if ( res & & name = = " res:// " ) {
name = " / " ;
} else {
if ( name . ends_with ( " / " ) ) {
name = name . substr ( 0 , name . length ( ) - 1 ) ;
}
name = name . get_file ( ) ;
}
recentd_paths . append ( recentd [ i ] ) ;
recentd_names . append ( name ) ;
}
EditorNode : : disambiguate_filenames ( recentd_paths , recentd_names ) ;
for ( int i = 0 ; i < recentd_paths . size ( ) ; i + + ) {
recent - > add_item ( recentd_names [ i ] , theme_cache . folder ) ;
recent - > set_item_metadata ( - 1 , recentd_paths [ i ] ) ;
2022-09-07 01:09:32 +08:00
recent - > set_item_icon_modulate ( - 1 , theme_cache . folder_icon_color ) ;
2022-09-01 23:52:49 +08:00
}
EditorSettings : : get_singleton ( ) - > set_recent_dirs ( recentd ) ;
}
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _recent_selected ( int p_idx ) {
Vector < String > recentd = EditorSettings : : get_singleton ( ) - > get_recent_dirs ( ) ;
ERR_FAIL_INDEX ( p_idx , recentd . size ( ) ) ;
dir_access - > change_dir ( recent - > get_item_metadata ( p_idx ) ) ;
update_file_list ( ) ;
update_dir ( ) ;
_push_history ( ) ;
}
void EditorFileDialog : : _go_up ( ) {
2022-01-12 07:53:52 +08:00
dir_access - > change_dir ( get_current_dir ( ) . get_base_dir ( ) ) ;
2015-06-06 20:44:38 +08:00
update_file_list ( ) ;
update_dir ( ) ;
_push_history ( ) ;
}
void EditorFileDialog : : _go_back ( ) {
if ( local_history_pos < = 0 ) {
return ;
}
local_history_pos - - ;
dir_access - > change_dir ( local_history [ local_history_pos ] ) ;
update_file_list ( ) ;
update_dir ( ) ;
dir_prev - > set_disabled ( local_history_pos = = 0 ) ;
dir_next - > set_disabled ( local_history_pos = = local_history . size ( ) - 1 ) ;
}
2020-05-14 20:29:06 +08:00
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _go_forward ( ) {
2023-01-03 16:23:49 +08:00
if ( local_history_pos > = local_history . size ( ) - 1 ) {
2015-06-06 20:44:38 +08:00
return ;
}
local_history_pos + + ;
dir_access - > change_dir ( local_history [ local_history_pos ] ) ;
update_file_list ( ) ;
update_dir ( ) ;
dir_prev - > set_disabled ( local_history_pos = = 0 ) ;
dir_next - > set_disabled ( local_history_pos = = local_history . size ( ) - 1 ) ;
}
2015-12-07 06:35:31 +08:00
bool EditorFileDialog : : default_show_hidden_files = false ;
2015-05-31 12:59:42 +08:00
2015-12-16 00:39:13 +08:00
EditorFileDialog : : DisplayMode EditorFileDialog : : default_display_mode = DISPLAY_THUMBNAILS ;
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : set_display_mode ( DisplayMode p_mode ) {
2020-05-14 22:41:43 +08:00
if ( display_mode = = p_mode ) {
2015-06-06 20:44:38 +08:00
return ;
2020-05-14 22:41:43 +08:00
}
2015-06-06 20:44:38 +08:00
if ( p_mode = = DISPLAY_THUMBNAILS ) {
mode_list - > set_pressed ( false ) ;
mode_thumbnails - > set_pressed ( true ) ;
} else {
mode_thumbnails - > set_pressed ( false ) ;
mode_list - > set_pressed ( true ) ;
}
display_mode = p_mode ;
2017-01-15 01:03:38 +08:00
invalidate ( ) ;
2015-06-06 20:44:38 +08:00
}
EditorFileDialog : : DisplayMode EditorFileDialog : : get_display_mode ( ) const {
return display_mode ;
}
2015-05-31 12:59:42 +08:00
void EditorFileDialog : : _bind_methods ( ) {
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " _cancel_pressed " ) , & EditorFileDialog : : _cancel_pressed ) ;
2017-03-05 23:44:50 +08:00
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " clear_filters " ) , & EditorFileDialog : : clear_filters ) ;
2022-07-05 05:26:26 +08:00
ClassDB : : bind_method ( D_METHOD ( " add_filter " , " filter " , " description " ) , & EditorFileDialog : : add_filter , DEFVAL ( " " ) ) ;
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_current_dir " ) , & EditorFileDialog : : get_current_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " get_current_file " ) , & EditorFileDialog : : get_current_file ) ;
ClassDB : : bind_method ( D_METHOD ( " get_current_path " ) , & EditorFileDialog : : get_current_path ) ;
ClassDB : : bind_method ( D_METHOD ( " set_current_dir " , " dir " ) , & EditorFileDialog : : set_current_dir ) ;
ClassDB : : bind_method ( D_METHOD ( " set_current_file " , " file " ) , & EditorFileDialog : : set_current_file ) ;
ClassDB : : bind_method ( D_METHOD ( " set_current_path " , " path " ) , & EditorFileDialog : : set_current_path ) ;
2020-03-07 01:00:16 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_file_mode " , " mode " ) , & EditorFileDialog : : set_file_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_file_mode " ) , & EditorFileDialog : : get_file_mode ) ;
2017-08-09 19:19:41 +08:00
ClassDB : : bind_method ( D_METHOD ( " get_vbox " ) , & EditorFileDialog : : get_vbox ) ;
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " set_access " , " access " ) , & EditorFileDialog : : set_access ) ;
ClassDB : : bind_method ( D_METHOD ( " get_access " ) , & EditorFileDialog : : get_access ) ;
ClassDB : : bind_method ( D_METHOD ( " set_show_hidden_files " , " show " ) , & EditorFileDialog : : set_show_hidden_files ) ;
ClassDB : : bind_method ( D_METHOD ( " is_showing_hidden_files " ) , & EditorFileDialog : : is_showing_hidden_files ) ;
2019-06-28 15:29:50 +08:00
ClassDB : : bind_method ( D_METHOD ( " _update_file_name " ) , & EditorFileDialog : : update_file_name ) ;
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " _update_dir " ) , & EditorFileDialog : : update_dir ) ;
2020-03-04 02:43:37 +08:00
ClassDB : : bind_method ( D_METHOD ( " _update_file_list " ) , & EditorFileDialog : : update_file_list ) ;
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " _thumbnail_done " ) , & EditorFileDialog : : _thumbnail_done ) ;
ClassDB : : bind_method ( D_METHOD ( " set_display_mode " , " mode " ) , & EditorFileDialog : : set_display_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_display_mode " ) , & EditorFileDialog : : get_display_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " _thumbnail_result " ) , & EditorFileDialog : : _thumbnail_result ) ;
ClassDB : : bind_method ( D_METHOD ( " set_disable_overwrite_warning " , " disable " ) , & EditorFileDialog : : set_disable_overwrite_warning ) ;
ClassDB : : bind_method ( D_METHOD ( " is_overwrite_warning_disabled " ) , & EditorFileDialog : : is_overwrite_warning_disabled ) ;
2017-03-05 23:44:50 +08:00
2017-02-13 19:47:24 +08:00
ClassDB : : bind_method ( D_METHOD ( " invalidate " ) , & EditorFileDialog : : invalidate ) ;
2017-03-05 23:44:50 +08:00
2015-05-31 12:59:42 +08:00
ADD_SIGNAL ( MethodInfo ( " file_selected " , PropertyInfo ( Variant : : STRING , " path " ) ) ) ;
2020-02-18 05:06:54 +08:00
ADD_SIGNAL ( MethodInfo ( " files_selected " , PropertyInfo ( Variant : : PACKED_STRING_ARRAY , " paths " ) ) ) ;
2015-05-31 12:59:42 +08:00
ADD_SIGNAL ( MethodInfo ( " dir_selected " , PropertyInfo ( Variant : : STRING , " dir " ) ) ) ;
2017-03-05 23:44:50 +08:00
2017-12-05 06:11:31 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " access " , PROPERTY_HINT_ENUM , " Resources,User data,File system " ) , " set_access " , " get_access " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " display_mode " , PROPERTY_HINT_ENUM , " Thumbnails,List " ) , " set_display_mode " , " get_display_mode " ) ;
2020-03-07 01:00:16 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " file_mode " , PROPERTY_HINT_ENUM , " Open one,Open many,Open folder,Open any,Save " ) , " set_file_mode " , " get_file_mode " ) ;
2021-10-30 02:15:33 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " current_dir " , PROPERTY_HINT_DIR , " " , PROPERTY_USAGE_NONE ) , " set_current_dir " , " get_current_dir " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " current_file " , PROPERTY_HINT_FILE , " * " , PROPERTY_USAGE_NONE ) , " set_current_file " , " get_current_file " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " current_path " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NONE ) , " set_current_path " , " get_current_path " ) ;
2017-12-05 06:11:31 +08:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " show_hidden_files " ) , " set_show_hidden_files " , " is_showing_hidden_files " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " disable_overwrite_warning " ) , " set_disable_overwrite_warning " , " is_overwrite_warning_disabled " ) ;
2020-03-07 01:00:16 +08:00
BIND_ENUM_CONSTANT ( FILE_MODE_OPEN_FILE ) ;
BIND_ENUM_CONSTANT ( FILE_MODE_OPEN_FILES ) ;
BIND_ENUM_CONSTANT ( FILE_MODE_OPEN_DIR ) ;
BIND_ENUM_CONSTANT ( FILE_MODE_OPEN_ANY ) ;
BIND_ENUM_CONSTANT ( FILE_MODE_SAVE_FILE ) ;
2017-08-20 23:45:01 +08:00
BIND_ENUM_CONSTANT ( ACCESS_RESOURCES ) ;
BIND_ENUM_CONSTANT ( ACCESS_USERDATA ) ;
BIND_ENUM_CONSTANT ( ACCESS_FILESYSTEM ) ;
2017-09-13 03:09:06 +08:00
BIND_ENUM_CONSTANT ( DISPLAY_THUMBNAILS ) ;
BIND_ENUM_CONSTANT ( DISPLAY_LIST ) ;
2015-05-31 12:59:42 +08:00
}
void EditorFileDialog : : set_show_hidden_files ( bool p_show ) {
2020-10-06 21:42:25 +08:00
if ( p_show = = show_hidden_files ) {
return ;
}
EditorSettings : : get_singleton ( ) - > set ( " filesystem/file_dialog/show_hidden_files " , p_show ) ;
2015-05-31 12:59:42 +08:00
show_hidden_files = p_show ;
2019-06-10 02:00:30 +08:00
show_hidden - > set_pressed ( p_show ) ;
2015-05-31 12:59:42 +08:00
invalidate ( ) ;
}
bool EditorFileDialog : : is_showing_hidden_files ( ) const {
return show_hidden_files ;
}
void EditorFileDialog : : set_default_show_hidden_files ( bool p_show ) {
default_show_hidden_files = p_show ;
}
2015-12-16 00:39:13 +08:00
void EditorFileDialog : : set_default_display_mode ( DisplayMode p_mode ) {
default_display_mode = p_mode ;
}
2015-06-06 20:44:38 +08:00
void EditorFileDialog : : _save_to_recent ( ) {
2022-09-29 17:53:28 +08:00
String cur_dir = get_current_dir ( ) ;
Vector < String > recent_new = EditorSettings : : get_singleton ( ) - > get_recent_dirs ( ) ;
2015-06-06 20:44:38 +08:00
const int max = 20 ;
int count = 0 ;
2022-09-29 17:53:28 +08:00
bool res = cur_dir . begins_with ( " res:// " ) ;
2015-06-06 20:44:38 +08:00
2022-09-29 17:53:28 +08:00
for ( int i = 0 ; i < recent_new . size ( ) ; i + + ) {
bool cres = recent_new [ i ] . begins_with ( " res:// " ) ;
if ( recent_new [ i ] = = cur_dir | | ( res = = cres & & count > max ) ) {
recent_new . remove_at ( i ) ;
2015-06-06 20:44:38 +08:00
i - - ;
} else {
count + + ;
}
}
2022-09-29 17:53:28 +08:00
recent_new . insert ( 0 , cur_dir ) ;
2015-06-06 20:44:38 +08:00
2022-09-29 17:53:28 +08:00
EditorSettings : : get_singleton ( ) - > set_recent_dirs ( recent_new ) ;
2015-06-06 20:44:38 +08:00
}
2016-06-20 11:38:13 +08:00
void EditorFileDialog : : set_disable_overwrite_warning ( bool p_disable ) {
disable_overwrite_warning = p_disable ;
}
bool EditorFileDialog : : is_overwrite_warning_disabled ( ) const {
return disable_overwrite_warning ;
}
2022-02-03 08:21:52 +08:00
void EditorFileDialog : : set_previews_enabled ( bool p_enabled ) {
previews_enabled = p_enabled ;
}
bool EditorFileDialog : : are_previews_enabled ( ) {
return previews_enabled ;
}
2015-05-31 12:59:42 +08:00
EditorFileDialog : : EditorFileDialog ( ) {
2015-12-07 06:35:31 +08:00
show_hidden_files = default_show_hidden_files ;
2015-12-16 00:39:13 +08:00
display_mode = default_display_mode ;
2015-05-31 12:59:42 +08:00
VBoxContainer * vbc = memnew ( VBoxContainer ) ;
add_child ( vbc ) ;
2016-05-04 09:25:37 +08:00
set_title ( TTR ( " Save a File " ) ) ;
2015-05-31 12:59:42 +08:00
2021-08-14 05:31:57 +08:00
ED_SHORTCUT ( " file_dialog/go_back " , TTR ( " Go Back " ) , KeyModifierMask : : ALT | Key : : LEFT ) ;
ED_SHORTCUT ( " file_dialog/go_forward " , TTR ( " Go Forward " ) , KeyModifierMask : : ALT | Key : : RIGHT ) ;
ED_SHORTCUT ( " file_dialog/go_up " , TTR ( " Go Up " ) , KeyModifierMask : : ALT | Key : : UP ) ;
ED_SHORTCUT ( " file_dialog/refresh " , TTR ( " Refresh " ) , Key : : F5 ) ;
2022-09-02 17:37:48 +08:00
ED_SHORTCUT ( " file_dialog/toggle_hidden_files " , TTR ( " Toggle Hidden Files " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : H ) ;
2021-08-14 05:31:57 +08:00
ED_SHORTCUT ( " file_dialog/toggle_favorite " , TTR ( " Toggle Favorite " ) , KeyModifierMask : : ALT | Key : : F ) ;
ED_SHORTCUT ( " file_dialog/toggle_mode " , TTR ( " Toggle Mode " ) , KeyModifierMask : : ALT | Key : : V ) ;
2022-09-02 17:37:48 +08:00
ED_SHORTCUT ( " file_dialog/create_folder " , TTR ( " Create Folder " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : N ) ;
2021-08-14 05:31:57 +08:00
ED_SHORTCUT ( " file_dialog/delete " , TTR ( " Delete " ) , Key : : KEY_DELETE ) ;
2022-09-02 17:37:48 +08:00
ED_SHORTCUT ( " file_dialog/focus_path " , TTR ( " Focus Path " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : D ) ;
ED_SHORTCUT ( " file_dialog/move_favorite_up " , TTR ( " Move Favorite Up " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : UP ) ;
ED_SHORTCUT ( " file_dialog/move_favorite_down " , TTR ( " Move Favorite Down " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : DOWN ) ;
2016-06-19 01:32:04 +08:00
2015-05-31 12:59:42 +08:00
HBoxContainer * pathhb = memnew ( HBoxContainer ) ;
2015-06-06 20:44:38 +08:00
2020-06-20 02:49:04 +08:00
dir_prev = memnew ( Button ) ;
dir_prev - > set_flat ( true ) ;
2022-08-25 18:42:17 +08:00
dir_prev - > set_tooltip_text ( TTR ( " Go to previous folder. " ) ) ;
2020-06-20 02:49:04 +08:00
dir_next = memnew ( Button ) ;
dir_next - > set_flat ( true ) ;
2022-08-25 18:42:17 +08:00
dir_next - > set_tooltip_text ( TTR ( " Go to next folder. " ) ) ;
2020-06-20 02:49:04 +08:00
dir_up = memnew ( Button ) ;
dir_up - > set_flat ( true ) ;
2022-08-25 18:42:17 +08:00
dir_up - > set_tooltip_text ( TTR ( " Go to parent folder. " ) ) ;
2015-06-06 20:44:38 +08:00
pathhb - > add_child ( dir_prev ) ;
pathhb - > add_child ( dir_next ) ;
pathhb - > add_child ( dir_up ) ;
2020-02-22 01:28:45 +08:00
dir_prev - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _go_back ) ) ;
dir_next - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _go_forward ) ) ;
dir_up - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _go_up ) ) ;
2015-06-06 20:44:38 +08:00
2021-07-08 21:29:15 +08:00
Label * l = memnew ( Label ( TTR ( " Path: " ) ) ) ;
l - > set_theme_type_variation ( " HeaderSmall " ) ;
pathhb - > add_child ( l ) ;
2017-09-28 03:44:48 +08:00
2020-02-10 16:19:29 +08:00
drives_container = memnew ( HBoxContainer ) ;
pathhb - > add_child ( drives_container ) ;
2015-06-06 20:44:38 +08:00
dir = memnew ( LineEdit ) ;
2022-04-19 18:27:18 +08:00
dir - > set_structured_text_bidi_override ( TextServer : : STRUCTURED_TEXT_FILE ) ;
2015-05-31 12:59:42 +08:00
pathhb - > add_child ( dir ) ;
2020-03-07 01:00:16 +08:00
dir - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-05-31 12:59:42 +08:00
2020-06-20 02:49:04 +08:00
refresh = memnew ( Button ) ;
refresh - > set_flat ( true ) ;
2022-08-25 18:42:17 +08:00
refresh - > set_tooltip_text ( TTR ( " Refresh files. " ) ) ;
2020-02-22 01:28:45 +08:00
refresh - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : update_file_list ) ) ;
2015-12-05 02:33:30 +08:00
pathhb - > add_child ( refresh ) ;
2020-06-20 02:49:04 +08:00
favorite = memnew ( Button ) ;
favorite - > set_flat ( true ) ;
2015-06-06 20:44:38 +08:00
favorite - > set_toggle_mode ( true ) ;
2022-08-25 18:42:17 +08:00
favorite - > set_tooltip_text ( TTR ( " (Un)favorite current folder. " ) ) ;
2020-02-22 01:28:45 +08:00
favorite - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _favorite_pressed ) ) ;
2015-06-06 20:44:38 +08:00
pathhb - > add_child ( favorite ) ;
2020-06-20 02:49:04 +08:00
show_hidden = memnew ( Button ) ;
show_hidden - > set_flat ( true ) ;
2019-06-10 02:00:30 +08:00
show_hidden - > set_toggle_mode ( true ) ;
show_hidden - > set_pressed ( is_showing_hidden_files ( ) ) ;
2022-08-25 18:42:17 +08:00
show_hidden - > set_tooltip_text ( TTR ( " Toggle the visibility of hidden files. " ) ) ;
2020-02-22 01:28:45 +08:00
show_hidden - > connect ( " toggled " , callable_mp ( this , & EditorFileDialog : : set_show_hidden_files ) ) ;
2019-06-10 02:00:30 +08:00
pathhb - > add_child ( show_hidden ) ;
2017-06-14 22:00:39 +08:00
2017-12-25 12:29:00 +08:00
pathhb - > add_child ( memnew ( VSeparator ) ) ;
2019-06-10 02:00:30 +08:00
Ref < ButtonGroup > view_mode_group ;
2021-06-18 06:03:09 +08:00
view_mode_group . instantiate ( ) ;
2019-06-10 02:00:30 +08:00
2020-06-20 02:49:04 +08:00
mode_thumbnails = memnew ( Button ) ;
mode_thumbnails - > set_flat ( true ) ;
2022-07-29 04:56:41 +08:00
mode_thumbnails - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : set_display_mode ) . bind ( DISPLAY_THUMBNAILS ) ) ;
2015-06-06 20:44:38 +08:00
mode_thumbnails - > set_toggle_mode ( true ) ;
2015-12-16 00:39:13 +08:00
mode_thumbnails - > set_pressed ( display_mode = = DISPLAY_THUMBNAILS ) ;
2017-06-14 22:00:39 +08:00
mode_thumbnails - > set_button_group ( view_mode_group ) ;
2022-08-25 18:42:17 +08:00
mode_thumbnails - > set_tooltip_text ( TTR ( " View items as a grid of thumbnails. " ) ) ;
2015-06-06 20:44:38 +08:00
pathhb - > add_child ( mode_thumbnails ) ;
2015-12-16 00:39:13 +08:00
2020-06-20 02:49:04 +08:00
mode_list = memnew ( Button ) ;
mode_list - > set_flat ( true ) ;
2022-07-29 04:56:41 +08:00
mode_list - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : set_display_mode ) . bind ( DISPLAY_LIST ) ) ;
2015-06-06 20:44:38 +08:00
mode_list - > set_toggle_mode ( true ) ;
2015-12-16 00:39:13 +08:00
mode_list - > set_pressed ( display_mode = = DISPLAY_LIST ) ;
2017-06-14 22:00:39 +08:00
mode_list - > set_button_group ( view_mode_group ) ;
2022-08-25 18:42:17 +08:00
mode_list - > set_tooltip_text ( TTR ( " View items as a list. " ) ) ;
2015-06-06 20:44:38 +08:00
pathhb - > add_child ( mode_list ) ;
2020-02-10 16:19:29 +08:00
shortcuts_container = memnew ( HBoxContainer ) ;
pathhb - > add_child ( shortcuts_container ) ;
2015-05-31 12:59:42 +08:00
drives = memnew ( OptionButton ) ;
2020-02-22 01:28:45 +08:00
drives - > connect ( " item_selected " , callable_mp ( this , & EditorFileDialog : : _select_drive ) ) ;
2020-04-07 02:07:08 +08:00
pathhb - > add_child ( drives ) ;
2015-05-31 12:59:42 +08:00
makedir = memnew ( Button ) ;
2016-05-04 09:25:37 +08:00
makedir - > set_text ( TTR ( " Create Folder " ) ) ;
2020-02-22 01:28:45 +08:00
makedir - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _make_dir ) ) ;
2015-05-31 12:59:42 +08:00
pathhb - > add_child ( makedir ) ;
2017-09-28 03:44:48 +08:00
list_hb = memnew ( HSplitContainer ) ;
2015-05-31 12:59:42 +08:00
2017-09-28 03:44:48 +08:00
vbc - > add_child ( pathhb ) ;
2015-06-06 20:44:38 +08:00
vbc - > add_child ( list_hb ) ;
2020-03-07 01:00:16 +08:00
list_hb - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-06-06 20:44:38 +08:00
2017-12-25 12:29:00 +08:00
VSplitContainer * vsc = memnew ( VSplitContainer ) ;
list_hb - > add_child ( vsc ) ;
2015-06-06 20:44:38 +08:00
VBoxContainer * fav_vb = memnew ( VBoxContainer ) ;
2017-12-25 12:29:00 +08:00
vsc - > add_child ( fav_vb ) ;
fav_vb - > set_custom_minimum_size ( Size2 ( 150 , 100 ) * EDSCALE ) ;
2020-03-07 01:00:16 +08:00
fav_vb - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-06-06 20:44:38 +08:00
HBoxContainer * fav_hb = memnew ( HBoxContainer ) ;
fav_vb - > add_child ( fav_hb ) ;
2021-07-08 21:29:15 +08:00
l = memnew ( Label ( TTR ( " Favorites: " ) ) ) ;
l - > set_theme_type_variation ( " HeaderSmall " ) ;
fav_hb - > add_child ( l ) ;
2015-06-06 20:44:38 +08:00
fav_hb - > add_spacer ( ) ;
2020-06-20 02:49:04 +08:00
fav_up = memnew ( Button ) ;
fav_up - > set_flat ( true ) ;
2015-06-06 20:44:38 +08:00
fav_hb - > add_child ( fav_up ) ;
2020-02-22 01:28:45 +08:00
fav_up - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _favorite_move_up ) ) ;
2020-06-20 02:49:04 +08:00
fav_down = memnew ( Button ) ;
fav_down - > set_flat ( true ) ;
2015-06-06 20:44:38 +08:00
fav_hb - > add_child ( fav_down ) ;
2020-02-22 01:28:45 +08:00
fav_down - > connect ( " pressed " , callable_mp ( this , & EditorFileDialog : : _favorite_move_down ) ) ;
2015-06-06 20:44:38 +08:00
favorites = memnew ( ItemList ) ;
2017-12-25 12:29:00 +08:00
fav_vb - > add_child ( favorites ) ;
2020-03-07 01:00:16 +08:00
favorites - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2020-02-22 01:28:45 +08:00
favorites - > connect ( " item_selected " , callable_mp ( this , & EditorFileDialog : : _favorite_selected ) ) ;
2015-06-06 20:44:38 +08:00
2017-12-25 12:29:00 +08:00
VBoxContainer * rec_vb = memnew ( VBoxContainer ) ;
vsc - > add_child ( rec_vb ) ;
rec_vb - > set_custom_minimum_size ( Size2 ( 150 , 100 ) * EDSCALE ) ;
2020-03-07 01:00:16 +08:00
rec_vb - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-06-06 20:44:38 +08:00
recent = memnew ( ItemList ) ;
2019-06-10 09:09:10 +08:00
recent - > set_allow_reselect ( true ) ;
2017-12-25 12:29:00 +08:00
rec_vb - > add_margin_child ( TTR ( " Recent: " ) , recent , true ) ;
2020-02-22 01:28:45 +08:00
recent - > connect ( " item_selected " , callable_mp ( this , & EditorFileDialog : : _recent_selected ) ) ;
2015-06-06 20:44:38 +08:00
VBoxContainer * item_vb = memnew ( VBoxContainer ) ;
list_hb - > add_child ( item_vb ) ;
2017-12-25 12:29:00 +08:00
item_vb - > set_custom_minimum_size ( Size2 ( 320 , 0 ) * EDSCALE ) ;
2015-06-06 20:44:38 +08:00
2017-10-06 22:01:54 +08:00
HBoxContainer * preview_hb = memnew ( HBoxContainer ) ;
2020-03-07 01:00:16 +08:00
preview_hb - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2017-10-06 22:01:54 +08:00
item_vb - > add_child ( preview_hb ) ;
2015-05-31 12:59:42 +08:00
2017-10-06 22:01:54 +08:00
VBoxContainer * list_vb = memnew ( VBoxContainer ) ;
2020-03-07 01:00:16 +08:00
list_vb - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2021-07-08 21:29:15 +08:00
l = memnew ( Label ( TTR ( " Directories & Files: " ) ) ) ;
l - > set_theme_type_variation ( " HeaderSmall " ) ;
list_vb - > add_child ( l ) ;
2017-10-06 22:01:54 +08:00
preview_hb - > add_child ( list_vb ) ;
2015-05-31 12:59:42 +08:00
2019-06-10 09:09:10 +08:00
// Item (files and folders) list with context menu.
2017-12-02 08:37:32 +08:00
2017-10-06 22:01:54 +08:00
item_list = memnew ( ItemList ) ;
2020-03-07 01:00:16 +08:00
item_list - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2021-11-26 07:53:27 +08:00
item_list - > connect ( " item_clicked " , callable_mp ( this , & EditorFileDialog : : _item_list_item_rmb_clicked ) ) ;
item_list - > connect ( " empty_clicked " , callable_mp ( this , & EditorFileDialog : : _item_list_empty_clicked ) ) ;
2017-12-02 08:37:32 +08:00
item_list - > set_allow_rmb_select ( true ) ;
2021-08-21 06:22:09 +08:00
2017-10-06 22:01:54 +08:00
list_vb - > add_child ( item_list ) ;
2015-05-31 12:59:42 +08:00
2017-12-02 08:37:32 +08:00
item_menu = memnew ( PopupMenu ) ;
2020-02-22 01:28:45 +08:00
item_menu - > connect ( " id_pressed " , callable_mp ( this , & EditorFileDialog : : _item_menu_id_pressed ) ) ;
2017-12-02 08:37:32 +08:00
add_child ( item_menu ) ;
2019-06-10 09:09:10 +08:00
// Other stuff.
2017-12-02 08:37:32 +08:00
2015-05-31 12:59:42 +08:00
preview_vb = memnew ( VBoxContainer ) ;
2017-10-06 22:01:54 +08:00
preview_hb - > add_child ( preview_vb ) ;
2015-05-31 12:59:42 +08:00
CenterContainer * prev_cc = memnew ( CenterContainer ) ;
2016-05-04 09:25:37 +08:00
preview_vb - > add_margin_child ( TTR ( " Preview: " ) , prev_cc ) ;
2017-01-13 05:27:27 +08:00
preview = memnew ( TextureRect ) ;
2015-05-31 12:59:42 +08:00
prev_cc - > add_child ( preview ) ;
preview_vb - > hide ( ) ;
2019-10-26 23:29:22 +08:00
file_box = memnew ( HBoxContainer ) ;
2021-07-08 21:29:15 +08:00
l = memnew ( Label ( TTR ( " File: " ) ) ) ;
l - > set_theme_type_variation ( " HeaderSmall " ) ;
file_box - > add_child ( l ) ;
2015-05-31 12:59:42 +08:00
file = memnew ( LineEdit ) ;
2022-04-19 18:27:18 +08:00
file - > set_structured_text_bidi_override ( TextServer : : STRUCTURED_TEXT_FILE ) ;
2017-10-06 22:01:54 +08:00
file - > set_stretch_ratio ( 4 ) ;
2020-03-07 01:00:16 +08:00
file - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2019-10-26 23:29:22 +08:00
file_box - > add_child ( file ) ;
2015-05-31 12:59:42 +08:00
filter = memnew ( OptionButton ) ;
2017-10-06 22:01:54 +08:00
filter - > set_stretch_ratio ( 3 ) ;
2020-03-07 01:00:16 +08:00
filter - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2019-06-10 09:09:10 +08:00
filter - > set_clip_text ( true ) ; // Too many extensions overflow it.
2019-10-26 23:29:22 +08:00
file_box - > add_child ( filter ) ;
2020-03-07 01:00:16 +08:00
file_box - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2019-10-26 23:29:22 +08:00
item_vb - > add_child ( file_box ) ;
2015-05-31 12:59:42 +08:00
dir_access = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
_update_drives ( ) ;
2020-02-22 01:28:45 +08:00
connect ( " confirmed " , callable_mp ( this , & EditorFileDialog : : _action_pressed ) ) ;
2022-07-29 04:56:41 +08:00
item_list - > connect ( " item_selected " , callable_mp ( this , & EditorFileDialog : : _item_selected ) , CONNECT_DEFERRED ) ;
item_list - > connect ( " multi_selected " , callable_mp ( this , & EditorFileDialog : : _multi_selected ) , CONNECT_DEFERRED ) ;
item_list - > connect ( " item_activated " , callable_mp ( this , & EditorFileDialog : : _item_dc_selected ) . bind ( ) ) ;
2021-11-26 07:53:27 +08:00
item_list - > connect ( " empty_clicked " , callable_mp ( this , & EditorFileDialog : : _items_clear_selection ) ) ;
2021-06-17 00:43:34 +08:00
dir - > connect ( " text_submitted " , callable_mp ( this , & EditorFileDialog : : _dir_submitted ) ) ;
file - > connect ( " text_submitted " , callable_mp ( this , & EditorFileDialog : : _file_submitted ) ) ;
2020-02-22 01:28:45 +08:00
filter - > connect ( " item_selected " , callable_mp ( this , & EditorFileDialog : : _filter_selected ) ) ;
2015-05-31 12:59:42 +08:00
confirm_save = memnew ( ConfirmationDialog ) ;
add_child ( confirm_save ) ;
2020-02-22 01:28:45 +08:00
confirm_save - > connect ( " confirmed " , callable_mp ( this , & EditorFileDialog : : _save_confirm_pressed ) ) ;
2015-05-31 12:59:42 +08:00
2022-02-03 08:21:52 +08:00
dep_remove_dialog = memnew ( DependencyRemoveDialog ) ;
add_child ( dep_remove_dialog ) ;
global_remove_dialog = memnew ( ConfirmationDialog ) ;
global_remove_dialog - > set_text ( TTR ( " Remove the selected files? For safety only files and empty directories can be deleted from here. (Cannot be undone.) \n Depending on your filesystem configuration, the files will either be moved to the system trash or deleted permanently. " ) ) ;
global_remove_dialog - > connect ( " confirmed " , callable_mp ( this , & EditorFileDialog : : _delete_files_global ) ) ;
add_child ( global_remove_dialog ) ;
2017-12-02 08:37:32 +08:00
2015-05-31 12:59:42 +08:00
makedialog = memnew ( ConfirmationDialog ) ;
2016-05-04 09:25:37 +08:00
makedialog - > set_title ( TTR ( " Create Folder " ) ) ;
2015-05-31 12:59:42 +08:00
VBoxContainer * makevb = memnew ( VBoxContainer ) ;
makedialog - > add_child ( makevb ) ;
2017-01-10 12:49:55 +08:00
2015-05-31 12:59:42 +08:00
makedirname = memnew ( LineEdit ) ;
2022-04-19 18:27:18 +08:00
makedirname - > set_structured_text_bidi_override ( TextServer : : STRUCTURED_TEXT_FILE ) ;
2016-05-04 09:25:37 +08:00
makevb - > add_margin_child ( TTR ( " Name: " ) , makedirname ) ;
2015-05-31 12:59:42 +08:00
add_child ( makedialog ) ;
makedialog - > register_text_enter ( makedirname ) ;
2020-02-22 01:28:45 +08:00
makedialog - > connect ( " confirmed " , callable_mp ( this , & EditorFileDialog : : _make_dir_confirm ) ) ;
2022-02-03 08:21:52 +08:00
error_dialog = memnew ( AcceptDialog ) ;
add_child ( error_dialog ) ;
2015-05-31 12:59:42 +08:00
update_filters ( ) ;
update_dir ( ) ;
set_hide_on_ok ( false ) ;
vbox = vbc ;
2020-05-14 22:41:43 +08:00
if ( register_func ) {
2015-05-31 12:59:42 +08:00
register_func ( this ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}
EditorFileDialog : : ~ EditorFileDialog ( ) {
2020-05-14 22:41:43 +08:00
if ( unregister_func ) {
2015-05-31 12:59:42 +08:00
unregister_func ( this ) ;
2020-05-14 22:41:43 +08:00
}
2015-05-31 12:59:42 +08:00
}