diff options
| author | Rémi Verschelde <rverschelde@gmail.com> | 2017-12-09 16:34:35 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-12-09 16:34:35 +0100 | 
| commit | 5b54690323342b1f99189d0e94dcebd2d410f466 (patch) | |
| tree | 64ed7e89bbb3593cf97b3c5d2572976ffe98b69e | |
| parent | 5c7644d167c2f075f9b4b07eb586ab611919ef28 (diff) | |
| parent | 3e5074897252cf957ae31719f4501968d514064e (diff) | |
Merge pull request #13446 from gad-o/duplicate_file
Add  duplicate option to filesystem dock
| -rw-r--r-- | editor/filesystem_dock.cpp | 100 | ||||
| -rw-r--r-- | editor/filesystem_dock.h | 6 | 
2 files changed, 106 insertions, 0 deletions
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 4a74ceac6d..9ece36ea80 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -806,6 +806,39 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_  	memdelete(da);  } +void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const { +	//Ensure folder paths end with "/" +	String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/"); +	String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/"); + +	if (new_path == old_path) { +		return; +	} else if (old_path == "res://") { +		EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root.")); +		return; +	} else if (!p_item.is_file && new_path.begins_with(old_path)) { +		//This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/" +		EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.\n") + old_path + "\n"); +		return; +	} + +	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); +	print_line("Duplicating " + old_path + " -> " + new_path); +	Error err = da->copy(old_path, new_path); +	if (err == OK) { +		//Move/Rename any corresponding import settings too +		if (p_item.is_file && FileAccess::exists(old_path + ".import")) { +			err = da->copy(old_path + ".import", new_path + ".import"); +			if (err != OK) { +				EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:\n") + old_path + ".import\n"); +			} +		} +	} else { +		EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:\n") + old_path + "\n"); +	} +	memdelete(da); +} +  void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const {  	//The following code assumes that the following holds:  	// 1) EditorFileSystem contains the old paths/folder structure from before the rename/move. @@ -888,6 +921,39 @@ void FileSystemDock::_rename_operation_confirm() {  	_rescan();  } +void FileSystemDock::_duplicate_operation_confirm() { + +	String new_name = duplicate_dialog_text->get_text().strip_edges(); +	if (new_name.length() == 0) { +		EditorNode::get_singleton()->show_warning(TTR("No name provided.")); +		return; +	} else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) { +		EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); +		return; +	} + +	String old_path = to_duplicate.path.ends_with("/") ? to_duplicate.path.substr(0, to_duplicate.path.length() - 1) : to_rename.path; +	String new_path = old_path.get_base_dir().plus_file(new_name); +	if (old_path == new_path) { +		return; +	} + +	//Present a more user friendly warning for name conflict +	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); +	if (da->file_exists(new_path) || da->dir_exists(new_path)) { +		EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); +		memdelete(da); +		return; +	} +	memdelete(da); + +	_try_duplicate_item(to_duplicate, new_name); + +	//Rescan everything +	print_line("call rescan!"); +	_rescan(); +} +  void FileSystemDock::_move_operation_confirm(const String &p_to_path) {  	Map<String, String> renames; @@ -1003,6 +1069,27 @@ void FileSystemDock::_file_option(int p_option) {  				//2) warn  			}  		} break; +		case FILE_DUPLICATE: { +			int idx = files->get_current(); +			if (idx < 0 || idx >= files->get_item_count()) +				break; + +			to_duplicate.path = files->get_item_metadata(idx); +			to_duplicate.is_file = !to_duplicate.path.ends_with("/"); +			if (to_duplicate.is_file) { +				String name = to_duplicate.path.get_file(); +				duplicate_dialog->set_title(TTR("Duplicating file:") + " " + name); +				duplicate_dialog_text->set_text(name); +				duplicate_dialog_text->select(0, name.find_last(".")); +			} else { +				String name = to_duplicate.path.substr(0, to_duplicate.path.length() - 1).get_file(); +				duplicate_dialog->set_title(TTR("Duplicating folder:") + " " + name); +				duplicate_dialog_text->set_text(name); +				duplicate_dialog_text->select(0, name.length()); +			} +			duplicate_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); +			duplicate_dialog_text->grab_focus(); +		} break;  		case FILE_INFO: {  		} break; @@ -1459,6 +1546,7 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {  		if (num_items == 1) {  			file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH);  			file_options->add_item(TTR("Rename.."), FILE_RENAME); +			file_options->add_item(TTR("Duplicate.."), FILE_DUPLICATE);  		}  		file_options->add_item(TTR("Move To.."), FILE_MOVE);  		file_options->add_item(TTR("Delete"), FILE_REMOVE); @@ -1570,6 +1658,7 @@ void FileSystemDock::_bind_methods() {  	ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);  	ClassDB::bind_method(D_METHOD("_move_operation_confirm"), &FileSystemDock::_move_operation_confirm);  	ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm); +	ClassDB::bind_method(D_METHOD("_duplicate_operation_confirm"), &FileSystemDock::_duplicate_operation_confirm);  	ClassDB::bind_method(D_METHOD("_search_changed"), &FileSystemDock::_search_changed); @@ -1743,6 +1832,17 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {  	rename_dialog->register_text_enter(rename_dialog_text);  	rename_dialog->connect("confirmed", this, "_rename_operation_confirm"); +	duplicate_dialog = memnew(ConfirmationDialog); +	VBoxContainer *duplicate_dialog_vb = memnew(VBoxContainer); +	duplicate_dialog->add_child(duplicate_dialog_vb); + +	duplicate_dialog_text = memnew(LineEdit); +	duplicate_dialog_vb->add_margin_child(TTR("Name:"), duplicate_dialog_text); +	duplicate_dialog->get_ok()->set_text(TTR("Duplicate")); +	add_child(duplicate_dialog); +	duplicate_dialog->register_text_enter(duplicate_dialog_text); +	duplicate_dialog->connect("confirmed", this, "_duplicate_operation_confirm"); +  	make_dir_dialog = memnew(ConfirmationDialog);  	make_dir_dialog->set_title(TTR("Create Folder"));  	VBoxContainer *make_folder_dialog_vb = memnew(VBoxContainer); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index b004b1974d..bc8d835ba1 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -70,6 +70,7 @@ private:  		FILE_MOVE,  		FILE_RENAME,  		FILE_REMOVE, +		FILE_DUPLICATE,  		FILE_REIMPORT,  		FILE_INFO,  		FILE_NEW_FOLDER, @@ -120,6 +121,8 @@ private:  	EditorDirDialog *move_dialog;  	ConfirmationDialog *rename_dialog;  	LineEdit *rename_dialog_text; +	ConfirmationDialog *duplicate_dialog; +	LineEdit *duplicate_dialog_text;  	ConfirmationDialog *make_dir_dialog;  	LineEdit *make_dir_dialog_text; @@ -136,6 +139,7 @@ private:  				is_file(p_is_file) {}  	};  	FileOrFolder to_rename; +	FileOrFolder to_duplicate;  	Vector<FileOrFolder> to_move;  	Vector<String> history; @@ -172,10 +176,12 @@ private:  	void _get_all_files_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files) const;  	void _find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const;  	void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const; +	void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const;  	void _update_dependencies_after_move(const Map<String, String> &p_renames) const;  	void _make_dir_confirm();  	void _rename_operation_confirm(); +	void _duplicate_operation_confirm();  	void _move_operation_confirm(const String &p_to_path);  	void _file_option(int p_option);  |