diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-03-21 16:59:25 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-03-25 12:09:57 +0300 |
commit | 94388d69bb8082945e95f1b7583320cd43d90c69 (patch) | |
tree | 7e4d1162521f017d868a2da144a081118a7d156f /source/blender | |
parent | c1f8b9753acd6e61317dd7076eac5408fc48d7e6 (diff) |
Add copy/paste of any IDs in Outliner.
This adds entries to copy/paste (selected) IDs in the Outliner, as well
as usual ctrl-C/ctrl-V shortcuts.
Note that the clipboard is shared with other IDs copying (currently, the
one for objects in 3DView).
Reviewers: brecht, dfelinto, billreynish, pablovazquez
Differential Revision: https://developer.blender.org/D4568
Diffstat (limited to 'source/blender')
4 files changed, 122 insertions, 0 deletions
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index a96d5ad183f..0cadda235f4 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -40,6 +40,8 @@ #include "BLT_translation.h" #include "BKE_animsys.h" +#include "BKE_appdir.h" +#include "BKE_blender_copybuffer.h" #include "BKE_collection.h" #include "BKE_context.h" #include "BKE_idcode.h" @@ -592,6 +594,104 @@ void id_remap_cb( WM_operator_properties_free(&op_props); } +/* ID copy/Paste ------------------------------------------------------------- */ + +static int outliner_id_copy_tag(SpaceOutliner *soops, ListBase *tree) +{ + TreeElement *te; + TreeStoreElem *tselem; + int num_ids = 0; + + for (te = tree->first; te; te = te->next) { + tselem = TREESTORE(te); + + /* if item is selected and is an ID, tag it as needing to be copied. */ + if (tselem->flag & TSE_SELECTED && ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) { + ID *id = tselem->id; + if (!(id->tag & LIB_TAG_DOIT)) { + BKE_copybuffer_tag_ID(tselem->id); + num_ids++; + } + } + + /* go over sub-tree */ + if (TSELEM_OPEN(tselem, soops)) { + num_ids += outliner_id_copy_tag(soops, &te->subtree); + } + } + + return num_ids; +} + +static int outliner_id_copy_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + SpaceOutliner *soops = CTX_wm_space_outliner(C); + char str[FILE_MAX]; + + BKE_copybuffer_begin(bmain); + + const int num_ids = outliner_id_copy_tag(soops, &soops->tree); + if (num_ids == 0) { + BKE_report(op->reports, RPT_INFO, "No selected data-blocks to copy"); + return OPERATOR_CANCELLED; + } + + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend"); + BKE_copybuffer_save(bmain, str, op->reports); + + BKE_reportf(op->reports, RPT_INFO, "Copied %d selected data-blocks", num_ids); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_id_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Outliner ID Data Copy"; + ot->idname = "OUTLINER_OT_id_copy"; + ot->description = "Selected data-blocks are copied to the clipboard"; + + /* callbacks */ + ot->exec = outliner_id_copy_exec; + ot->poll = ED_operator_outliner_active; + + ot->flag = 0; +} + +static int outliner_id_paste_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + const short flag = FILE_AUTOSELECT | FILE_ACTIVE_COLLECTION; + + BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend"); + + const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, 0); + if (num_pasted == 0) { + BKE_report(op->reports, RPT_INFO, "No data to paste"); + return OPERATOR_CANCELLED; + } + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + BKE_reportf(op->reports, RPT_INFO, "%d data-blocks pasted", num_pasted); + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_id_paste(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Outliner ID Data Paste"; + ot->idname = "OUTLINER_OT_id_paste"; + ot->description = "Data-blocks from the clipboard are pasted"; + + /* callbacks */ + ot->exec = outliner_id_paste_exec; + ot->poll = ED_operator_outliner_active; + + ot->flag = 0; +} + /* Library relocate/reload --------------------------------------------------- */ static int lib_relocate( diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index b93217395d6..57fed22d36b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -297,6 +297,8 @@ void OUTLINER_OT_object_operation(struct wmOperatorType *ot); void OUTLINER_OT_lib_operation(struct wmOperatorType *ot); void OUTLINER_OT_id_operation(struct wmOperatorType *ot); void OUTLINER_OT_id_remap(struct wmOperatorType *ot); +void OUTLINER_OT_id_copy(struct wmOperatorType *ot); +void OUTLINER_OT_id_paste(struct wmOperatorType *ot); void OUTLINER_OT_data_operation(struct wmOperatorType *ot); void OUTLINER_OT_animdata_operation(struct wmOperatorType *ot); void OUTLINER_OT_action_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 5d9437210e2..c14a5eace91 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -63,6 +63,8 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_id_operation); WM_operatortype_append(OUTLINER_OT_id_delete); WM_operatortype_append(OUTLINER_OT_id_remap); + WM_operatortype_append(OUTLINER_OT_id_copy); + WM_operatortype_append(OUTLINER_OT_id_paste); WM_operatortype_append(OUTLINER_OT_data_operation); WM_operatortype_append(OUTLINER_OT_animdata_operation); WM_operatortype_append(OUTLINER_OT_action_set); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 19d79965a6f..400a69cef51 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1152,6 +1152,9 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_DELETE, OUTLINER_IDOP_REMAP, + OUTLINER_IDOP_COPY, + OUTLINER_IDOP_PASTE, + OUTLINER_IDOP_FAKE_ADD, OUTLINER_IDOP_FAKE_CLEAR, OUTLINER_IDOP_RENAME, @@ -1169,6 +1172,10 @@ static const EnumPropertyItem prop_id_op_types[] = { {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""}, {OUTLINER_IDOP_REMAP, "REMAP", 0, "Remap Users", "Make all users of selected data-blocks to use instead current (clicked) one"}, + {0, "", 0, NULL, NULL}, + {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""}, + {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""}, + {0, "", 0, NULL, NULL}, {OUTLINER_IDOP_FAKE_ADD, "ADD_FAKE", 0, "Add Fake User", "Ensure data-block gets saved even if it isn't in use (e.g. for motion and material libraries)"}, {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""}, @@ -1320,6 +1327,17 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) } break; } + case OUTLINER_IDOP_COPY: + { + WM_operator_name_call(C, "OUTLINER_OT_id_copy", WM_OP_INVOKE_DEFAULT, NULL); + break; + } + case OUTLINER_IDOP_PASTE: + { + WM_operator_name_call(C, "OUTLINER_OT_id_paste", WM_OP_INVOKE_DEFAULT, NULL); + ED_undo_push(C, "Paste"); + break; + } case OUTLINER_IDOP_FAKE_ADD: { /* set fake user */ |