Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Remove Missing of project manager #91266

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 14 additions & 21 deletions editor/project_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@
#include "project_manager.h"

#include "core/config/project_settings.h"
#include "core/io/config_file.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/resource_saver.h"
#include "core/io/stream_peer_tls.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/os/time.h"
Expand All @@ -51,20 +48,17 @@
#include "editor/project_manager/project_list.h"
#include "editor/project_manager/project_tag.h"
#include "editor/project_manager/quick_settings_dialog.h"
#include "editor/themes/editor_icons.h"
#include "editor/project_manager/remove_missing_dialog.h"
#include "editor/themes/editor_scale.h"
#include "editor/themes/editor_theme_manager.h"
#include "main/main.h"
#include "scene/gui/check_box.h"
#include "scene/gui/color_rect.h"
#include "scene/gui/flow_container.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
#include "scene/main/window.h"
#include "scene/theme/theme_db.h"
#include "servers/display_server.h"
Expand Down Expand Up @@ -661,8 +655,7 @@ void ProjectManager::_erase_project() {
}

void ProjectManager::_erase_missing_projects() {
erase_missing_ask->set_text(TTR("Remove all missing projects from the list?\nThe project folders' contents won't be modified."));
erase_missing_ask->popup_centered();
remove_missing_dialog->show_dialog(project_list->get_missing_project_paths());
}

void ProjectManager::_erase_project_confirm() {
Expand All @@ -671,8 +664,8 @@ void ProjectManager::_erase_project_confirm() {
_update_list_placeholder();
}

void ProjectManager::_erase_missing_projects_confirm() {
project_list->erase_missing_projects();
void ProjectManager::_erase_missing_projects_confirm(const Vector<String> &p_paths) {
project_list->erase_missing_projects(p_paths);
_update_project_buttons();
_update_list_placeholder();
}
Expand All @@ -695,7 +688,7 @@ void ProjectManager::_update_project_buttons() {
manage_tags_btn->set_disabled(empty_selection || is_missing_project_selected || selected_projects.size() > 1);
run_btn->set_disabled(empty_selection || is_missing_project_selected);

erase_missing_btn->set_disabled(!project_list->is_any_project_missing());
erase_missing_btn->set_visible(project_list->is_any_project_missing());
}

void ProjectManager::_on_projects_updated() {
Expand Down Expand Up @@ -1231,6 +1224,12 @@ ProjectManager::ProjectManager() {
scan_btn->connect(SceneStringName(pressed), callable_mp(this, &ProjectManager::_scan_projects));
hb->add_child(scan_btn);

erase_missing_btn = memnew(Button);
erase_missing_btn->set_text(TTR("Clean"));
erase_missing_btn->set_tooltip_text(TTR("Remove missing projects."));
erase_missing_btn->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects));
hb->add_child(erase_missing_btn);

loading_label = memnew(Label(TTR("Loading, please wait...")));
loading_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
loading_label->hide();
Expand Down Expand Up @@ -1374,11 +1373,6 @@ ProjectManager::ProjectManager() {
Control *filler = memnew(Control);
filler->set_v_size_flags(Control::SIZE_EXPAND_FILL);
project_list_sidebar->add_child(filler);

erase_missing_btn = memnew(Button);
erase_missing_btn->set_text(TTR("Remove Missing"));
erase_missing_btn->connect(SceneStringName(pressed), callable_mp(this, &ProjectManager::_erase_missing_projects));
project_list_sidebar->add_child(erase_missing_btn);
}
}

Expand Down Expand Up @@ -1444,10 +1438,9 @@ ProjectManager::ProjectManager() {
add_child(scan_dir);
scan_dir->connect("dir_selected", callable_mp(project_list, &ProjectList::find_projects));

erase_missing_ask = memnew(ConfirmationDialog);
erase_missing_ask->set_ok_button_text(TTR("Remove All"));
erase_missing_ask->get_ok_button()->connect(SceneStringName(pressed), callable_mp(this, &ProjectManager::_erase_missing_projects_confirm));
add_child(erase_missing_ask);
remove_missing_dialog = memnew(RemoveMissingDialog);
remove_missing_dialog->connect("remove_missing_projects", callable_mp(this, &ProjectManager::_erase_missing_projects_confirm));
add_child(remove_missing_dialog);

erase_ask = memnew(ConfirmationDialog);
erase_ask->set_ok_button_text(TTR("Remove"));
Expand Down
6 changes: 3 additions & 3 deletions editor/project_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#define PROJECT_MANAGER_H

#include "scene/gui/dialogs.h"
#include "scene/gui/scroll_container.h"

class CheckBox;
class EditorAbout;
Expand All @@ -48,6 +47,7 @@ class PanelContainer;
class ProjectDialog;
class ProjectList;
class QuickSettingsDialog;
class RemoveMissingDialog;
class RichTextLabel;
class TabContainer;
class VBoxContainer;
Expand Down Expand Up @@ -165,7 +165,7 @@ class ProjectManager : public Control {
// Comment out for now until we have a better warning system to
// ensure users delete their project only.
//CheckBox *delete_project_contents = nullptr;
ConfirmationDialog *erase_missing_ask = nullptr;
RemoveMissingDialog *remove_missing_dialog = nullptr;
ConfirmationDialog *multi_open_ask = nullptr;
ConfirmationDialog *multi_run_ask = nullptr;

Expand All @@ -184,7 +184,7 @@ class ProjectManager : public Control {
void _erase_project();
void _erase_missing_projects();
void _erase_project_confirm();
void _erase_missing_projects_confirm();
void _erase_missing_projects_confirm(const Vector<String> &p_paths);
void _update_project_buttons();

void _on_project_created(const String &dir);
Expand Down
19 changes: 12 additions & 7 deletions editor/project_manager/project_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,16 @@ Vector<ProjectList::Item> ProjectList::get_selected_projects() const {
return items;
}

Vector<String> ProjectList::get_missing_project_paths() const {
Vector<String> paths;
for (const Item &project : _projects) {
if (project.missing) {
paths.push_back(project.path);
}
}
return paths;
}

const HashSet<String> &ProjectList::get_selected_project_keys() const {
// Faster if that's all you need
return _selected_project_paths;
Expand Down Expand Up @@ -963,22 +973,17 @@ bool ProjectList::is_any_project_missing() const {
return false;
}

void ProjectList::erase_missing_projects() {
if (_projects.is_empty()) {
return;
}

void ProjectList::erase_missing_projects(const Vector<String> &p_paths) {
int deleted_count = 0;
int remaining_count = 0;

for (int i = 0; i < _projects.size(); ++i) {
const Item &item = _projects[i];

if (item.missing) {
if (item.missing && p_paths.has(item.path)) {
_remove_project(i, true);
--i;
++deleted_count;

} else {
++remaining_count;
}
Expand Down
3 changes: 2 additions & 1 deletion editor/project_manager/project_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,15 @@ class ProjectList : public ScrollContainer {
void select_project(int p_index);
void select_first_visible_project();
Vector<Item> get_selected_projects() const;
Vector<String> get_missing_project_paths() const;
const HashSet<String> &get_selected_project_keys() const;
int get_single_selected_index() const;
void erase_selected_projects(bool p_delete_project_contents);

// Missing projects.

bool is_any_project_missing() const;
void erase_missing_projects();
void erase_missing_projects(const Vector<String> &p_paths);

// Project list sorting and filtering.

Expand Down
98 changes: 98 additions & 0 deletions editor/project_manager/remove_missing_dialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**************************************************************************/
/* remove_missing_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 "remove_missing_dialog.h"

#include "editor/themes/editor_scale.h"
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
#include "scene/gui/tree.h"

void RemoveMissingDialog::_on_item_edited() {
bool has_checked = false;
for (TreeItem *item = tree->get_root()->get_next_visible(); item != nullptr; item = item->get_next_visible()) {
if (item->is_checked(0)) {
has_checked = true;
break;
}
}
get_ok_button()->set_disabled(!has_checked);
}

void RemoveMissingDialog::_bind_methods() {
ADD_SIGNAL(MethodInfo("remove_missing_projects", PropertyInfo(Variant::PACKED_STRING_ARRAY, "paths")));
}

void RemoveMissingDialog::ok_pressed() {
Vector<String> paths;
for (TreeItem *item = tree->get_root()->get_next_visible(); item != nullptr; item = item->get_next_visible()) {
if (item->is_checked(0)) {
paths.push_back(item->get_text(0));
}
}
hide();
emit_signal("remove_missing_projects", paths);
}

void RemoveMissingDialog::show_dialog(const Vector<String> &p_paths) {
tree->clear();

TreeItem *root = tree->create_item();

for (const String &path : p_paths) {
TreeItem *item = tree->create_item(root);
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
item->set_editable(0, true);
item->set_checked(0, true);
item->set_text(0, path);
}

popup_centered_clamped(Size2(480, 260) * EDSCALE);
}

RemoveMissingDialog::RemoveMissingDialog() {
set_title(TTR("Remove Missing"));
set_hide_on_ok(false);

VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);

vb->add_child(memnew(Label(TTR("The following paths will be removed from the project list."))));

tree = memnew(Tree);
tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE);
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tree->set_h_scroll_enabled(false);
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tree->set_hide_root(true);
tree->set_select_mode(Tree::SELECT_ROW);
tree->connect("item_edited", callable_mp(this, &RemoveMissingDialog::_on_item_edited));
vb->add_child(tree);
}
56 changes: 56 additions & 0 deletions editor/project_manager/remove_missing_dialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**************************************************************************/
/* remove_missing_dialog.h */
/**************************************************************************/
/* 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. */
/**************************************************************************/

#ifndef REMOVE_MISSING_DIALOG_H
#define REMOVE_MISSING_DIALOG_H

#include "scene/gui/dialogs.h"

class Tree;

class RemoveMissingDialog : public ConfirmationDialog {
GDCLASS(RemoveMissingDialog, ConfirmationDialog);

Tree *tree;

void _on_item_edited();

protected:
static void _bind_methods();

virtual void ok_pressed() override;

public:
void show_dialog(const Vector<String> &p_paths);

RemoveMissingDialog();
};

#endif // REMOVE_MISSING_DIALOG_H
Loading