Cleanup: Deduplicate operator paths properties reading in io importers

Adds a function that deduplicates operator paths properties reading.

-----

There are other places where this function can be useful, but I'm not sure whether to include `BLI_vector.hh` in RNA_access.hh

Pull Request: https://projects.blender.org/blender/blender/pulls/117644
This commit is contained in:
Guillermo Venegas
2024-02-06 17:12:25 +01:00
committed by Bastien Montagne
parent 1497005054
commit 16129d6a48
7 changed files with 76 additions and 109 deletions

View File

@@ -23,31 +23,10 @@
#include "UI_interface.hh"
#include "io_drop_import_file.hh"
#include "io_utils.hh"
static CLG_LogRef LOG = {"io.drop_import_file"};
/** Returns the list of file paths stored in #WM_OT_drop_import_file operator properties. */
static blender::Vector<std::string> drop_import_file_paths(const wmOperator *op)
{
blender::Vector<std::string> result;
char dir[FILE_MAX], file[FILE_MAX];
RNA_string_get(op->ptr, "directory", dir);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "files");
int files_len = RNA_property_collection_length(op->ptr, prop);
for (int i = 0; i < files_len; i++) {
PointerRNA fileptr;
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file);
char file_path[FILE_MAX];
BLI_path_join(file_path, sizeof(file_path), dir, file);
result.append(file_path);
}
return result;
}
/**
* Return a vector of file handlers that support any file path in `paths` and the call to
* `poll_drop` returns #true. Unlike `bke::file_handlers_poll_file_drop`, it ensures that file
@@ -121,7 +100,7 @@ static PointerRNA file_handler_import_operator_create_ptr(
static int wm_drop_import_file_exec(bContext *C, wmOperator *op)
{
auto paths = drop_import_file_paths(op);
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
if (paths.is_empty()) {
return OPERATOR_CANCELLED;
}
@@ -141,7 +120,7 @@ static int wm_drop_import_file_exec(bContext *C, wmOperator *op)
static int wm_drop_import_file_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
const auto paths = drop_import_file_paths(op);
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
if (paths.is_empty()) {
return OPERATOR_CANCELLED;
}

View File

@@ -100,29 +100,16 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op)
/* Loop all selected files to import them. All SVG imported shared the same import
* parameters, but they are created in separated grease pencil objects. */
PropertyRNA *prop;
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
char *directory = RNA_string_get_alloc(op->ptr, "directory", nullptr, 0, nullptr);
if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
char file_path[FILE_MAX];
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
char *filename = RNA_string_get_alloc(&itemptr, "name", nullptr, 0, nullptr);
BLI_path_join(file_path, sizeof(file_path), directory, filename);
MEM_freeN(filename);
/* Do Import. */
WM_cursor_wait(true);
RNA_string_get(&itemptr, "name", params.filename);
const bool done = gpencil_io_import(file_path, &params);
WM_cursor_wait(false);
if (!done) {
BKE_reportf(op->reports, RPT_WARNING, "Unable to import '%s'", file_path);
}
}
RNA_PROP_END;
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
for (const auto &path : paths) {
/* Do Import. */
WM_cursor_wait(true);
BLI_path_split_file_part(path.c_str(), params.filename, ARRAY_SIZE(params.filename));
const bool done = gpencil_io_import(path.c_str(), &params);
WM_cursor_wait(false);
if (!done) {
BKE_reportf(op->reports, RPT_WARNING, "Unable to import '%s'", path.c_str());
}
MEM_freeN(directory);
}
return OPERATOR_FINISHED;

View File

@@ -390,7 +390,6 @@ void WM_OT_obj_export(wmOperatorType *ot)
static int wm_obj_import_exec(bContext *C, wmOperator *op)
{
OBJImportParams import_params{};
RNA_string_get(op->ptr, "filepath", import_params.filepath);
import_params.global_scale = RNA_float_get(op->ptr, "global_scale");
import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size");
import_params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
@@ -405,32 +404,18 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
import_params.relative_paths = ((U.flag & USER_RELPATHS) != 0);
import_params.clear_selection = true;
int files_len = RNA_collection_length(op->ptr, "files");
if (files_len) {
/* Importing multiple files: loop over them and import one by one. */
PointerRNA fileptr;
PropertyRNA *prop;
char dir_only[FILE_MAX], file_only[FILE_MAX];
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
RNA_string_get(op->ptr, "directory", dir_only);
prop = RNA_struct_find_property(op->ptr, "files");
for (int i = 0; i < files_len; i++) {
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
BLI_path_join(import_params.filepath, sizeof(import_params.filepath), dir_only, file_only);
import_params.clear_selection = (i == 0);
OBJ_import(C, &import_params);
}
}
else if (RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
/* Importing one file. */
RNA_string_get(op->ptr, "filepath", import_params.filepath);
OBJ_import(C, &import_params);
}
else {
if (paths.is_empty()) {
BKE_report(op->reports, RPT_ERROR, "No filepath given");
return OPERATOR_CANCELLED;
}
for (const auto &path : paths) {
STRNCPY(import_params.filepath, path.c_str());
OBJ_import(C, &import_params);
/* Only first import clears selection. */
import_params.clear_selection = false;
};
Scene *scene = CTX_data_scene(C);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);

View File

@@ -251,30 +251,16 @@ static int wm_ply_import_exec(bContext *C, wmOperator *op)
params.import_attributes = RNA_boolean_get(op->ptr, "import_attributes");
params.vertex_colors = ePLYVertexColorMode(RNA_enum_get(op->ptr, "import_colors"));
int files_len = RNA_collection_length(op->ptr, "files");
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
if (files_len) {
PointerRNA fileptr;
PropertyRNA *prop;
char dir_only[FILE_MAX], file_only[FILE_MAX];
RNA_string_get(op->ptr, "directory", dir_only);
prop = RNA_struct_find_property(op->ptr, "files");
for (int i = 0; i < files_len; i++) {
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
BLI_path_join(params.filepath, sizeof(params.filepath), dir_only, file_only);
PLY_import(C, &params, op);
}
}
else if (RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
RNA_string_get(op->ptr, "filepath", params.filepath);
PLY_import(C, &params, op);
}
else {
if (paths.is_empty()) {
BKE_report(op->reports, RPT_ERROR, "No filepath given");
return OPERATOR_CANCELLED;
}
for (const auto &path : paths) {
STRNCPY(params.filepath, path.c_str());
PLY_import(C, &params, op);
};
Scene *scene = CTX_data_scene(C);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);

View File

@@ -189,30 +189,16 @@ static int wm_stl_import_exec(bContext *C, wmOperator *op)
params.global_scale = RNA_float_get(op->ptr, "global_scale");
params.use_mesh_validate = RNA_boolean_get(op->ptr, "use_mesh_validate");
int files_len = RNA_collection_length(op->ptr, "files");
const auto paths = blender::ed::io::paths_from_operator_properties(op->ptr);
if (files_len) {
PointerRNA fileptr;
PropertyRNA *prop;
char dir_only[FILE_MAX], file_only[FILE_MAX];
RNA_string_get(op->ptr, "directory", dir_only);
prop = RNA_struct_find_property(op->ptr, "files");
for (int i = 0; i < files_len; i++) {
RNA_property_collection_lookup_int(op->ptr, prop, i, &fileptr);
RNA_string_get(&fileptr, "name", file_only);
BLI_path_join(params.filepath, sizeof(params.filepath), dir_only, file_only);
STL_import(C, &params);
}
}
else if (RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
RNA_string_get(op->ptr, "filepath", params.filepath);
STL_import(C, &params);
}
else {
if (paths.is_empty()) {
BKE_report(op->reports, RPT_ERROR, "No filepath given");
return OPERATOR_CANCELLED;
}
for (const auto &path : paths) {
STRNCPY(params.filepath, path.c_str());
STL_import(C, &params);
}
Scene *scene = CTX_data_scene(C);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);

View File

@@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_path_util.h"
#include "BKE_context.hh"
#include "DNA_space_types.h"
@@ -9,6 +11,7 @@
#include "ED_fileselect.hh"
#include "RNA_access.hh"
#include "RNA_prototypes.h"
#include "WM_api.hh"
@@ -47,4 +50,35 @@ bool poll_file_object_drop(const bContext *C, blender::bke::FileHandlerType * /*
}
return false;
}
Vector<std::string> paths_from_operator_properties(PointerRNA *ptr)
{
Vector<std::string> paths;
PropertyRNA *directory_prop = RNA_struct_find_property(ptr, "directory");
if (RNA_property_is_set(ptr, directory_prop)) {
char directory[FILE_MAX], name[FILE_MAX];
RNA_string_get(ptr, "directory", directory);
PropertyRNA *files_prop = RNA_struct_find_collection_property_check(
*ptr, "files", &RNA_OperatorFileListElement);
BLI_assert(files_prop);
RNA_PROP_BEGIN (ptr, file_ptr, files_prop) {
RNA_string_get(&file_ptr, "name", name);
char path[FILE_MAX];
BLI_path_join(path, sizeof(path), directory, name);
paths.append_non_duplicates(path);
}
RNA_PROP_END;
}
PropertyRNA *filepath_prop = RNA_struct_find_property(ptr, "filepath");
if (filepath_prop && RNA_property_is_set(ptr, filepath_prop)) {
char filepath[FILE_MAX];
RNA_string_get(ptr, "filepath", filepath);
paths.append_non_duplicates(filepath);
}
return paths;
}
} // namespace blender::ed::io

View File

@@ -6,6 +6,8 @@
#include "WM_types.hh"
#include "BLI_vector.hh"
struct wmOperator;
struct wmOperatorType;
struct wmDrag;
@@ -23,4 +25,12 @@ namespace blender::ed::io {
int filesel_drop_import_invoke(bContext *C, wmOperator *op, const wmEvent *event);
bool poll_file_object_drop(const bContext *C, blender::bke::FileHandlerType *fh);
/**
* Return all paths stored in the pointer.
* Properties in pointer should include a `directory` #PropertySubType::PROP_FILEPATH property and
* a `files` #RNA_OperatorFileListElement collection property.
* If the pointer has a `filepath` property is also returned as fallback.
*/
Vector<std::string> paths_from_operator_properties(PointerRNA *ptr);
} // namespace blender::ed::io