diff --git a/Userland/Applications/FileManager/DirectoryView.cpp b/Userland/Applications/FileManager/DirectoryView.cpp index d7403bdff7..0cd9e3a286 100644 --- a/Userland/Applications/FileManager/DirectoryView.cpp +++ b/Userland/Applications/FileManager/DirectoryView.cpp @@ -659,35 +659,11 @@ void DirectoryView::setup_actions() void DirectoryView::handle_drop(GUI::ModelIndex const& index, GUI::DropEvent const& event) { - if (!event.mime_data().has_urls()) - return; - auto urls = event.mime_data().urls(); - if (urls.is_empty()) { - dbgln("No files to drop"); - return; - } + auto const& target_node = node(index); - auto& target_node = node(index); - if (!target_node.is_directory()) - return; + bool const has_accepted_drop = ::FileManager::handle_drop(event, target_node.full_path(), window()).release_value_but_fixme_should_propagate_errors(); - bool had_accepted_drop = false; - Vector paths_to_copy; - for (auto& url_to_copy : urls) { - if (!url_to_copy.is_valid() || url_to_copy.path() == target_node.full_path()) - continue; - auto new_path = DeprecatedString::formatted("{}/{}", target_node.full_path(), LexicalPath::basename(url_to_copy.path())); - if (url_to_copy.path() == new_path) - continue; - - paths_to_copy.append(url_to_copy.path()); - had_accepted_drop = true; - } - - if (!paths_to_copy.is_empty()) - MUST(run_file_operation(FileOperation::Copy, paths_to_copy, target_node.full_path(), window())); - - if (had_accepted_drop && on_accepted_drop) + if (has_accepted_drop && on_accepted_drop) on_accepted_drop(); } diff --git a/Userland/Applications/FileManager/FileUtils.cpp b/Userland/Applications/FileManager/FileUtils.cpp index 468994a515..d9daae3f71 100644 --- a/Userland/Applications/FileManager/FileUtils.cpp +++ b/Userland/Applications/FileManager/FileUtils.cpp @@ -8,8 +8,11 @@ #include "FileUtils.h" #include "FileOperationProgressWidget.h" #include +#include +#include #include #include +#include #include #include @@ -108,4 +111,39 @@ ErrorOr run_file_operation(FileOperation operation, Vector handle_drop(GUI::DropEvent const& event, DeprecatedString const& destination, GUI::Window* window) +{ + bool has_accepted_drop = false; + + if (!event.mime_data().has_urls()) + return has_accepted_drop; + auto const urls = event.mime_data().urls(); + if (urls.is_empty()) { + dbgln("No files to drop"); + return has_accepted_drop; + } + + auto const target = LexicalPath::canonicalized_path(destination); + + if (!Core::File::is_directory(target)) + return has_accepted_drop; + + Vector paths_to_copy; + for (auto& url_to_copy : urls) { + if (!url_to_copy.is_valid() || url_to_copy.path() == target) + continue; + auto new_path = DeprecatedString::formatted("{}/{}", target, LexicalPath::basename(url_to_copy.path())); + if (url_to_copy.path() == new_path) + continue; + + paths_to_copy.append(url_to_copy.path()); + has_accepted_drop = true; + } + + if (!paths_to_copy.is_empty()) + TRY(run_file_operation(FileOperation::Copy, paths_to_copy, target, window)); + + return has_accepted_drop; +} + } diff --git a/Userland/Applications/FileManager/FileUtils.h b/Userland/Applications/FileManager/FileUtils.h index 5f856525d5..b64b413370 100644 --- a/Userland/Applications/FileManager/FileUtils.h +++ b/Userland/Applications/FileManager/FileUtils.h @@ -22,4 +22,5 @@ enum class FileOperation { void delete_paths(Vector const&, bool should_confirm, GUI::Window*); ErrorOr run_file_operation(FileOperation, Vector const& sources, DeprecatedString const& destination, GUI::Window*); +ErrorOr handle_drop(GUI::DropEvent const& event, DeprecatedString const& destination, GUI::Window* window); } diff --git a/Userland/Applications/FileManager/main.cpp b/Userland/Applications/FileManager/main.cpp index 6f61c64588..c5840a8e41 100644 --- a/Userland/Applications/FileManager/main.cpp +++ b/Userland/Applications/FileManager/main.cpp @@ -1301,34 +1301,10 @@ ErrorOr run_in_windowed_mode(DeprecatedString const& initial_location, Depr } }; - auto copy_urls_to_directory = [&](Vector const& urls, DeprecatedString const& directory) { - if (urls.is_empty()) { - dbgln("No files to copy"); - return; - } - bool had_accepted_copy = false; - for (auto& url_to_copy : urls) { - if (!url_to_copy.is_valid() || url_to_copy.path() == directory) - continue; - auto new_path = DeprecatedString::formatted("{}/{}", directory, LexicalPath::basename(url_to_copy.path())); - if (url_to_copy.path() == new_path) - continue; - - if (auto result = Core::File::copy_file_or_directory(url_to_copy.path(), new_path); result.is_error()) { - auto error_message = DeprecatedString::formatted("Could not copy {} into {}:\n {}", url_to_copy.to_deprecated_string(), new_path, static_cast(result.error())); - GUI::MessageBox::show(window, error_message, "File Manager"sv, GUI::MessageBox::Type::Error); - } else { - had_accepted_copy = true; - } - } - if (had_accepted_copy) - refresh_tree_view(); - }; - breadcrumbbar.on_segment_drop = [&](size_t segment_index, GUI::DropEvent const& event) { - if (!event.mime_data().has_urls()) - return; - copy_urls_to_directory(event.mime_data().urls(), breadcrumbbar.segment_data(segment_index)); + bool const has_accepted_drop = handle_drop(event, breadcrumbbar.segment_data(segment_index), window).release_value_but_fixme_should_propagate_errors(); + if (has_accepted_drop) + refresh_tree_view(); }; breadcrumbbar.on_segment_drag_enter = [&](size_t, GUI::DragEvent& event) { @@ -1341,13 +1317,12 @@ ErrorOr run_in_windowed_mode(DeprecatedString const& initial_location, Depr }; tree_view.on_drop = [&](GUI::ModelIndex const& index, GUI::DropEvent const& event) { - if (!event.mime_data().has_urls()) - return; - auto& target_node = directories_model->node(index); - if (!target_node.is_directory()) - return; - copy_urls_to_directory(event.mime_data().urls(), target_node.full_path()); - const_cast(event).accept(); + auto const& target_node = directories_model->node(index); + bool const has_accepted_drop = handle_drop(event, target_node.full_path(), window).release_value_but_fixme_should_propagate_errors(); + if (has_accepted_drop) { + refresh_tree_view(); + const_cast(event).accept(); + } }; directory_view->open(initial_location);