From d441ac2d6f61ef59cf73d337097ef5c98bf7a30e Mon Sep 17 00:00:00 2001 From: Guillermo Venegas Date: Thu, 3 Jul 2025 19:21:59 +0200 Subject: [PATCH] Fix: Incorrects filepaths on drag and drop with recursive option enabled Currently drag and drop expects to selection to be in the same folder, but blender internal file browser allows to select files from different folders when recursion is active. When writing to operator properties the `directory` is taken now from the first file provided, and `files` are now relative to this `directory` instead of just taking the file name. When reading from operator properties filepaths are normalized. I notice this issue while reading about #140942, the issue would require a proper fix too. Pull Request: https://projects.blender.org/blender/blender/pulls/140948 --- .../blender/editors/include/ED_fileselect.hh | 6 ++++++ .../blender/editors/io/io_drop_import_file.cc | 8 +++++--- source/blender/editors/io/io_utils.cc | 5 ++++- source/blender/editors/space_file/filesel.cc | 14 ++++++++++++++ .../windowmanager/intern/wm_dragdrop.cc | 19 ++++++------------- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/include/ED_fileselect.hh b/source/blender/editors/include/ED_fileselect.hh index a2c3351e58a..4cceb1f6c19 100644 --- a/source/blender/editors/include/ED_fileselect.hh +++ b/source/blender/editors/include/ED_fileselect.hh @@ -8,6 +8,10 @@ #pragma once +#include + +#include "BLI_vector.hh" + #include "DNA_uuid_types.h" struct ARegion; @@ -203,6 +207,8 @@ ScrArea *ED_fileselect_handler_area_find_any_with_op(const wmWindow *win); */ void ED_fileselect_ensure_default_filepath(bContext *C, wmOperator *op, const char *extension); +blender::Vector ED_fileselect_selected_files_full_paths(const SpaceFile *sfile); + /* TODO: Maybe we should move this to BLI? * On the other hand, it's using defines from space-file area, so not sure... */ int ED_path_extension_type(const char *path); diff --git a/source/blender/editors/io/io_drop_import_file.cc b/source/blender/editors/io/io_drop_import_file.cc index 093b0488531..a7fb0174472 100644 --- a/source/blender/editors/io/io_drop_import_file.cc +++ b/source/blender/editors/io/io_drop_import_file.cc @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_path_utils.hh" +#include "BLI_string.h" #include "BLT_translation.hh" @@ -60,9 +61,9 @@ static void file_handler_import_operator_write_ptr( } PropertyRNA *directory_prop = RNA_struct_find_property_check(props, "directory", PROP_STRING); + char dir[FILE_MAX]; + BLI_path_split_dir_part(paths[0].c_str(), dir, sizeof(dir)); if (directory_prop) { - char dir[FILE_MAX]; - BLI_path_split_dir_part(paths[0].c_str(), dir, sizeof(dir)); RNA_property_string_set(&props, directory_prop, dir); } @@ -72,7 +73,8 @@ static void file_handler_import_operator_write_ptr( RNA_property_collection_clear(&props, files_prop); for (const auto &index : supported_paths) { char file[FILE_MAX]; - BLI_path_split_file_part(paths[index].c_str(), file, sizeof(file)); + STRNCPY(file, paths[index].c_str()); + BLI_path_rel(file, dir); PointerRNA item_ptr{}; RNA_property_collection_add(&props, files_prop, &item_ptr); diff --git a/source/blender/editors/io/io_utils.cc b/source/blender/editors/io/io_utils.cc index 47b7d8eab04..a18af9e90bb 100644 --- a/source/blender/editors/io/io_utils.cc +++ b/source/blender/editors/io/io_utils.cc @@ -5,6 +5,7 @@ #include #include "BLI_path_utils.hh" +#include "BLI_string.h" #include "BLT_translation.hh" @@ -96,6 +97,7 @@ Vector paths_from_operator_properties(PointerRNA *ptr) RNA_string_get(&file_ptr, "name", name); char path[FILE_MAX]; BLI_path_join(path, sizeof(path), directory, name); + BLI_path_normalize(path); paths.append_non_duplicates(path); } RNA_PROP_END; @@ -121,7 +123,8 @@ void paths_to_operator_properties(PointerRNA *ptr, const Span paths RNA_collection_clear(ptr, "files"); for (const auto &path : paths) { char file[FILE_MAX]; - BLI_path_split_file_part(path.c_str(), file, sizeof(file)); + STRNCPY(file, path.c_str()); + BLI_path_rel(file, dir); PointerRNA itemptr{}; RNA_collection_add(ptr, "files", &itemptr); diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 75c626d1081..390c0f2cc99 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -1502,3 +1502,17 @@ void ED_fileselect_ensure_default_filepath(bContext *C, wmOperator *op, const ch RNA_string_set(op->ptr, "filepath", filepath); } } + +blender::Vector ED_fileselect_selected_files_full_paths(const SpaceFile *sfile) +{ + blender::Vector paths; + char path[FILE_MAX_LIBEXTRA]; + for (const int i : blender::IndexRange(filelist_files_ensure(sfile->files))) { + if (filelist_entry_is_selected(sfile->files, i)) { + const FileDirEntry *entry = filelist_file(sfile->files, i); + filelist_file_get_full_path(sfile->files, entry, path); + paths.append(path); + } + } + return paths; +} diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index 5164d91c677..0d7ed152b84 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -21,7 +21,6 @@ #include "BLT_translation.hh" -#include "BLI_linear_allocator.hh" #include "BLI_listbase.h" #include "BLI_math_color.h" #include "BLI_path_utils.hh" @@ -365,21 +364,15 @@ void WM_event_drag_image(wmDrag *drag, const ImBuf *imb, float scale) void WM_event_drag_path_override_poin_data_with_space_file_paths(const bContext *C, wmDrag *drag) { BLI_assert(drag->type == WM_DRAG_PATH); - if (!CTX_wm_space_file(C)) { + const SpaceFile *sfile = CTX_wm_space_file(C); + if (!sfile) { return; } - char dirpath[FILE_MAX]; - BLI_path_split_dir_part(WM_drag_get_single_path(drag), dirpath, FILE_MAX); - - blender::LinearAllocator<> allocator; + const blender::Vector selected_paths = ED_fileselect_selected_files_full_paths( + sfile); blender::Vector paths; - const blender::Vector files = CTX_data_collection_get(C, "selected_files"); - for (const PointerRNA &file_ptr : files) { - const FileDirEntry *file = static_cast(file_ptr.data); - char filepath[FILE_MAX]; - BLI_path_join(filepath, sizeof(filepath), dirpath, file->name); - - paths.append(allocator.copy_string(filepath).c_str()); + for (const std::string &path : selected_paths) { + paths.append(path.c_str()); } if (paths.is_empty()) { return;