Copy/Paste: refactor to be able to paste any kind of IDs, by type.

This commit does not add anything new from user perspective, but make it
possible to paste any kind of IDs, not only objects/collections.

Will be used by new copy/paste in the outliner in next commit.
This commit is contained in:
Bastien Montagne 2019-03-25 09:55:36 +01:00
parent 6d8a945f06
commit c1f8b9753a
6 changed files with 32 additions and 22 deletions

View File

@ -33,8 +33,10 @@ struct bContext;
void BKE_copybuffer_begin(struct Main *bmain_src);
void BKE_copybuffer_tag_ID(struct ID *id);
bool BKE_copybuffer_save(struct Main *bmain_src, const char *filename, struct ReportList *reports);
bool BKE_copybuffer_read(struct Main *bmain_dst, const char *libname, struct ReportList *reports);
bool BKE_copybuffer_paste(struct bContext *C, const char *libname, const short flag, struct ReportList *reports);
bool BKE_copybuffer_read(
struct Main *bmain_dst, const char *libname, struct ReportList *reports, const unsigned int id_types_mask);
int BKE_copybuffer_paste(
struct bContext *C, const char *libname, const short flag, struct ReportList *reports, const unsigned int id_types_mask);
#ifdef __cplusplus
}

View File

@ -82,7 +82,7 @@ bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *repo
return retval;
}
bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports)
bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports, const unsigned int id_types_mask)
{
BlendHandle *bh = BLO_blendhandle_from_file(libname, reports);
if (bh == NULL) {
@ -91,7 +91,7 @@ bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *repor
}
/* Here appending/linking starts. */
Main *mainl = BLO_library_link_begin(bmain_dst, &bh, libname);
BLO_library_link_copypaste(mainl, bh);
BLO_library_link_copypaste(mainl, bh, id_types_mask);
BLO_library_link_end(mainl, &bh, 0, NULL, NULL, NULL, NULL);
/* Mark all library linked objects to be updated. */
BKE_main_lib_objects_recalc_all(bmain_dst);
@ -108,9 +108,10 @@ bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *repor
}
/**
* \return Success.
* \return Number of IDs directly pasted from the buffer (does not includes indirectly pulled out ones).
*/
bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, ReportList *reports)
int BKE_copybuffer_paste(
bContext *C, const char *libname, const short flag, ReportList *reports, const unsigned int id_types_mask)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@ -124,7 +125,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
if (bh == NULL) {
/* error reports will have been made by BLO_blendhandle_from_file() */
return false;
return 0;
}
BKE_view_layer_base_deselect_all(view_layer);
@ -138,7 +139,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
/* here appending/linking starts */
mainl = BLO_library_link_begin(bmain, &bh, libname);
BLO_library_link_copypaste(mainl, bh);
const int num_pasted = BLO_library_link_copypaste(mainl, bh, id_types_mask);
BLO_library_link_end(mainl, &bh, flag, bmain, scene, view_layer, v3d);
@ -164,7 +165,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
BLO_blendhandle_close(bh);
/* remove library... */
return true;
return num_pasted;
}
/** \} */

View File

@ -138,7 +138,7 @@ void BLO_library_link_end(
struct Main *mainl, BlendHandle **bh, int flag,
struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, const struct View3D *v3d);
void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh);
int BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh, const unsigned int id_types_mask);
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);

View File

@ -11019,20 +11019,24 @@ static ID *link_named_part(
/**
* Simple reader for copy/paste buffers.
*/
void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const unsigned int id_types_mask)
{
FileData *fd = (FileData *)(bh);
BHead *bhead;
int num_directly_linked = 0;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
ID *id = NULL;
if (bhead->code == ENDB)
break;
if (ELEM(bhead->code, ID_OB, ID_GR)) {
read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, &id);
}
if (BKE_idcode_is_valid(bhead->code) && BKE_idcode_is_linkable(bhead->code) &&
(id_types_mask == 0 || (BKE_idcode_to_idfilter((short)bhead->code) & id_types_mask) != 0))
{
read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, &id);
num_directly_linked++;
}
if (id) {
/* sort by name in list */
@ -11049,6 +11053,8 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
}
}
}
return num_directly_linked;
}
static ID *link_named_part_ex(

View File

@ -530,7 +530,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
char str[FILE_MAX];
Main *tmp_bmain = BKE_main_new();
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer_pose.blend");
if (!BKE_copybuffer_read(tmp_bmain, str, op->reports)) {
if (!BKE_copybuffer_read(tmp_bmain, str, op->reports, FILTER_ID_OB)) {
BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;

View File

@ -107,17 +107,18 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
flag |= FILE_ACTIVE_COLLECTION;
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
if (BKE_copybuffer_paste(C, str, flag, op->reports)) {
WM_event_add_notifier(C, NC_WINDOW, NULL);
BKE_report(op->reports, RPT_INFO, "Objects pasted from buffer");
return OPERATOR_FINISHED;
const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, FILTER_ID_OB);
if (num_pasted == 0) {
BKE_report(op->reports, RPT_INFO, "No buffer to paste from");
return OPERATOR_CANCELLED;
}
BKE_report(op->reports, RPT_INFO, "No buffer to paste from");
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_CANCELLED;
BKE_reportf(op->reports, RPT_INFO, "%d objects pasted from buffer", num_pasted);
return OPERATOR_FINISHED;
}
static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)