2023-04-15 18:15:57 +08:00
/**************************************************************************/
/* directory_create_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. */
/**************************************************************************/
# include "directory_create_dialog.h"
# include "core/io/dir_access.h"
# include "editor/editor_node.h"
2023-06-27 01:18:27 +08:00
# include "editor/gui/editor_validation_panel.h"
2024-01-15 20:14:55 +08:00
# include "editor/themes/editor_scale.h"
2023-04-15 18:15:57 +08:00
# include "scene/gui/box_container.h"
# include "scene/gui/label.h"
# include "scene/gui/line_edit.h"
static String sanitize_input ( const String & p_path ) {
String path = p_path . strip_edges ( ) ;
if ( path . ends_with ( " / " ) ) {
path = path . left ( path . length ( ) - 1 ) ;
}
return path ;
}
String DirectoryCreateDialog : : _validate_path ( const String & p_path ) const {
if ( p_path . is_empty ( ) ) {
return TTR ( " Folder name cannot be empty. " ) ;
}
2023-08-28 21:27:00 +08:00
if ( p_path . contains ( " \\ " ) | | p_path . contains ( " : " ) | | p_path . contains ( " * " ) | |
p_path . contains ( " | " ) | | p_path . contains ( " > " ) ) {
return TTR ( " Folder name contains invalid characters. " ) ;
}
2023-04-15 18:15:57 +08:00
for ( const String & part : p_path . split ( " / " ) ) {
if ( part . is_empty ( ) ) {
return TTR ( " Folder name cannot be empty. " ) ;
}
2023-08-28 21:27:00 +08:00
if ( part . ends_with ( " " ) | | part [ 0 ] = = ' ' ) {
return TTR ( " Folder name cannot begin or end with a space. " ) ;
}
if ( part [ 0 ] = = ' . ' ) {
return TTR ( " Folder name cannot begin with a dot. " ) ;
2023-04-15 18:15:57 +08:00
}
}
Ref < DirAccess > da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
da - > change_dir ( base_dir ) ;
if ( da - > file_exists ( p_path ) ) {
return TTR ( " File with that name already exists. " ) ;
}
if ( da - > dir_exists ( p_path ) ) {
return TTR ( " Folder with that name already exists. " ) ;
}
return String ( ) ;
}
2023-06-27 01:18:27 +08:00
void DirectoryCreateDialog : : _on_dir_path_changed ( ) {
const String path = sanitize_input ( dir_path - > get_text ( ) ) ;
2023-04-15 18:15:57 +08:00
const String error = _validate_path ( path ) ;
if ( error . is_empty ( ) ) {
if ( path . contains ( " / " ) ) {
2023-06-27 01:18:27 +08:00
validation_panel - > set_message ( EditorValidationPanel : : MSG_ID_DEFAULT , TTR ( " Using slashes in folder names will create subfolders recursively. " ) , EditorValidationPanel : : MSG_OK ) ;
2023-04-15 18:15:57 +08:00
}
} else {
2023-06-27 01:18:27 +08:00
validation_panel - > set_message ( EditorValidationPanel : : MSG_ID_DEFAULT , error , EditorValidationPanel : : MSG_ERROR ) ;
2023-04-15 18:15:57 +08:00
}
}
void DirectoryCreateDialog : : ok_pressed ( ) {
const String path = sanitize_input ( dir_path - > get_text ( ) ) ;
// The OK button should be disabled if the path is invalid, but just in case.
const String error = _validate_path ( path ) ;
ERR_FAIL_COND_MSG ( ! error . is_empty ( ) , error ) ;
Error err ;
Ref < DirAccess > da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
err = da - > change_dir ( base_dir ) ;
ERR_FAIL_COND_MSG ( err ! = OK , " Cannot open directory ' " + base_dir + " '. " ) ;
print_verbose ( " Making folder " + path + " in " + base_dir ) ;
err = da - > make_dir_recursive ( path ) ;
if ( err = = OK ) {
2023-12-24 13:59:32 +08:00
emit_signal ( SNAME ( " dir_created " ) , base_dir . path_join ( path ) ) ;
2023-04-15 18:15:57 +08:00
} else {
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " Could not create folder. " ) ) ;
}
hide ( ) ;
}
void DirectoryCreateDialog : : _post_popup ( ) {
ConfirmationDialog : : _post_popup ( ) ;
dir_path - > grab_focus ( ) ;
}
void DirectoryCreateDialog : : config ( const String & p_base_dir ) {
base_dir = p_base_dir ;
label - > set_text ( vformat ( TTR ( " Create new folder in %s: " ) , base_dir ) ) ;
dir_path - > set_text ( " new folder " ) ;
dir_path - > select_all ( ) ;
2023-06-27 01:18:27 +08:00
validation_panel - > update ( ) ;
2023-04-15 18:15:57 +08:00
}
void DirectoryCreateDialog : : _bind_methods ( ) {
2023-12-24 13:59:32 +08:00
ADD_SIGNAL ( MethodInfo ( " dir_created " , PropertyInfo ( Variant : : STRING , " path " ) ) ) ;
2023-04-15 18:15:57 +08:00
}
DirectoryCreateDialog : : DirectoryCreateDialog ( ) {
set_title ( TTR ( " Create Folder " ) ) ;
set_min_size ( Size2i ( 480 , 0 ) * EDSCALE ) ;
VBoxContainer * vb = memnew ( VBoxContainer ) ;
add_child ( vb ) ;
label = memnew ( Label ) ;
label - > set_text_overrun_behavior ( TextServer : : OVERRUN_TRIM_WORD_ELLIPSIS ) ;
vb - > add_child ( label ) ;
dir_path = memnew ( LineEdit ) ;
vb - > add_child ( dir_path ) ;
register_text_enter ( dir_path ) ;
Control * spacing = memnew ( Control ) ;
spacing - > set_custom_minimum_size ( Size2 ( 0 , 10 * EDSCALE ) ) ;
vb - > add_child ( spacing ) ;
2023-06-27 01:18:27 +08:00
validation_panel = memnew ( EditorValidationPanel ) ;
vb - > add_child ( validation_panel ) ;
validation_panel - > add_line ( EditorValidationPanel : : MSG_ID_DEFAULT , TTR ( " Folder name is valid. " ) ) ;
validation_panel - > set_update_callback ( callable_mp ( this , & DirectoryCreateDialog : : _on_dir_path_changed ) ) ;
validation_panel - > set_accept_button ( get_ok_button ( ) ) ;
2023-04-15 18:15:57 +08:00
2023-06-27 01:18:27 +08:00
dir_path - > connect ( " text_changed " , callable_mp ( validation_panel , & EditorValidationPanel : : update ) . unbind ( 1 ) ) ;
2023-04-15 18:15:57 +08:00
}