Revert #106653: Cleanup Dialog to Manage Orphaned Data #117241
|
@ -237,8 +237,35 @@ class TOPBAR_MT_file_cleanup(Menu):
|
|||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.operator("outliner.orphans_cleanup")
|
||||
layout.operator("outliner.orphans_manage")
|
||||
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = True
|
||||
|
||||
layout.separator()
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
|
||||
props.do_local_ids = False
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
|
||||
props.do_local_ids = False
|
||||
props.do_linked_ids = True
|
||||
props.do_recursive = True
|
||||
|
||||
layout.separator()
|
||||
props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = False
|
||||
props.do_recursive = False
|
||||
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
|
||||
props.do_local_ids = True
|
||||
props.do_linked_ids = False
|
||||
props.do_recursive = True
|
||||
|
||||
|
||||
class TOPBAR_MT_file(Menu):
|
||||
|
|
|
@ -12,7 +12,6 @@ set(INC
|
|||
../../makesrna
|
||||
../../sequencer
|
||||
../../windowmanager
|
||||
../../../../extern/fmtlib/include
|
||||
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
|
@ -138,7 +137,6 @@ set(LIB
|
|||
bf_editor_undo
|
||||
PRIVATE bf::intern::clog
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
extern_fmtlib
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
#include "tree/tree_element_rna.hh"
|
||||
#include "tree/tree_iterator.hh"
|
||||
|
||||
#include "wm_window.hh"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
using namespace blender::ed::outliner;
|
||||
|
||||
namespace blender::ed::outliner {
|
||||
|
@ -2144,7 +2140,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
|
|||
RNA_int_set(op->ptr, "num_deleted", num_tagged[INDEX_ID_NULL]);
|
||||
|
||||
if (num_tagged[INDEX_ID_NULL] == 0) {
|
||||
BKE_report(op->reports, RPT_INFO, "No unused data-blocks to purge");
|
||||
BKE_report(op->reports, RPT_INFO, "No orphaned data-blocks to purge");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
@ -2192,7 +2188,7 @@ static int outliner_orphans_purge_exec(bContext *C, wmOperator *op)
|
|||
bmain, LIB_TAG_DOIT, do_local_ids, do_linked_ids, do_recursive_cleanup, num_tagged);
|
||||
|
||||
if (num_tagged[INDEX_ID_NULL] == 0) {
|
||||
BKE_report(op->reports, RPT_INFO, "No unused data-blocks to purge");
|
||||
BKE_report(op->reports, RPT_INFO, "No orphaned data-blocks to purge");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
@ -2223,7 +2219,7 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
|||
/* identifiers */
|
||||
ot->idname = "OUTLINER_OT_orphans_purge";
|
||||
ot->name = "Purge All";
|
||||
ot->description = "Remove all unused data-blocks without any users from the file";
|
||||
ot->description = "Clear all orphaned data-blocks without any users from the file";
|
||||
|
||||
/* callbacks */
|
||||
ot->invoke = outliner_orphans_purge_invoke;
|
||||
|
@ -2252,267 +2248,10 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
|||
"do_recursive",
|
||||
false,
|
||||
"Recursive Delete",
|
||||
"Recursively check for indirectly unused data-blocks, ensuring that no unused "
|
||||
"Recursively check for indirectly unused data-blocks, ensuring that no orphaned "
|
||||
"data-blocks remain after execution");
|
||||
}
|
||||
|
||||
static void wm_block_orphans_cancel(bContext *C, void *arg_block, void * /*arg_data*/)
|
||||
{
|
||||
UI_popup_block_close(C, CTX_wm_window(C), (uiBlock *)arg_block);
|
||||
}
|
||||
|
||||
static void wm_block_orphans_cancel_button(uiBlock *block)
|
||||
{
|
||||
uiBut *but = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, 0, IFACE_("Cancel"), 0, 0, 0, UI_UNIT_Y, 0, 0, 0, 0, 0, "");
|
||||
UI_but_func_set(but, wm_block_orphans_cancel, block, nullptr);
|
||||
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
||||
UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
|
||||
}
|
||||
|
||||
struct OrphansPurgeData {
|
||||
wmOperator *op = nullptr;
|
||||
char local = true;
|
||||
char linked = false;
|
||||
char recursive = false;
|
||||
};
|
||||
|
||||
static void wm_block_orphans_purge(bContext *C, void *arg_block, void *arg_data)
|
||||
{
|
||||
OrphansPurgeData *purge_data = (OrphansPurgeData *)arg_data;
|
||||
wmOperator *op = purge_data->op;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
int num_tagged[INDEX_ID_MAX] = {0};
|
||||
|
||||
/* Tag all IDs to delete. */
|
||||
BKE_lib_query_unused_ids_tag(bmain,
|
||||
LIB_TAG_DOIT,
|
||||
purge_data->local,
|
||||
purge_data->linked,
|
||||
purge_data->recursive,
|
||||
num_tagged);
|
||||
|
||||
if (num_tagged[INDEX_ID_NULL] == 0) {
|
||||
BKE_report(op->reports, RPT_INFO, "No unused data to remove");
|
||||
}
|
||||
else {
|
||||
BKE_id_multi_tagged_delete(bmain);
|
||||
BKE_reportf(op->reports, RPT_INFO, "Deleted %d data block(s)", num_tagged[INDEX_ID_NULL]);
|
||||
DEG_relations_tag_update(bmain);
|
||||
WM_event_add_notifier(C, NC_ID | NA_REMOVED, nullptr);
|
||||
/* Force full redraw of the UI. */
|
||||
WM_main_add_notifier(NC_WINDOW, nullptr);
|
||||
}
|
||||
|
||||
UI_popup_block_close(C, CTX_wm_window(C), (uiBlock *)arg_block);
|
||||
}
|
||||
|
||||
static void wm_block_orphans_purge_button(uiBlock *block, OrphansPurgeData *purge_data)
|
||||
{
|
||||
uiBut *but = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, 0, IFACE_("Delete"), 0, 0, 0, UI_UNIT_Y, 0, 0, 0, 0, 0, "");
|
||||
UI_but_func_set(but, wm_block_orphans_purge, block, purge_data);
|
||||
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
|
||||
}
|
||||
|
||||
static std::string orphan_desc(const bContext *C, const bool local, bool linked, bool recursive)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
int num_tagged[INDEX_ID_MAX] = {0};
|
||||
std::string desc;
|
||||
|
||||
BKE_lib_query_unused_ids_tag(bmain, LIB_TAG_DOIT, local, linked, recursive, num_tagged);
|
||||
|
||||
bool is_first = true;
|
||||
for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
|
||||
if (num_tagged[i] != 0) {
|
||||
desc += fmt::format(
|
||||
"{}{} {}",
|
||||
(is_first) ? "" : ", ",
|
||||
num_tagged[i],
|
||||
(num_tagged[i] > 1) ?
|
||||
TIP_(BKE_idtype_idcode_to_name_plural(BKE_idtype_idcode_from_index(i))) :
|
||||
TIP_(BKE_idtype_idcode_to_name(BKE_idtype_idcode_from_index(i))));
|
||||
is_first = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc.empty()) {
|
||||
desc = "Nothing";
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
static uiBlock *wm_block_create_orphans_cleanup(bContext *C, ARegion *region, void *arg)
|
||||
{
|
||||
OrphansPurgeData *purge_data = static_cast<OrphansPurgeData *>(arg);
|
||||
uiBlock *block = UI_block_begin(C, region, "orphans_remove_popup", UI_EMBOSS);
|
||||
UI_block_flag_enable(
|
||||
block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
|
||||
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
||||
|
||||
uiLayout *layout = uiItemsAlertBox(block, 40, ALERT_ICON_WARNING);
|
||||
|
||||
/* Title. */
|
||||
uiItemL_ex(layout, TIP_("Purge Unused Data From This File"), 0, true, false);
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
std::string desc = "Local data: " + orphan_desc(C, true, false, false);
|
||||
|
||||
uiDefButBitC(block,
|
||||
UI_BTYPE_CHECKBOX,
|
||||
1,
|
||||
0,
|
||||
desc.c_str(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_Y,
|
||||
&purge_data->local,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"Delete unused local data");
|
||||
|
||||
desc = "Linked data: " + orphan_desc(C, false, true, false);
|
||||
|
||||
uiDefButBitC(block,
|
||||
UI_BTYPE_CHECKBOX,
|
||||
1,
|
||||
0,
|
||||
desc.c_str(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_Y,
|
||||
&purge_data->linked,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"Delete unused linked data");
|
||||
|
||||
uiDefButBitC(
|
||||
block,
|
||||
UI_BTYPE_CHECKBOX,
|
||||
1,
|
||||
0,
|
||||
"Include indirect data",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_Y,
|
||||
&purge_data->recursive,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"Recursively check for indirectly unused data, ensuring that no unused data remains");
|
||||
|
||||
uiItemS_ex(layout, 2.0f);
|
||||
|
||||
/* Buttons. */
|
||||
#ifdef _WIN32
|
||||
const bool windows_layout = true;
|
||||
#else
|
||||
const bool windows_layout = false;
|
||||
#endif
|
||||
|
||||
uiLayout *split = uiLayoutSplit(layout, 0.0f, true);
|
||||
uiLayoutSetScaleY(split, 1.2f);
|
||||
|
||||
if (windows_layout) {
|
||||
/* Windows standard layout. */
|
||||
uiLayoutColumn(split, false);
|
||||
wm_block_orphans_purge_button(block, purge_data);
|
||||
uiLayoutColumn(split, false);
|
||||
wm_block_orphans_cancel_button(block);
|
||||
}
|
||||
else {
|
||||
/* Non-Windows layout (macOS and Linux). */
|
||||
uiLayoutColumn(split, false);
|
||||
wm_block_orphans_cancel_button(block);
|
||||
uiLayoutColumn(split, false);
|
||||
wm_block_orphans_purge_button(block, purge_data);
|
||||
}
|
||||
|
||||
UI_block_bounds_set_centered(block, 14 * UI_SCALE_FAC);
|
||||
return block;
|
||||
}
|
||||
|
||||
static int outliner_orphans_cleanup_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
OrphansPurgeData *purge_data = MEM_new<OrphansPurgeData>(__func__);
|
||||
purge_data->op = op;
|
||||
UI_popup_block_invoke(C, wm_block_create_orphans_cleanup, purge_data, MEM_freeN);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OUTLINER_OT_orphans_cleanup(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->idname = "OUTLINER_OT_orphans_cleanup";
|
||||
ot->name = "Purge Unused Data...";
|
||||
ot->description = "Remove unused data from this file";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = outliner_orphans_cleanup_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int outliner_orphans_manage_exec(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
int width = 800;
|
||||
int height = 500;
|
||||
if (wm_get_screensize(&width, &height)) {
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ 0,
|
||||
/*xmax*/ width,
|
||||
/*ymin*/ 0,
|
||||
/*ymax*/ height,
|
||||
};
|
||||
|
||||
if (WM_window_open(C,
|
||||
IFACE_("Manage Unused Data"),
|
||||
&window_rect,
|
||||
SPACE_OUTLINER,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_PARENT_CENTER,
|
||||
nullptr,
|
||||
nullptr) != nullptr)
|
||||
{
|
||||
SpaceOutliner *soutline = (SpaceOutliner *)CTX_wm_area(C)->spacedata.first;
|
||||
soutline->outlinevis = SO_ID_ORPHANS;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void OUTLINER_OT_orphans_manage(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->idname = "OUTLINER_OT_orphans_manage";
|
||||
ot->name = "Manage Unused Data...";
|
||||
ot->description = "Open a window to manage unused data";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = outliner_orphans_manage_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::ed::outliner
|
||||
|
|
|
@ -511,9 +511,7 @@ void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot);
|
|||
void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot);
|
||||
void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot);
|
||||
|
||||
void OUTLINER_OT_orphans_cleanup(wmOperatorType *ot);
|
||||
void OUTLINER_OT_orphans_purge(wmOperatorType *ot);
|
||||
void OUTLINER_OT_orphans_manage(wmOperatorType *ot);
|
||||
|
||||
/* `outliner_query.cc` */
|
||||
|
||||
|
|
|
@ -60,8 +60,6 @@ void outliner_operatortypes()
|
|||
WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
|
||||
|
||||
WM_operatortype_append(OUTLINER_OT_orphans_purge);
|
||||
WM_operatortype_append(OUTLINER_OT_orphans_cleanup);
|
||||
WM_operatortype_append(OUTLINER_OT_orphans_manage);
|
||||
|
||||
WM_operatortype_append(OUTLINER_OT_parent_drop);
|
||||
WM_operatortype_append(OUTLINER_OT_parent_clear);
|
||||
|
|
Loading…
Reference in New Issue