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:
committed by
Bastien Montagne
parent
1497005054
commit
16129d6a48
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, ¶ms);
|
||||
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(), ¶ms);
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ¶ms, op);
|
||||
}
|
||||
}
|
||||
else if (RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
|
||||
RNA_string_get(op->ptr, "filepath", params.filepath);
|
||||
PLY_import(C, ¶ms, 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, ¶ms, op);
|
||||
};
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
||||
|
||||
@@ -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, ¶ms);
|
||||
}
|
||||
}
|
||||
else if (RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
|
||||
RNA_string_get(op->ptr, "filepath", params.filepath);
|
||||
STL_import(C, ¶ms);
|
||||
}
|
||||
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, ¶ms);
|
||||
}
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user