summaryrefslogtreecommitdiff
path: root/editor/project_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/project_manager.cpp')
-rw-r--r--editor/project_manager.cpp103
1 files changed, 52 insertions, 51 deletions
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 87d008d144..82aa4ead6f 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -147,7 +147,7 @@ private:
}
String _test_path() {
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String valid_path, valid_install_path;
if (d->change_dir(project_path->get_text()) == OK) {
valid_path = project_path->get_text();
@@ -165,7 +165,6 @@ private:
if (valid_path.is_empty()) {
set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR);
- memdelete(d);
get_ok_button()->set_disabled(true);
return "";
}
@@ -179,7 +178,6 @@ private:
if (valid_install_path.is_empty()) {
set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR, INSTALL_PATH);
- memdelete(d);
get_ok_button()->set_disabled(true);
return "";
}
@@ -188,13 +186,11 @@ private:
if (mode == MODE_IMPORT || mode == MODE_RENAME) {
if (!valid_path.is_empty() && !d->file_exists("project.godot")) {
if (valid_path.ends_with(".zip")) {
- FileAccess *src_f = nullptr;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ zlib_filefunc_def io = zipio_create_io();
unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io);
if (!pkg) {
set_message(TTR("Error opening package file (it's not in ZIP format)."), MESSAGE_ERROR);
- memdelete(d);
get_ok_button()->set_disabled(true);
unzClose(pkg);
return "";
@@ -205,6 +201,9 @@ private:
unz_file_info info;
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
+ if (ret != UNZ_OK) {
+ break;
+ }
if (String::utf8(fname).ends_with("project.godot")) {
break;
@@ -215,7 +214,6 @@ private:
if (ret == UNZ_END_OF_LIST_OF_FILE) {
set_message(TTR("Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."), MESSAGE_ERROR);
- memdelete(d);
get_ok_button()->set_disabled(true);
unzClose(pkg);
return "";
@@ -242,14 +240,12 @@ private:
if (!is_folder_empty) {
set_message(TTR("Please choose an empty folder."), MESSAGE_WARNING, INSTALL_PATH);
- memdelete(d);
get_ok_button()->set_disabled(true);
return "";
}
} else {
set_message(TTR("Please choose a \"project.godot\" or \".zip\" file."), MESSAGE_ERROR);
- memdelete(d);
install_path_container->hide();
get_ok_button()->set_disabled(true);
return "";
@@ -257,7 +253,6 @@ private:
} else if (valid_path.ends_with("zip")) {
set_message(TTR("This directory already contains a Godot project."), MESSAGE_ERROR, INSTALL_PATH);
- memdelete(d);
get_ok_button()->set_disabled(true);
return "";
}
@@ -282,7 +277,6 @@ private:
if (!is_folder_empty) {
set_message(TTR("The selected path is not empty. Choosing an empty folder is highly recommended."), MESSAGE_WARNING);
- memdelete(d);
get_ok_button()->set_disabled(false);
return valid_path;
}
@@ -290,7 +284,6 @@ private:
set_message("");
set_message("", MESSAGE_SUCCESS, INSTALL_PATH);
- memdelete(d);
get_ok_button()->set_disabled(false);
return valid_path;
}
@@ -389,7 +382,7 @@ private:
return;
}
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (d->change_dir(project_path->get_text()) == OK) {
if (!d->dir_exists(project_name_no_edges)) {
if (d->make_dir(project_name_no_edges) == OK) {
@@ -408,8 +401,6 @@ private:
dialog_error->popup_centered();
}
}
-
- memdelete(d);
}
void _text_changed(const String &p_text) {
@@ -508,8 +499,7 @@ private:
zip_path = project_path->get_text();
}
- FileAccess *src_f = nullptr;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ zlib_filefunc_def io = zipio_create_io();
unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
if (!pkg) {
@@ -545,20 +535,20 @@ private:
unz_file_info info;
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
+ if (ret != UNZ_OK) {
+ break;
+ }
String path = String::utf8(fname);
if (path.is_empty() || path == zip_root || !zip_root.is_subsequence_of(path)) {
//
} else if (path.ends_with("/")) { // a dir
-
path = path.substr(0, path.length() - 1);
String rel_path = path.substr(zip_root.length());
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->make_dir(dir.plus_file(rel_path));
- memdelete(da);
-
} else {
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -566,14 +556,13 @@ private:
//read
unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptrw(), data.size());
+ ret = unzReadCurrentFile(pkg, data.ptrw(), data.size());
+ ERR_BREAK_MSG(ret < 0, vformat("An error occurred while attempting to read from file: %s. This file will not be used.", rel_path));
unzCloseCurrentFile(pkg);
- FileAccess *f = FileAccess::open(dir.plus_file(rel_path), FileAccess::WRITE);
-
- if (f) {
+ Ref<FileAccess> f = FileAccess::open(dir.plus_file(rel_path), FileAccess::WRITE);
+ if (f.is_valid()) {
f->store_buffer(data.ptr(), data.size());
- memdelete(f);
} else {
failed_files.push_back(rel_path);
}
@@ -620,9 +609,8 @@ private:
void _remove_created_folder() {
if (!created_folder_path.is_empty()) {
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
d->remove(created_folder_path);
- memdelete(d);
create_dir->set_disabled(false);
created_folder_path = "";
@@ -725,10 +713,9 @@ public:
project_path->set_text(fav_dir);
fdialog->set_current_dir(fav_dir);
} else {
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
project_path->set_text(d->get_current_dir());
fdialog->set_current_dir(d->get_current_dir());
- memdelete(d);
}
String proj = TTR("New Game Project");
project_name->set_text(proj);
@@ -815,7 +802,7 @@ public:
project_path = memnew(LineEdit);
project_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- project_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
+ project_path->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
pphb->add_child(project_path);
install_path_container = memnew(VBoxContainer);
@@ -830,7 +817,7 @@ public:
install_path = memnew(LineEdit);
install_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- install_path->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
+ install_path->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
iphb->add_child(install_path);
// status icon
@@ -1057,6 +1044,8 @@ public:
}
};
+ bool project_opening_initiated;
+
ProjectList();
~ProjectList();
@@ -1130,12 +1119,13 @@ struct ProjectListComparator {
};
ProjectList::ProjectList() {
- _order_option = FilterOption::NAME;
+ _order_option = FilterOption::EDIT_DATE;
_scroll_children = memnew(VBoxContainer);
_scroll_children->set_h_size_flags(Control::SIZE_EXPAND_FILL);
add_child(_scroll_children);
_icon_load_index = 0;
+ project_opening_initiated = false;
}
ProjectList::~ProjectList() {
@@ -1450,7 +1440,7 @@ void ProjectList::create_project_item_control(int p_index) {
}
Label *fpath = memnew(Label(item.path));
- fpath->set_structured_text_bidi_override(Control::STRUCTURED_TEXT_FILE);
+ fpath->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
path_hb->add_child(fpath);
fpath->set_h_size_flags(Control::SIZE_EXPAND_FILL);
fpath->set_modulate(Color(1, 1, 1, 0.5));
@@ -1818,7 +1808,9 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
emit_signal(SNAME(SIGNAL_SELECTION_CHANGED));
- if (!mb->is_ctrl_pressed() && mb->is_double_click()) {
+ // Do not allow opening a project more than once using a single project manager instance.
+ // Opening the same project in several editor instances at once can lead to various issues.
+ if (!mb->is_ctrl_pressed() && mb->is_double_click() && !project_opening_initiated) {
emit_signal(SNAME(SIGNAL_PROJECT_ASK_OPEN));
}
}
@@ -1906,10 +1898,15 @@ void ProjectManager::_notification(int p_what) {
// to search without having to reach for their mouse
search_box->grab_focus();
}
+
+ if (asset_library) {
+ // Removes extra border margins.
+ asset_library->add_theme_style_override("panel", memnew(StyleBoxEmpty));
+ }
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
- set_process_unhandled_key_input(is_visible_in_tree());
+ set_process_shortcut_input(is_visible_in_tree());
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
@@ -1968,7 +1965,7 @@ void ProjectManager::_update_project_buttons() {
erase_missing_btn->set_disabled(!_project_list->is_any_project_missing());
}
-void ProjectManager::unhandled_key_input(const Ref<InputEvent> &p_ev) {
+void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventKey> k = p_ev;
@@ -2140,6 +2137,8 @@ void ProjectManager::_open_selected_projects() {
ERR_FAIL_COND(err);
}
+ _project_list->project_opening_initiated = true;
+
_dim_window();
get_tree()->quit();
}
@@ -2275,7 +2274,7 @@ void ProjectManager::_run_project() {
}
void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error error = da->change_dir(path);
ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path);
da->list_dir_begin();
@@ -2397,19 +2396,18 @@ void ProjectManager::_install_project(const String &p_zip_path, const String &p_
npdialog->show_dialog();
}
-void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) {
+void ProjectManager::_files_dropped(PackedStringArray p_files) {
if (p_files.size() == 1 && p_files[0].ends_with(".zip")) {
const String file = p_files[0].get_file();
_install_project(p_files[0], file.substr(0, file.length() - 4).capitalize());
return;
}
Set<String> folders_set;
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < p_files.size(); i++) {
String file = p_files[i];
folders_set.insert(da->dir_exists(file) ? file : file.get_base_dir());
}
- memdelete(da);
if (folders_set.size() > 0) {
PackedStringArray folders;
for (Set<String>::Element *E = folders_set.front(); E; E = E->next()) {
@@ -2418,7 +2416,7 @@ void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) {
bool confirm = true;
if (folders.size() == 1) {
- DirAccess *dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (dir->change_dir(folders[0]) == OK) {
dir->list_dir_begin();
String file = dir->get_next();
@@ -2430,7 +2428,6 @@ void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) {
}
dir->list_dir_end();
}
- memdelete(dir);
}
if (confirm) {
multi_scan_ask->get_ok_button()->disconnect("pressed", callable_mp(this, &ProjectManager::_scan_multiple_folders));
@@ -2541,7 +2538,7 @@ ProjectManager::ProjectManager() {
}
// TRANSLATORS: This refers to the application where users manage their Godot projects.
- DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager"));
+ DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager", "Application"));
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -2566,7 +2563,6 @@ ProjectManager::ProjectManager() {
tabs = memnew(TabContainer);
center_box->add_child(tabs);
tabs->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
HBoxContainer *projects_hb = memnew(HBoxContainer);
@@ -2608,9 +2604,9 @@ ProjectManager::ProjectManager() {
hb->add_child(filter_option);
Vector<String> sort_filter_titles;
+ sort_filter_titles.push_back(TTR("Last Edited"));
sort_filter_titles.push_back(TTR("Name"));
sort_filter_titles.push_back(TTR("Path"));
- sort_filter_titles.push_back(TTR("Last Edited"));
for (int i = 0; i < sort_filter_titles.size(); i++) {
filter_option->add_item(sort_filter_titles[i]);
@@ -2847,7 +2843,7 @@ ProjectManager::ProjectManager() {
_load_recent_projects();
- DirAccessRef dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM);
+ Ref<DirAccess> dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM);
String default_project_path = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path");
if (!dir_access->dir_exists(default_project_path)) {
@@ -2879,12 +2875,17 @@ ProjectManager::ProjectManager() {
if (scale_factor > 1.0) {
Vector2i window_size = DisplayServer::get_singleton()->window_get_size();
Vector2i screen_size = DisplayServer::get_singleton()->screen_get_size();
+ Vector2i screen_position = DisplayServer::get_singleton()->screen_get_position();
+
window_size *= scale_factor;
- Vector2i window_position;
- window_position.x = (screen_size.x - window_size.x) / 2;
- window_position.y = (screen_size.y - window_size.y) / 2;
+
DisplayServer::get_singleton()->window_set_size(window_size);
- DisplayServer::get_singleton()->window_set_position(window_position);
+ if (screen_size != Vector2i()) {
+ Vector2i window_position;
+ window_position.x = screen_position.x + (screen_size.x - window_size.x) / 2;
+ window_position.y = screen_position.y + (screen_size.y - window_size.y) / 2;
+ DisplayServer::get_singleton()->window_set_position(window_position);
+ }
}
OS::get_singleton()->set_low_processor_usage_mode(true);