/* Recursively iterate over tree, finding and working on selected items */ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode) { TreeElement *te; TreeStoreElem *tselem; for (te = tree->first; te; te = te->next) { tselem = TREESTORE(te); /* if item is selected, perform operation */ if (tselem->flag & TSE_SELECTED) { ID *id = NULL; char *path = NULL; int array_index = 0; short flag = 0; short groupmode = KSP_GROUP_KSNAME; /* check if RNA-property described by this selected element is an animatable prop */ if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ tree_element_to_path(soops, te, tselem, &id, &path, &array_index, &flag, &groupmode); } /* only if ID and path were set, should we perform any actions */ if (id && path) { /* action depends on mode */ switch (mode) { case KEYINGSET_EDITMODE_ADD: { /* add a new path with the information obtained (only if valid) */ // TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode); ks->active_path = BLI_countlist(&ks->paths); } break; case KEYINGSET_EDITMODE_REMOVE: { /* find the relevant path, then remove it from the KeyingSet */ KS_Path *ksp = BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode); if (ksp) { /* free path's data */ BKE_keyingset_free_path(ks, ksp); ks->active_path = 0; } } break; } /* free path, since it had to be generated */ MEM_freeN(path); } } /* go over sub-tree */ if (TSELEM_OPEN(tselem, soops)) do_outliner_keyingset_editop(soops, ks, &te->subtree, mode); } }
static int remove_keyingset_button_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); KeyingSet *ks = NULL; PropertyRNA *prop = NULL; PointerRNA ptr = {{NULL}}; char *path = NULL; short success = 0; int index = 0; /* verify the Keying Set to use: * - use the active one for now (more control over this can be added later) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set"); return OPERATOR_CANCELLED; } else { ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1); } /* try to add to keyingset using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path = RNA_path_from_ID_to_property(&ptr, prop); if (path) { KS_Path *ksp; /* try to find a path matching this description */ ksp = BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME); if (ksp) { BKE_keyingset_free_path(ks, ksp); success = 1; } /* free temp path used */ MEM_freeN(path); } } if (success) { /* send updates */ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL); /* show warning */ BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set"); } return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; }
static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports, KS_Path *ksp) { /* if data is valid, call the API function for this */ if (keyingset && ksp) { /* remove the active path from the KeyingSet */ BKE_keyingset_free_path(keyingset, ksp); /* the active path number will most likely have changed */ /* TODO: we should get more fancy and actually check if it was removed, but this will do for now */ keyingset->active_path = 0; } else { BKE_report(reports, RPT_ERROR, "Keying Set Path could not be removed"); } }
static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports, PointerRNA *ksp_ptr) { KS_Path *ksp = ksp_ptr->data; /* if data is valid, call the API function for this */ if ((keyingset && ksp) == FALSE) { BKE_report(reports, RPT_ERROR, "Keying set path could not be removed"); return; } /* remove the active path from the KeyingSet */ BKE_keyingset_free_path(keyingset, ksp); RNA_POINTER_INVALIDATE(ksp_ptr); /* the active path number will most likely have changed */ /* TODO: we should get more fancy and actually check if it was removed, but this will do for now */ keyingset->active_path = 0; }
static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports) { /* if data is valid, call the API function for this */ if (keyingset) { KS_Path *ksp, *kspn; /* free each path as we go to avoid looping twice */ for (ksp = keyingset->paths.first; ksp; ksp = kspn) { kspn = ksp->next; BKE_keyingset_free_path(keyingset, ksp); } /* reset the active path, since there aren't any left */ keyingset->active_path = 0; } else { BKE_report(reports, RPT_ERROR, "Keying set paths could not be removed"); } }