void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) { TreeElement *te; TreeStoreElem *tselem; for (te = lb->first; te; te = te->next) { tselem = TREESTORE(te); if (tselem->flag & TSE_SELECTED) { if (tselem->type == 0 && te->idcode == ID_OB) { // when objects selected in other scenes... dunno if that should be allowed Scene *scene_owner = (Scene *)outliner_search_back(soops, te, ID_SCE); if (scene_owner && scene_act != scene_owner) { ED_screen_set_scene(C, CTX_wm_screen(C), scene_owner); } /* important to use 'scene_owner' not scene_act else deleting objects can crash. * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the * outliner isn't showing scenes: Visible Layer draw mode for eg. */ operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem); } } if (TSELEM_OPEN(tselem, soops)) { outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb); } } }
static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene); return OPERATOR_FINISHED; }
static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceOops *soops= CTX_wm_space_outliner(C); Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); ED_region_tag_redraw(ar); return OPERATOR_FINISHED; }
static int outliner_toggle_selectability_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceOops *soops= CTX_wm_space_outliner(C); Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); ED_region_tag_redraw(ar); return OPERATOR_FINISHED; }
static int outliner_object_operation_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); SpaceOops *soops = CTX_wm_space_outliner(C); int event; const char *str = NULL; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); if (event == OL_OP_SELECT) { Scene *sce = scene; // to be able to delete, scenes are set... outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb); if (scene != sce) { ED_screen_set_scene(C, CTX_wm_screen(C), sce); } str = "Select Objects"; WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } else if (event == OL_OP_SELECT_HIERARCHY) { Scene *sce = scene; // to be able to delete, scenes are set... outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb); if (scene != sce) { ED_screen_set_scene(C, CTX_wm_screen(C), sce); } str = "Select Object Hierarchy"; WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } else if (event == OL_OP_DESELECT) { outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb); str = "Deselect Objects"; WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } else if (event == OL_OP_DELETE) { outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb); /* 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); DAG_relations_tag_update(bmain); str = "Delete Objects"; WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); } else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */ outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb); str = "Localized Objects"; } else if (event == OL_OP_TOGVIS) { outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); str = "Toggle Visibility"; WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene); } else if (event == OL_OP_TOGSEL) { outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); str = "Toggle Selectability"; WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } else if (event == OL_OP_TOGREN) { outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); str = "Toggle Renderability"; WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene); } else if (event == OL_OP_RENAME) { outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb); str = "Rename Object"; } ED_undo_push(C, str); return OPERATOR_FINISHED; }