diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-07 19:17:24 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-07 22:46:53 +0300 |
commit | 949bc7aa2a73df4a96b284c2f8182ec533878246 (patch) | |
tree | 3c5ccccff12c5b400493d2299bd9817be2e2fd4b | |
parent | 599561de841b6f6f2c0ef6a5a4afa80cf3c51918 (diff) |
Outliner: modernize Purge operator.
That guy was still from the era where only way to remove an ID was to
save & reload the .blend file. Use modern code instead, should also be
much, much more efficient in big production files.
And that’s another nice occasion to add/test new batch ID deletion code, too. ;)
Related to T61276 Make Single User unlinks original object.
-rw-r--r-- | source/blender/editors/space_outliner/outliner_edit.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 274897c0a13..2f765fd0c66 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1856,16 +1856,37 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv "Click here to proceed..."); } +static bool outliner_orphans_purge_tag_cb(Main *UNUSED(bmain), ID *id, void *UNUSED(user_data)) +{ + if (id->us == 0) { + id->tag |= LIB_TAG_DOIT; + } + else { + id->tag &= ~LIB_TAG_DOIT; + } + return true; +} + static int outliner_orphans_purge_exec(bContext *C, wmOperator *UNUSED(op)) { - /* Firstly, ensure that the file has been saved, - * so that the latest changes since the last save - * are retained... - */ - WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL); + Main *bmain = CTX_data_main(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + + /* Tag all IDs having zero users. */ + BKE_main_foreach_id(bmain, false, outliner_orphans_purge_tag_cb, NULL); - /* Now, reload the file to get rid of the orphans... */ - WM_operator_name_call(C, "WM_OT_revert_mainfile", WM_OP_EXEC_DEFAULT, NULL); + BKE_id_multi_tagged_delete(bmain); + + /* XXX: tree management normally happens from draw_outliner(), but when + * you're clicking to fast on Delete object from context menu in + * outliner several mouse events can be handled in one cycle without + * handling notifiers/redraw which leads to deleting the same object twice. + * cleanup tree here to prevent such cases. */ + outliner_cleanup_tree(soops); + + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL); return OPERATOR_FINISHED; } @@ -1874,8 +1895,7 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot) /* identifiers */ ot->idname = "OUTLINER_OT_orphans_purge"; ot->name = "Purge All"; - ot->description = "Clear all orphaned data-blocks without any users from the file " - "(cannot be undone, saves to current .blend file)"; + ot->description = "Clear all orphaned data-blocks without any users from the file."; /* callbacks */ ot->invoke = outliner_orphans_purge_invoke; |