mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:37:43 +00:00
FileManager: Factorize code to handle drag-and-drop
The treeview and the breadcrumbbar used to be on one side, sharing drag-and-drop handling and on the other side the directory view had its one logic. This patch factorizes both versions, in the meantime upgrading the version used by the treeview/breadcrumbbar that was left behind. It now uses the copy dialog :^).
This commit is contained in:
parent
0c4bbf5be3
commit
be28800e0d
4 changed files with 51 additions and 61 deletions
|
@ -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<DeprecatedString> 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
#include "FileUtils.h"
|
||||
#include "FileOperationProgressWidget.h"
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/MimeData.h>
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibGUI/Event.h>
|
||||
#include <LibGUI/MessageBox.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -108,4 +111,39 @@ ErrorOr<void> run_file_operation(FileOperation operation, Vector<DeprecatedStrin
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<bool> 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<DeprecatedString> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,4 +22,5 @@ enum class FileOperation {
|
|||
void delete_paths(Vector<DeprecatedString> const&, bool should_confirm, GUI::Window*);
|
||||
|
||||
ErrorOr<void> run_file_operation(FileOperation, Vector<DeprecatedString> const& sources, DeprecatedString const& destination, GUI::Window*);
|
||||
ErrorOr<bool> handle_drop(GUI::DropEvent const& event, DeprecatedString const& destination, GUI::Window* window);
|
||||
}
|
||||
|
|
|
@ -1301,34 +1301,10 @@ ErrorOr<int> run_in_windowed_mode(DeprecatedString const& initial_location, Depr
|
|||
}
|
||||
};
|
||||
|
||||
auto copy_urls_to_directory = [&](Vector<URL> 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<Error const&>(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<int> 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<GUI::DropEvent&>(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<GUI::DropEvent&>(event).accept();
|
||||
}
|
||||
};
|
||||
|
||||
directory_view->open(initial_location);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue