static int outliner_modifier_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; eOutliner_PropModifierOps event; event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); outliner_do_data_operation(soops, datalevel, event, &soops->tree, modifier_cb, C); if (event == OL_MODIFIER_OP_DELETE) { outliner_cleanup_tree(soops); } ED_undo_push(C, "Modifier operation"); return OPERATOR_FINISHED; }
static int outliner_action_set_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; bAction *act; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); /* get action to use */ act = BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "action")); if (act == NULL) { BKE_report(op->reports, RPT_ERROR, "No valid action to add"); return OPERATOR_CANCELLED; } else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, "Action '%s' does not specify what datablocks it can be used on " "(try setting the 'ID Root Type' setting from the Datablocks Editor " "for this action to avoid future problems)", act->id.name + 2); } /* perform action if valid channel */ if (datalevel == TSE_ANIM_DATA) outliner_do_id_set_operation(soops, datalevel, &soops->tree, (ID *)act, actionset_id_cb); else if (idlevel == ID_AC) outliner_do_id_set_operation(soops, idlevel, &soops->tree, (ID *)act, actionset_id_cb); else return OPERATOR_CANCELLED; /* set notifier that things have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Set action"); /* done */ return OPERATOR_FINISHED; }
static int outliner_data_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops= CTX_wm_space_outliner(C); int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; int event; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event= RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (datalevel==TSE_POSE_CHANNEL) { if (event>0) { outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb); WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); ED_undo_push(C, "PoseChannel operation"); } } else if (datalevel==TSE_BONE) { if (event>0) { outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb); WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); ED_undo_push(C, "Bone operation"); } } else if (datalevel==TSE_EBONE) { if (event>0) { outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb); WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); ED_undo_push(C, "EditBone operation"); } } else if (datalevel==TSE_SEQUENCE) { if (event>0) { outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb); } } return OPERATOR_FINISHED; }
static int outliner_id_operation_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; eOutlinerIdOpTypes event; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); event = RNA_enum_get(op->ptr, "type"); switch (event) { case OUTLINER_IDOP_UNLINK: { /* unlink datablock from its parent */ switch (idlevel) { case ID_AC: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_action_cb); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Unlink action"); break; case ID_MA: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_material_cb); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL); ED_undo_push(C, "Unlink material"); break; case ID_TE: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_texture_cb); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL); ED_undo_push(C, "Unlink texture"); break; case ID_WO: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_world_cb); WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL); ED_undo_push(C, "Unlink world"); break; default: BKE_report(op->reports, RPT_WARNING, "Not yet implemented"); break; } } break; case OUTLINER_IDOP_LOCAL: { /* make local */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); ED_undo_push(C, "Localized Data"); } break; case OUTLINER_IDOP_SINGLE: { /* make single user */ switch (idlevel) { case ID_AC: outliner_do_libdata_operation(C, scene, soops, &soops->tree, singleuser_action_cb); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Single-User Action"); break; case ID_WO: outliner_do_libdata_operation(C, scene, soops, &soops->tree, singleuser_world_cb); WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL); ED_undo_push(C, "Single-User World"); break; default: BKE_report(op->reports, RPT_WARNING, "Not yet implemented"); break; } } break; case OUTLINER_IDOP_FAKE_ADD: { /* set fake user */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_fake_user_set_cb); WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Add Fake User"); } break; case OUTLINER_IDOP_FAKE_CLEAR: { /* clear fake user */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_fake_user_clear_cb); WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Clear Fake User"); } break; case OUTLINER_IDOP_RENAME: { /* rename */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Rename"); } break; case OUTLINER_IDOP_SELECT_LINKED: outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_select_linked_cb); ED_undo_push(C, "Select"); break; default: // invalid - unhandled break; } /* wrong notifier still... */ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); // XXX: this is just so that outliner is always up to date WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL); return OPERATOR_FINISHED; }
static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, const wmEvent *event, const float mval[2]) { ReportList *reports = CTX_wm_reports(C); // XXX... if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) { int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; TreeStoreElem *tselem = TREESTORE(te); /* select object that's clicked on and popup context menu */ if (!(tselem->flag & TSE_SELECTED)) { if (outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1) ) outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); tselem->flag |= TSE_SELECTED; /* redraw, same as outliner_select function */ soops->storeflag |= SO_TREESTORE_REDRAW; ED_region_tag_redraw(ar); } set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (scenelevel) { //if (objectlevel || datalevel || idlevel) error("Mixed selection"); //else pupmenu("Scene Operations%t|Delete"); } else if (objectlevel) { WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL); } else if (idlevel) { if (idlevel == -1 || datalevel) { BKE_report(reports, RPT_WARNING, "Mixed selection"); } else { if (idlevel == ID_GR) WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL); else WM_operator_name_call(C, "OUTLINER_OT_id_operation", WM_OP_INVOKE_REGION_WIN, NULL); } } else if (datalevel) { if (datalevel == -1) { BKE_report(reports, RPT_WARNING, "Mixed selection"); } else { if (datalevel == TSE_ANIM_DATA) WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); else if (datalevel == TSE_DRIVER_BASE) { /* do nothing... no special ops needed yet */ } else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ } else { WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); } } } return 1; } for (te = te->subtree.first; te; te = te->next) { if (do_outliner_operation_event(C, scene, ar, soops, te, event, mval)) return 1; } return 0; }
static int outliner_data_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; int event; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (event <= 0) return OPERATOR_CANCELLED; switch (datalevel) { case TSE_POSE_CHANNEL: { outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "PoseChannel operation"); } break; case TSE_BONE: { outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "Bone operation"); } break; case TSE_EBONE: { outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "EditBone operation"); } break; case TSE_SEQUENCE: { Scene *scene = CTX_data_scene(C); outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene); } break; case TSE_RNA_STRUCT: if (event == 5) { outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); } break; default: BKE_report(op->reports, RPT_WARNING, "Not yet implemented"); break; } return OPERATOR_FINISHED; }
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; eOutliner_AnimDataOps event; short updateDeps = 0; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (datalevel != TSE_ANIM_DATA) return OPERATOR_CANCELLED; /* perform the core operation */ switch (event) { case OUTLINER_ANIMOP_CLEAR_ADT: /* Remove Animation Data - this may remove the active action, in some cases... */ outliner_do_data_operation(soops, datalevel, event, &soops->tree, clear_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Clear Animation Data"); break; case OUTLINER_ANIMOP_SET_ACT: /* delegate once again... */ WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL); break; case OUTLINER_ANIMOP_CLEAR_ACT: /* clear active action - using standard rules */ outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Unlink action"); break; case OUTLINER_ANIMOP_REFRESH_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */ updateDeps = 1; break; case OUTLINER_ANIMOP_CLEAR_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); ED_undo_push(C, "Clear Drivers"); updateDeps = 1; break; default: // invalid break; } /* update dependencies */ if (updateDeps) { /* rebuild depsgraph for the new deps */ DAG_relations_tag_update(CTX_data_main(C)); } return OPERATOR_FINISHED; }