From d74a55af9713e9d3e9e1a0fae870cc33078a4729 Mon Sep 17 00:00:00 2001 From: Brandon Scott Date: Mon, 16 Sep 2019 01:33:59 -0500 Subject: [PATCH] FileManager+LibGUI: Fix crash when opening a folder, as well as when trying to open a newly created folder. --- Applications/FileManager/main.cpp | 16 ++++++++++++++++ Libraries/LibGUI/GFileSystemModel.cpp | 22 +++++++++++++++++++--- Libraries/LibGUI/GFileSystemModel.h | 1 + Libraries/LibGUI/GModelSelection.h | 14 ++++++++++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index 14361c69b71276c..0c7845c80c84548 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -104,6 +104,22 @@ int main(int argc, char** argv) if (rc < 0) { GMessageBox::show(String::format("mkdir(\"%s\") failed: %s", new_dir_path.characters(), strerror(errno)), "Error", GMessageBox::Type::Error, GMessageBox::InputType::OK, window); } else { + file_system_model->update(); + + auto current_path = directory_view->path(); + + // not exactly sure why i have to reselect the root node first, but the index() fails if I dont + auto root_index = file_system_model->index(file_system_model->root_path()); + tree_view->selection().set(root_index); + tree_view->scroll_into_view(root_index, Orientation::Vertical); + tree_view->update(); + + // reselect the existing folder in the tree + auto new_index = file_system_model->index(current_path); + tree_view->selection().set(new_index); + tree_view->scroll_into_view(new_index, Orientation::Vertical); + tree_view->update(); + directory_view->refresh(); } } diff --git a/Libraries/LibGUI/GFileSystemModel.cpp b/Libraries/LibGUI/GFileSystemModel.cpp index 2a9c4cf25da4331..8509e3b278cf55e 100644 --- a/Libraries/LibGUI/GFileSystemModel.cpp +++ b/Libraries/LibGUI/GFileSystemModel.cpp @@ -31,6 +31,15 @@ struct GFileSystemModel::Node { ASSERT_NOT_REACHED(); } + void cleanup() + { + for(auto &child: children) { + child->cleanup(); + delete child; + } + children.clear(); + } + void traverse_if_needed(const GFileSystemModel& model) { if (type != Node::Directory || has_traversed) @@ -146,15 +155,22 @@ GFileSystemModel::~GFileSystemModel() void GFileSystemModel::update() { - // FIXME: Support refreshing the model! - if (m_root) - return; + cleanup(); m_root = new Node; m_root->name = m_root_path; m_root->reify_if_needed(*this); } +void GFileSystemModel::cleanup() +{ + if (m_root) { + m_root->cleanup(); + delete m_root; + m_root = nullptr; + } +} + int GFileSystemModel::row_count(const GModelIndex& index) const { if (!index.is_valid()) diff --git a/Libraries/LibGUI/GFileSystemModel.h b/Libraries/LibGUI/GFileSystemModel.h index 80b2f17ddddcc1c..8e4e481ec83f698 100644 --- a/Libraries/LibGUI/GFileSystemModel.h +++ b/Libraries/LibGUI/GFileSystemModel.h @@ -37,6 +37,7 @@ class GFileSystemModel : public GModel { struct Node; Node* m_root { nullptr }; + void cleanup(); GIcon m_open_folder_icon; GIcon m_closed_folder_icon; diff --git a/Libraries/LibGUI/GModelSelection.h b/Libraries/LibGUI/GModelSelection.h index 4c0c011336d3ecc..6b885741a50eebf 100644 --- a/Libraries/LibGUI/GModelSelection.h +++ b/Libraries/LibGUI/GModelSelection.h @@ -33,17 +33,27 @@ class GModelSelection { template void for_each_index(Callback callback) { - for (auto& index : m_indexes) + for (auto& index : indexes()) callback(index); } template void for_each_index(Callback callback) const { - for (auto& index : m_indexes) + for (auto& index : indexes()) callback(index); } + Vector indexes() const + { + Vector selected_indexes; + + for (auto& index : m_indexes) + selected_indexes.append(index); + + return selected_indexes; + } + // FIXME: This doesn't guarantee that what you get is the lowest or "first" index selected.. GModelIndex first() const {