Browse Source

Merge pull request #11031 from nabor/rename-dialog

Added support to rename projects on manager
Hein-Pieter van Braam 8 years ago
parent
commit
bdb07fcf4d
2 changed files with 240 additions and 126 deletions
  1. 237 126
      editor/project_manager.cpp
  2. 3 0
      editor/project_manager.h

+ 237 - 126
editor/project_manager.cpp

@@ -59,11 +59,13 @@ public:
 	enum Mode {
 		MODE_NEW,
 		MODE_IMPORT,
-		MODE_INSTALL
+		MODE_INSTALL,
+		MODE_RENAME
 	};
 
 private:
 	Mode mode;
+	Button *browse;
 	Label *pp, *pn;
 	Label *error;
 	LineEdit *project_path;
@@ -91,20 +93,20 @@ private:
 			return "";
 		}
 
-		if (mode != MODE_IMPORT) {
+		if (mode == MODE_IMPORT || mode == MODE_RENAME) {
 
-			if (d->file_exists("project.godot")) {
+			if (valid_path != "" && !d->file_exists("project.godot")) {
 
-				error->set_text(TTR("Invalid project path, project.godot must not exist."));
+				error->set_text(TTR("Invalid project path, project.godot must exist."));
 				memdelete(d);
 				return "";
 			}
 
 		} else {
 
-			if (valid_path != "" && !d->file_exists("project.godot")) {
+			if (d->file_exists("project.godot")) {
 
-				error->set_text(TTR("Invalid project path, project.godot must exist."));
+				error->set_text(TTR("Invalid project path, project.godot must not exist."));
 				memdelete(d);
 				return "";
 			}
@@ -172,6 +174,17 @@ private:
 
 	void _text_changed(const String &p_text) {
 		_test_path();
+		error->set_text("");
+		if (p_text == "") {
+
+			error->set_text(TTR("Name cannot be empty"));
+			get_ok()->set_disabled(true);
+			return;
+		}
+		get_ok()->set_disabled(false);
+	}
+
+	void _name_changed(const String &p_text) {
 	}
 
 	void ok_pressed() {
@@ -182,138 +195,165 @@ private:
 			return;
 		}
 
-		if (mode == MODE_IMPORT) {
-			// nothing to do
+		if (mode == MODE_RENAME) {
+
+			String dir = _test_path();
+			if (dir == "") {
+				error->set_text(TTR("Invalid project path (changed anything?)."));
+				return;
+			}
+
+			ProjectSettings *current = memnew(ProjectSettings);
+			current->add_singleton(ProjectSettings::Singleton("Current"));
+
+			if (current->setup(dir, "")) {
+				error->set_text(TTR("Couldn't get project.godot in project path."));
+			} else {
+				ProjectSettings::CustomMap edited_settings;
+				edited_settings["application/config/name"] = project_name->get_text();
+
+				if (current->save_custom(dir.plus_file("/project.godot"), edited_settings, Vector<String>(), true)) {
+					error->set_text(TTR("Couldn't edit project.godot in project path."));
+				}
+			}
+
+			hide();
+			emit_signal("project_renamed");
 		} else {
-			if (mode == MODE_NEW) {
 
-				ProjectSettings::CustomMap initial_settings;
-				initial_settings["application/config/name"] = project_name->get_text();
-				initial_settings["application/config/icon"] = "res://icon.png";
-				initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
+			if (mode == MODE_IMPORT) {
+				// nothing to do
+			} else {
+				if (mode == MODE_NEW) {
 
-				if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
-					error->set_text(TTR("Couldn't create project.godot in project path."));
-				} else {
-					ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+					ProjectSettings::CustomMap initial_settings;
+					initial_settings["application/config/name"] = project_name->get_text();
+					initial_settings["application/config/icon"] = "res://icon.png";
+					initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
 
-					FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
-					if (!f) {
+					if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
 						error->set_text(TTR("Couldn't create project.godot in project path."));
 					} else {
-						f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
-						f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
-						f->store_line("[resource]");
-						f->store_line("background_mode = 2");
-						f->store_line("background_sky = SubResource( 1 )");
-						memdelete(f);
+						ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+
+						FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
+						if (!f) {
+							error->set_text(TTR("Couldn't create project.godot in project path."));
+						} else {
+							f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
+							f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
+							f->store_line("[resource]");
+							f->store_line("background_mode = 2");
+							f->store_line("background_sky = SubResource( 1 )");
+							memdelete(f);
+						}
 					}
-				}
 
-			} else if (mode == MODE_INSTALL) {
+				} else if (mode == MODE_INSTALL) {
 
-				FileAccess *src_f = NULL;
-				zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+					FileAccess *src_f = NULL;
+					zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
 
-				unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
-				if (!pkg) {
+					unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
+					if (!pkg) {
 
-					dialog_error->set_text(TTR("Error opening package file, not in zip format."));
-					return;
-				}
+						dialog_error->set_text(TTR("Error opening package file, not in zip format."));
+						return;
+					}
 
-				int ret = unzGoToFirstFile(pkg);
+					int ret = unzGoToFirstFile(pkg);
 
-				Vector<String> failed_files;
+					Vector<String> failed_files;
 
-				int idx = 0;
-				while (ret == UNZ_OK) {
+					int idx = 0;
+					while (ret == UNZ_OK) {
 
-					//get filename
-					unz_file_info info;
-					char fname[16384];
-					ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
+						//get filename
+						unz_file_info info;
+						char fname[16384];
+						ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
 
-					String path = fname;
+						String path = fname;
 
-					int depth = 1; //stuff from github comes with tag
-					bool skip = false;
-					while (depth > 0) {
-						int pp = path.find("/");
-						if (pp == -1) {
-							skip = true;
-							break;
+						int depth = 1; //stuff from github comes with tag
+						bool skip = false;
+						while (depth > 0) {
+							int pp = path.find("/");
+							if (pp == -1) {
+								skip = true;
+								break;
+							}
+							path = path.substr(pp + 1, path.length());
+							depth--;
 						}
-						path = path.substr(pp + 1, path.length());
-						depth--;
-					}
 
-					if (skip || path == String()) {
-						//
-					} else if (path.ends_with("/")) { // a dir
+						if (skip || path == String()) {
+							//
+						} else if (path.ends_with("/")) { // a dir
 
-						path = path.substr(0, path.length() - 1);
+							path = path.substr(0, path.length() - 1);
 
-						DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
-						da->make_dir(dir.plus_file(path));
-						memdelete(da);
+							DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+							da->make_dir(dir.plus_file(path));
+							memdelete(da);
 
-					} else {
+						} else {
 
-						Vector<uint8_t> data;
-						data.resize(info.uncompressed_size);
+							Vector<uint8_t> data;
+							data.resize(info.uncompressed_size);
 
-						//read
-						unzOpenCurrentFile(pkg);
-						unzReadCurrentFile(pkg, data.ptr(), data.size());
-						unzCloseCurrentFile(pkg);
+							//read
+							unzOpenCurrentFile(pkg);
+							unzReadCurrentFile(pkg, data.ptr(), data.size());
+							unzCloseCurrentFile(pkg);
 
-						FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
+							FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
 
-						if (f) {
-							f->store_buffer(data.ptr(), data.size());
-							memdelete(f);
-						} else {
-							failed_files.push_back(path);
+							if (f) {
+								f->store_buffer(data.ptr(), data.size());
+								memdelete(f);
+							} else {
+								failed_files.push_back(path);
+							}
 						}
-					}
 
-					idx++;
-					ret = unzGoToNextFile(pkg);
-				}
+						idx++;
+						ret = unzGoToNextFile(pkg);
+					}
 
-				unzClose(pkg);
+					unzClose(pkg);
 
-				if (failed_files.size()) {
-					String msg = TTR("The following files failed extraction from package:") + "\n\n";
-					for (int i = 0; i < failed_files.size(); i++) {
+					if (failed_files.size()) {
+						String msg = TTR("The following files failed extraction from package:") + "\n\n";
+						for (int i = 0; i < failed_files.size(); i++) {
 
-						if (i > 15) {
-							msg += "\nAnd " + itos(failed_files.size() - i) + " more files.";
-							break;
+							if (i > 15) {
+								msg += "\nAnd " + itos(failed_files.size() - i) + " more files.";
+								break;
+							}
+							msg += failed_files[i] + "\n";
 						}
-						msg += failed_files[i] + "\n";
-					}
 
-					dialog_error->set_text(msg);
-					dialog_error->popup_centered_minsize();
+						dialog_error->set_text(msg);
+						dialog_error->popup_centered_minsize();
 
-				} else {
-					dialog_error->set_text(TTR("Package Installed Successfully!"));
-					dialog_error->popup_centered_minsize();
+					} else {
+						dialog_error->set_text(TTR("Package Installed Successfully!"));
+						dialog_error->popup_centered_minsize();
+					}
 				}
 			}
-		}
 
-		dir = dir.replace("\\", "/");
-		if (dir.ends_with("/"))
-			dir = dir.substr(0, dir.length() - 1);
-		String proj = dir.replace("/", "::");
-		EditorSettings::get_singleton()->set("projects/" + proj, dir);
-		EditorSettings::get_singleton()->save();
+			dir = dir.replace("\\", "/");
+			if (dir.ends_with("/"))
+				dir = dir.substr(0, dir.length() - 1);
+			String proj = dir.replace("/", "::");
+			EditorSettings::get_singleton()->set("projects/" + proj, dir);
+			EditorSettings::get_singleton()->save();
 
-		hide();
-		emit_signal("project_created", dir);
+			hide();
+			emit_signal("project_created", dir);
+		}
 	}
 
 protected:
@@ -325,6 +365,7 @@ protected:
 		ClassDB::bind_method("_path_selected", &NewProjectDialog::_path_selected);
 		ClassDB::bind_method("_file_selected", &NewProjectDialog::_file_selected);
 		ADD_SIGNAL(MethodInfo("project_created"));
+		ADD_SIGNAL(MethodInfo("project_renamed"));
 	}
 
 public:
@@ -340,44 +381,85 @@ public:
 		mode = p_mode;
 	}
 
-	void show_dialog() {
-
-		project_path->clear();
-		project_name->clear();
+	void set_project_path(const String &p_path) {
+		project_path->set_text(p_path);
+	}
 
-		if (mode == MODE_IMPORT) {
-			set_title(TTR("Import Existing Project"));
-			get_ok()->set_text(TTR("Import"));
-			pp->set_text(TTR("Project Path (Must Exist):"));
-			pn->set_text(TTR("Project Name:"));
-			pn->hide();
-			project_name->hide();
+	void show_dialog() {
 
-			popup_centered(Size2(500, 125) * EDSCALE);
+		if (mode == MODE_RENAME) {
 
-		} else if (mode == MODE_NEW) {
+			project_path->set_editable(false);
+			browse->set_disabled(true);
 
-			set_title(TTR("Create New Project"));
-			get_ok()->set_text(TTR("Create"));
+			set_title(TTR("Rename Project"));
+			get_ok()->set_text(TTR("Rename"));
 			pp->set_text(TTR("Project Path:"));
 			pn->set_text(TTR("Project Name:"));
 			pn->show();
 			project_name->show();
 
-			popup_centered(Size2(500, 145) * EDSCALE);
-		} else if (mode == MODE_INSTALL) {
+			String dir = _test_path();
+			if (dir == "") {
+				error->set_text(TTR("Invalid project path (changed anything?)."));
+				return;
+			}
+			ProjectSettings *current = memnew(ProjectSettings);
+			current->add_singleton(ProjectSettings::Singleton("Current"));
 
-			set_title(TTR("Install Project:") + " " + zip_title);
-			get_ok()->set_text(TTR("Install"));
-			pp->set_text(TTR("Project Path:"));
-			pn->hide();
-			project_name->hide();
+			if (current->setup(dir, "")) {
+				error->set_text(TTR("Couldn't get project.godot in project path."));
+			} else {
+				if (current->has("application/config/name")) {
+					String appname = current->get("application/config/name");
+					project_name->set_text(appname);
+				}
+			}
 
 			popup_centered(Size2(500, 125) * EDSCALE);
-		}
-		project_path->grab_focus();
+			project_name->grab_focus();
 
-		_test_path();
+		} else {
+
+			project_path->clear();
+			project_name->clear();
+			project_path->set_editable(true);
+			browse->set_disabled(false);
+
+			if (mode == MODE_IMPORT) {
+				set_title(TTR("Import Existing Project"));
+				get_ok()->set_text(TTR("Import"));
+				pp->set_text(TTR("Project Path (Must Exist):"));
+				pn->set_text(TTR("Project Name:"));
+				pn->hide();
+				project_name->hide();
+
+				popup_centered(Size2(500, 125) * EDSCALE);
+
+			} else if (mode == MODE_NEW) {
+
+				set_title(TTR("Create New Project"));
+				get_ok()->set_text(TTR("Create"));
+				pp->set_text(TTR("Project Path:"));
+				pn->set_text(TTR("Project Name:"));
+				pn->show();
+				project_name->show();
+
+				popup_centered(Size2(500, 145) * EDSCALE);
+			} else if (mode == MODE_INSTALL) {
+
+				set_title(TTR("Install Project:") + " " + zip_title);
+				get_ok()->set_text(TTR("Install"));
+				pp->set_text(TTR("Project Path:"));
+				pn->hide();
+				project_name->hide();
+
+				popup_centered(Size2(500, 125) * EDSCALE);
+			}
+			project_path->grab_focus();
+
+			_test_path();
+		}
 	}
 
 	NewProjectDialog() {
@@ -399,7 +481,7 @@ public:
 		pphb->add_child(project_path);
 		project_path->set_h_size_flags(SIZE_EXPAND_FILL);
 
-		Button *browse = memnew(Button);
+		browse = memnew(Button);
 		pphb->add_child(browse);
 		browse->set_text(TTR("Browse"));
 		browse->connect("pressed", this, "_browse_path");
@@ -495,6 +577,7 @@ void ProjectManager::_update_project_buttons() {
 
 	erase_btn->set_disabled(selected_list.size() < 1);
 	open_btn->set_disabled(selected_list.size() < 1);
+	rename_btn->set_disabled(selected_list.size() < 1);
 }
 
 void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
@@ -889,6 +972,10 @@ void ProjectManager::_load_recent_projects() {
 	tabs->set_current_tab(0);
 }
 
+void ProjectManager::_on_project_renamed() {
+	_load_recent_projects();
+}
+
 void ProjectManager::_on_project_created(const String &dir) {
 	bool has_already = false;
 	for (int i = 0; i < scroll_childs->get_child_count(); i++) {
@@ -1091,6 +1178,21 @@ void ProjectManager::_import_project() {
 	npdialog->show_dialog();
 }
 
+void ProjectManager::_rename_project() {
+
+	if (selected_list.size() == 0) {
+		return;
+	}
+
+	for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
+		const String &selected = E->key();
+		String path = EditorSettings::get_singleton()->get("projects/" + selected);
+		npdialog->set_project_path(path);
+		npdialog->set_mode(NewProjectDialog::MODE_RENAME);
+		npdialog->show_dialog();
+	}
+}
+
 void ProjectManager::_erase_project_confirm() {
 
 	if (selected_list.size() == 0) {
@@ -1185,10 +1287,12 @@ void ProjectManager::_bind_methods() {
 	ClassDB::bind_method("_scan_begin", &ProjectManager::_scan_begin);
 	ClassDB::bind_method("_import_project", &ProjectManager::_import_project);
 	ClassDB::bind_method("_new_project", &ProjectManager::_new_project);
+	ClassDB::bind_method("_rename_project", &ProjectManager::_rename_project);
 	ClassDB::bind_method("_erase_project", &ProjectManager::_erase_project);
 	ClassDB::bind_method("_erase_project_confirm", &ProjectManager::_erase_project_confirm);
 	ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
 	ClassDB::bind_method("_load_recent_projects", &ProjectManager::_load_recent_projects);
+	ClassDB::bind_method("_on_project_renamed", &ProjectManager::_on_project_renamed);
 	ClassDB::bind_method("_on_project_created", &ProjectManager::_on_project_created);
 	ClassDB::bind_method("_update_scroll_pos", &ProjectManager::_update_scroll_pos);
 	ClassDB::bind_method("_panel_draw", &ProjectManager::_panel_draw);
@@ -1349,6 +1453,12 @@ ProjectManager::ProjectManager() {
 	tree_vb->add_child(import);
 	import->connect("pressed", this, "_import_project");
 
+	Button *rename = memnew(Button);
+	rename->set_text(TTR("Rename"));
+	tree_vb->add_child(rename);
+	rename->connect("pressed", this, "_rename_project");
+	rename_btn = rename;
+
 	Button *erase = memnew(Button);
 	erase->set_text(TTR("Remove"));
 	tree_vb->add_child(erase);
@@ -1404,6 +1514,7 @@ ProjectManager::ProjectManager() {
 	npdialog = memnew(NewProjectDialog);
 	gui_base->add_child(npdialog);
 
+	npdialog->connect("project_renamed", this, "_on_project_renamed");
 	npdialog->connect("project_created", this, "_on_project_created");
 	_load_recent_projects();
 

+ 3 - 0
editor/project_manager.h

@@ -45,6 +45,7 @@ class ProjectManager : public Control {
 
 	Button *erase_btn;
 	Button *open_btn;
+	Button *rename_btn;
 	Button *run_btn;
 
 	FileDialog *scan_dir;
@@ -79,6 +80,7 @@ class ProjectManager : public Control {
 	void _open_project_confirm();
 	void _import_project();
 	void _new_project();
+	void _rename_project();
 	void _erase_project();
 	void _erase_project_confirm();
 	void _update_project_buttons();
@@ -87,6 +89,7 @@ class ProjectManager : public Control {
 
 	void _load_recent_projects();
 	void _on_project_created(const String &dir);
+	void _on_project_renamed();
 	void _update_scroll_pos(const String &dir);
 	void _scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects);