doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / editors / animation / keyingsets.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung (full recode)
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29  
30 #include <stdio.h>
31 #include <stddef.h>
32 #include <string.h>
33 #include <math.h>
34 #include <float.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_math.h"
40 #include "BLI_dynstr.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_anim_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_object_types.h"
46
47 #include "BKE_main.h"
48 #include "BKE_animsys.h"
49 #include "BKE_context.h"
50 #include "BKE_depsgraph.h"
51 #include "BKE_report.h"
52
53 #include "ED_keyframing.h"
54 #include "ED_screen.h"
55
56 #include "UI_interface.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "RNA_access.h"
62 #include "RNA_define.h"
63 #include "RNA_enum_types.h"
64
65 #include "anim_intern.h"
66
67 /* ************************************************** */
68 /* KEYING SETS - OPERATORS (for use in UI panels) */
69 /* These operators are really duplication of existing functionality, but just for completeness,
70  * they're here too, and will give the basic data needed...
71  */
72
73 /* poll callback for adding default KeyingSet */
74 static int keyingset_poll_default_add (bContext *C)
75 {
76         /* as long as there's an active Scene, it's fine */
77         return (CTX_data_scene(C) != NULL);
78 }
79
80 /* poll callback for editing active KeyingSet */
81 static int keyingset_poll_active_edit (bContext *C)
82 {
83         Scene *scene= CTX_data_scene(C);
84         
85         if (scene == NULL)
86                 return 0;
87         
88         /* there must be an active KeyingSet (and KeyingSets) */
89         return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
90 }
91
92 /* poll callback for editing active KeyingSet Path */
93 static int keyingset_poll_activePath_edit (bContext *C)
94 {
95         Scene *scene= CTX_data_scene(C);
96         KeyingSet *ks;
97         
98         if (scene == NULL)
99                 return 0;
100         if (scene->active_keyingset <= 0)
101                 return 0;
102         else
103                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
104         
105         /* there must be an active KeyingSet and an active path */
106         return ((ks) && (ks->paths.first) && (ks->active_path > 0));
107 }
108
109  
110 /* Add a Default (Empty) Keying Set ------------------------- */
111
112 static int add_default_keyingset_exec (bContext *C, wmOperator *UNUSED(op))
113 {
114         Scene *scene= CTX_data_scene(C);
115         short flag=0, keyingflag=0;
116         
117         /* validate flags 
118          *      - absolute KeyingSets should be created by default
119          */
120         flag |= KEYINGSET_ABSOLUTE;
121         
122         /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
123         keyingflag = ANIM_get_keyframing_flags(scene, 0);
124         
125         /* call the API func, and set the active keyingset index */
126         BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag);
127         
128         scene->active_keyingset= BLI_countlist(&scene->keyingsets);
129         
130         /* send notifiers */
131         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
132         
133         return OPERATOR_FINISHED;
134 }
135
136 void ANIM_OT_keying_set_add (wmOperatorType *ot)
137 {
138         /* identifiers */
139         ot->name= "Add Empty Keying Set";
140         ot->idname= "ANIM_OT_keying_set_add";
141         ot->description= "Add a new (empty) Keying Set to the active Scene";
142         
143         /* callbacks */
144         ot->exec= add_default_keyingset_exec;
145         ot->poll= keyingset_poll_default_add;
146 }
147
148 /* Remove 'Active' Keying Set ------------------------- */
149
150 static int remove_active_keyingset_exec (bContext *C, wmOperator *op)
151 {
152         Scene *scene= CTX_data_scene(C);
153         KeyingSet *ks;
154         
155         /* verify the Keying Set to use:
156          *      - use the active one
157          *      - return error if it doesn't exist
158          */
159         if (scene->active_keyingset == 0) {
160                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
161                 return OPERATOR_CANCELLED;
162         }
163         else if (scene->active_keyingset < 0) {
164                 BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set");
165                 return OPERATOR_CANCELLED;
166         }
167         else
168                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
169         
170         /* free KeyingSet's data, then remove it from the scene */
171         BKE_keyingset_free(ks);
172         BLI_freelinkN(&scene->keyingsets, ks);
173         
174         /* the active one should now be the previously second-to-last one */
175         scene->active_keyingset--;
176         
177         /* send notifiers */
178         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
179         
180         return OPERATOR_FINISHED;
181 }
182
183 void ANIM_OT_keying_set_remove (wmOperatorType *ot)
184 {
185         /* identifiers */
186         ot->name= "Removed Active Keying Set";
187         ot->idname= "ANIM_OT_keying_set_remove";
188         ot->description= "Remove the active Keying Set";
189         
190         /* callbacks */
191         ot->exec= remove_active_keyingset_exec;
192         ot->poll= keyingset_poll_active_edit;
193 }
194
195 /* Add Empty Keying Set Path ------------------------- */
196
197 static int add_empty_ks_path_exec (bContext *C, wmOperator *op)
198 {
199         Scene *scene= CTX_data_scene(C);
200         KeyingSet *ks;
201         KS_Path *ksp;
202         
203         /* verify the Keying Set to use:
204          *      - use the active one
205          *      - return error if it doesn't exist
206          */
207         if (scene->active_keyingset == 0) {
208                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
209                 return OPERATOR_CANCELLED;
210         }
211         else
212                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
213         
214         /* don't use the API method for this, since that checks on values... */
215         ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
216         BLI_addtail(&ks->paths, ksp);
217         ks->active_path= BLI_countlist(&ks->paths);
218         
219         ksp->groupmode= KSP_GROUP_KSNAME; // XXX?
220         ksp->idtype= ID_OB;
221         
222         return OPERATOR_FINISHED;
223 }
224
225 void ANIM_OT_keying_set_path_add (wmOperatorType *ot)
226 {
227         /* identifiers */
228         ot->name= "Add Empty Keying Set Path";
229         ot->idname= "ANIM_OT_keying_set_path_add";
230         ot->description= "Add empty path to active Keying Set";
231         
232         /* callbacks */
233         ot->exec= add_empty_ks_path_exec;
234         ot->poll= keyingset_poll_active_edit;
235 }
236
237 /* Remove Active Keying Set Path ------------------------- */
238
239 static int remove_active_ks_path_exec (bContext *C, wmOperator *op)
240 {
241         Scene *scene= CTX_data_scene(C);
242         KeyingSet *ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
243         
244         /* if there is a KeyingSet, find the nominated path to remove */
245         if (ks) {
246                 KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1);
247                 
248                 if (ksp) {
249                         /* remove the active path from the KeyingSet */
250                         BKE_keyingset_free_path(ks, ksp);
251                         
252                         /* the active path should now be the previously second-to-last active one */
253                         ks->active_path--;
254                 }
255                 else {
256                         BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove");
257                         return OPERATOR_CANCELLED;
258                 }
259         }
260         else {
261                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
262                 return OPERATOR_CANCELLED;
263         }
264         
265         return OPERATOR_FINISHED;
266 }
267
268 void ANIM_OT_keying_set_path_remove (wmOperatorType *ot)
269 {
270         /* identifiers */
271         ot->name= "Remove Active Keying Set Path";
272         ot->idname= "ANIM_OT_keying_set_path_remove";
273         ot->description= "Remove active Path from active Keying Set";
274         
275         /* callbacks */
276         ot->exec= remove_active_ks_path_exec;
277         ot->poll= keyingset_poll_activePath_edit;
278 }
279
280 /* ************************************************** */
281 /* KEYING SETS - OPERATORS (for use in UI menus) */
282
283 /* Add to KeyingSet Button Operator ------------------------ */
284
285 static int add_keyingset_button_exec (bContext *C, wmOperator *op)
286 {
287         Main *bmain= CTX_data_main(C);
288         Scene *scene= CTX_data_scene(C);
289         KeyingSet *ks = NULL;
290         PropertyRNA *prop= NULL;
291         PointerRNA ptr= {{NULL}};
292         char *path = NULL;
293         short success= 0;
294         int index=0, pflag=0;
295         int all= RNA_boolean_get(op->ptr, "all");
296         
297         /* verify the Keying Set to use:
298          *      - use the active one for now (more control over this can be added later)
299          *      - add a new one if it doesn't exist 
300          */
301         if (scene->active_keyingset == 0) {
302                 short flag=0, keyingflag=0;
303                 
304                 /* validate flags 
305                  *      - absolute KeyingSets should be created by default
306                  */
307                 flag |= KEYINGSET_ABSOLUTE;
308                 
309                 keyingflag |= ANIM_get_keyframing_flags(scene, 0);
310                 
311                 if (IS_AUTOKEY_FLAG(scene, XYZ2RGB)) 
312                         keyingflag |= INSERTKEY_XYZ2RGB;
313                         
314                 /* call the API func, and set the active keyingset index */
315                 ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag);
316                 
317                 scene->active_keyingset= BLI_countlist(&scene->keyingsets);
318         }
319         else if (scene->active_keyingset < 0) {
320                 BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set");
321                 return OPERATOR_CANCELLED;
322         }
323         else
324                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
325         
326         /* try to add to keyingset using property retrieved from UI */
327         uiContextActiveProperty(C, &ptr, &prop, &index);
328         
329         /* check if property is able to be added */
330         if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
331                 path= RNA_path_from_ID_to_property(&ptr, prop);
332                 
333                 if (path) {
334                         /* set flags */
335                         if (all) {
336                                 pflag |= KSP_FLAG_WHOLE_ARRAY;
337                                 
338                                 /* we need to set the index for this to 0, even though it may break in some cases, this is 
339                                  * necessary if we want the entire array for most cases to get included without the user
340                                  * having to worry about where they clicked
341                                  */
342                                 index= 0;
343                         }
344                                 
345                         /* add path to this setting */
346                         BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
347                         ks->active_path= BLI_countlist(&ks->paths);
348                         success= 1;
349                         
350                         /* free the temp path created */
351                         MEM_freeN(path);
352                 }
353         }
354         
355         if (success) {
356                 /* send updates */
357                 DAG_ids_flush_update(bmain, 0);
358                 
359                 /* for now, only send ND_KEYS for KeyingSets */
360                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
361         }
362         
363         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
364 }
365
366 void ANIM_OT_keyingset_button_add (wmOperatorType *ot)
367 {
368         /* identifiers */
369         ot->name= "Add to Keying Set";
370         ot->idname= "ANIM_OT_keyingset_button_add";
371         
372         /* callbacks */
373         ot->exec= add_keyingset_button_exec; 
374         //op->poll= ???
375         
376         /* flags */
377         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
378
379         /* properties */
380         RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set.");
381 }
382
383 /* Remove from KeyingSet Button Operator ------------------------ */
384
385 static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
386 {
387         Main *bmain= CTX_data_main(C);
388         Scene *scene= CTX_data_scene(C);
389         KeyingSet *ks = NULL;
390         PropertyRNA *prop= NULL;
391         PointerRNA ptr= {{NULL}};
392         char *path = NULL;
393         short success= 0;
394         int index=0;
395         
396         /* verify the Keying Set to use:
397          *      - use the active one for now (more control over this can be added later)
398          *      - return error if it doesn't exist
399          */
400         if (scene->active_keyingset == 0) {
401                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
402                 return OPERATOR_CANCELLED;
403         }
404         else if (scene->active_keyingset < 0) {
405                 BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set");
406                 return OPERATOR_CANCELLED;
407         }
408         else
409                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
410         
411         /* try to add to keyingset using property retrieved from UI */
412         uiContextActiveProperty(C, &ptr, &prop, &index);
413
414         if (ptr.id.data && ptr.data && prop) {
415                 path= RNA_path_from_ID_to_property(&ptr, prop);
416                 
417                 if (path) {
418                         KS_Path *ksp;
419                         
420                         /* try to find a path matching this description */
421                         ksp= BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
422
423                         if (ksp) {
424                                 BKE_keyingset_free_path(ks, ksp);
425                                 success= 1;
426                         }
427                         
428                         /* free temp path used */
429                         MEM_freeN(path);
430                 }
431         }
432         
433         
434         if (success) {
435                 /* send updates */
436                 DAG_ids_flush_update(bmain, 0);
437                 
438                 /* for now, only send ND_KEYS for KeyingSets */
439                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
440         }
441         
442         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
443 }
444
445 void ANIM_OT_keyingset_button_remove (wmOperatorType *ot)
446 {
447         /* identifiers */
448         ot->name= "Remove from Keying Set";
449         ot->idname= "ANIM_OT_keyingset_button_remove";
450         
451         /* callbacks */
452         ot->exec= remove_keyingset_button_exec; 
453         //op->poll= ???
454         
455         /* flags */
456         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
457 }
458
459 /* ******************************************* */
460
461 /* Change Active KeyingSet Operator ------------------------ */
462 /* This operator checks if a menu should be shown for choosing the KeyingSet to make the active one */
463
464 static int keyingset_active_menu_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED(event))
465 {
466         /* call the menu, which will call this operator again, hence the cancelled */
467         ANIM_keying_sets_menu_setup(C, op->type->name, "ANIM_OT_keying_set_active_set");
468         return OPERATOR_CANCELLED;
469 }
470
471 static int keyingset_active_menu_exec (bContext *C, wmOperator *op)
472 {
473         Scene *scene= CTX_data_scene(C);
474         int type= RNA_int_get(op->ptr, "type");
475         
476         /* simply set the scene's active keying set index, unless the type == 0 
477          * (i.e. which happens if we want the current active to be maintained) 
478          */
479         if (type)
480                 scene->active_keyingset= type;
481                 
482         /* send notifiers */
483         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
484         
485         return OPERATOR_FINISHED;
486 }
487  
488 void ANIM_OT_keying_set_active_set (wmOperatorType *ot)
489 {
490         /* identifiers */
491         ot->name= "Set Active Keying Set";
492         ot->idname= "ANIM_OT_keying_set_active_set";
493         
494         /* callbacks */
495         ot->invoke= keyingset_active_menu_invoke;
496         ot->exec= keyingset_active_menu_exec; 
497         ot->poll= ED_operator_areaactive;
498         
499         /* flags */
500         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
501         
502         /* keyingset to use
503          *      - here the type is int not enum, since many of the indices here are determined dynamically
504          */
505         RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
506 }
507
508 /* ******************************************* */
509 /* REGISTERED KEYING SETS */
510
511 /* Keying Set Type Info declarations */
512 static ListBase keyingset_type_infos = {NULL, NULL};
513
514 /* Built-In Keying Sets (referencing type infos)*/
515 ListBase builtin_keyingsets = {NULL, NULL};
516
517 /* --------------- */
518
519 /* Find KeyingSet type info given a name */
520 KeyingSetInfo *ANIM_keyingset_info_find_named (const char name[])
521 {
522         /* sanity checks */
523         if ((name == NULL) || (name[0] == 0))
524                 return NULL;
525                 
526         /* search by comparing names */
527         return BLI_findstring(&keyingset_type_infos, name, offsetof(KeyingSetInfo, idname));
528 }
529
530 /* Find builtin KeyingSet by name */
531 KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, const char name[])
532 {
533         KeyingSet *ks, *first=NULL;
534         
535         /* sanity checks  any name to check? */
536         if (name[0] == 0)
537                 return NULL;
538         
539         /* get first KeyingSet to use */
540         if (prevKS && prevKS->next)
541                 first= prevKS->next;
542         else
543                 first= builtin_keyingsets.first;
544                 
545         /* loop over KeyingSets checking names */
546         for (ks= first; ks; ks= ks->next) {
547                 if (strcmp(name, ks->name) == 0)
548                         return ks;
549         }
550         
551         /* no matches found */
552         return NULL;
553 }
554
555 /* --------------- */
556
557 /* Add the given KeyingSetInfo to the list of type infos, and create an appropriate builtin set too */
558 void ANIM_keyingset_info_register (KeyingSetInfo *ksi)
559 {
560         KeyingSet *ks;
561         
562         /* create a new KeyingSet 
563          *      - inherit name and keyframing settings from the typeinfo
564          */
565         ks = BKE_keyingset_add(&builtin_keyingsets, ksi->name, 1, ksi->keyingflag);
566         
567         /* link this KeyingSet with its typeinfo */
568         memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
569         
570         /* add type-info to the list */
571         BLI_addtail(&keyingset_type_infos, ksi);
572 }
573
574 /* Remove the given KeyingSetInfo from the list of type infos, and also remove the builtin set if appropriate */
575 void ANIM_keyingset_info_unregister (const bContext *C, KeyingSetInfo *ksi)
576 {
577         Main *bmain= CTX_data_main(C);
578         KeyingSet *ks, *ksn;
579         
580         /* find relevant builtin KeyingSets which use this, and remove them */
581         // TODO: this isn't done now, since unregister is really only used atm when we
582         // reload the scripts, which kindof defeats the purpose of "builtin"?
583         for (ks= builtin_keyingsets.first; ks; ks= ksn) {
584                 ksn = ks->next;
585                 
586                 /* remove if matching typeinfo name */
587                 if (strcmp(ks->typeinfo, ksi->idname) == 0) {
588                         Scene *scene;
589                         BKE_keyingset_free(ks);
590                         BLI_remlink(&builtin_keyingsets, ks);
591
592                         for(scene= bmain->scene.first; scene; scene= scene->id.next)
593                                 BLI_remlink_safe(&scene->keyingsets, ks);
594
595                         MEM_freeN(ks);
596                 }
597         }
598         
599         /* free the type info */
600         BLI_freelinkN(&keyingset_type_infos, ksi);
601 }
602
603 /* --------------- */
604
605 void ANIM_keyingset_infos_exit (void)
606 {
607         KeyingSetInfo *ksi, *next;
608         
609         /* free type infos */
610         for (ksi=keyingset_type_infos.first; ksi; ksi=next) {
611                 next= ksi->next;
612                 
613                 /* free extra RNA data, and remove from list */
614                 if (ksi->ext.free)
615                         ksi->ext.free(ksi->ext.data);
616                 BLI_freelinkN(&keyingset_type_infos, ksi);
617         }
618         
619         /* free builtin sets */
620         BKE_keyingsets_free(&builtin_keyingsets);
621 }
622
623 /* ******************************************* */
624 /* KEYING SETS API (for UI) */
625
626 /* Getters for Active/Indices ----------------------------- */
627
628 /* Get the active Keying Set for the Scene provided */
629 KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene)
630 {
631         /* if no scene, we've got no hope of finding the Keying Set */
632         if (scene == NULL)
633                 return NULL;
634         
635         /* currently, there are several possibilities here:
636          *      -   0: no active keying set
637          *      - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
638          *      - < 0: a builtin keying set
639          */
640         if (scene->active_keyingset > 0)
641                 return BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
642         else
643                 return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset)-1);
644 }
645
646 /* Get the index of the Keying Set provided, for the given Scene */
647 int ANIM_scene_get_keyingset_index (Scene *scene, KeyingSet *ks)
648 {
649         int index;
650         
651         /* if no KeyingSet provided, have none */
652         if (ks == NULL)
653                 return 0;
654         
655         /* check if the KeyingSet exists in scene list */
656         if (scene) {
657                 /* get index and if valid, return 
658                  *      - (absolute) Scene KeyingSets are from (>= 1)
659                  */
660                 index = BLI_findindex(&scene->keyingsets, ks);
661                 if (index != -1)
662                         return (index + 1);
663         }
664         
665         /* still here, so try builtins list too 
666          *      - builtins are from (<= -1)
667          *      - none/invalid is (= 0)
668          */
669         index = BLI_findindex(&builtin_keyingsets, ks);
670         if (index != -1)
671                 return -(index + 1);
672         else
673                 return 0;
674 }
675
676 /* Get Keying Set to use for Auto-Keyframing some transforms */
677 KeyingSet *ANIM_get_keyingset_for_autokeying(Scene *scene, const char *tranformKSName)
678 {
679         /* get KeyingSet to use 
680          *      - use the active KeyingSet if defined (and user wants to use it for all autokeying), 
681          *        or otherwise key transforms only
682          */
683         if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset))
684                 return ANIM_scene_get_active_keyingset(scene);
685         else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL))
686                 return ANIM_builtin_keyingset_get_named(NULL, "Available");
687         else 
688                 return ANIM_builtin_keyingset_get_named(NULL, tranformKSName);
689 }
690
691 /* Menu of All Keying Sets ----------------------------- */
692
693 /* Dynamically populate an enum of Keying Sets */
694 EnumPropertyItem *ANIM_keying_sets_enum_itemf (bContext *C, PointerRNA *UNUSED(ptr), int *free)
695 {
696         Scene *scene = CTX_data_scene(C);
697         KeyingSet *ks;
698         EnumPropertyItem *item= NULL, item_tmp= {0};
699         int totitem= 0;
700         int i= 0;
701
702         if (C == NULL) {
703                 return DummyRNA_DEFAULT_items;
704         }
705         
706         /* active Keying Set 
707          *      - only include entry if it exists
708          */
709         if (scene->active_keyingset) {
710                 /* active Keying Set */
711                 item_tmp.identifier= item_tmp.name= "Active Keying Set";
712                 item_tmp.value= i++;
713                 RNA_enum_item_add(&item, &totitem, &item_tmp);
714                 
715                 /* separator */
716                 RNA_enum_item_add_separator(&item, &totitem);
717         }
718         else
719                 i++;
720                 
721         /* user-defined Keying Sets 
722          *      - these are listed in the order in which they were defined for the active scene
723          */
724         if (scene->keyingsets.first) {
725                 for (ks= scene->keyingsets.first; ks; ks= ks->next) {
726                         if (ANIM_keyingset_context_ok_poll(C, ks)) {
727                                 item_tmp.identifier= item_tmp.name= ks->name;
728                                 item_tmp.value= i++;
729                                 RNA_enum_item_add(&item, &totitem, &item_tmp);
730                         }
731                 }
732                 
733                 /* separator */
734                 RNA_enum_item_add_separator(&item, &totitem);
735         }
736         
737         /* builtin Keying Sets */
738         i= -1;
739         for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
740                 /* only show KeyingSet if context is suitable */
741                 if (ANIM_keyingset_context_ok_poll(C, ks)) {
742                         item_tmp.identifier= item_tmp.name= ks->name;
743                         item_tmp.value= i--;
744                         RNA_enum_item_add(&item, &totitem, &item_tmp);
745                 }
746         }
747
748         RNA_enum_item_end(&item, &totitem);
749         *free= 1;
750
751         return item;
752 }
753
754 /* Create (and show) a menu containing all the Keying Sets which can be used in the current context */
755 void ANIM_keying_sets_menu_setup (bContext *C, const char title[], const char op_name[])
756 {
757         Scene *scene= CTX_data_scene(C);
758         KeyingSet *ks;
759         uiPopupMenu *pup;
760         uiLayout *layout;
761         int i = 0;
762         
763         pup= uiPupMenuBegin(C, title, ICON_NULL);
764         layout= uiPupMenuLayout(pup);
765         
766         /* active Keying Set 
767          *      - only include entry if it exists
768          */
769         if (scene->active_keyingset) {
770                 uiItemIntO(layout, "Active Keying Set", ICON_NULL, op_name, "type", i++);
771                 uiItemS(layout);
772         }
773         else
774                 i++;
775         
776         /* user-defined Keying Sets 
777          *      - these are listed in the order in which they were defined for the active scene
778          */
779         if (scene->keyingsets.first) {
780                 for (ks= scene->keyingsets.first; ks; ks= ks->next) {
781                         if (ANIM_keyingset_context_ok_poll(C, ks))
782                                 uiItemIntO(layout, ks->name, ICON_NULL, op_name, "type", i++);
783                 }
784                 uiItemS(layout);
785         }
786         
787         /* builtin Keying Sets */
788         i= -1;
789         for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
790                 /* only show KeyingSet if context is suitable */
791                 if (ANIM_keyingset_context_ok_poll(C, ks))
792                         uiItemIntO(layout, ks->name, ICON_NULL, op_name, "type", i--);
793         }
794         
795         uiPupMenuEnd(C, pup);
796
797
798 /* ******************************************* */
799 /* KEYFRAME MODIFICATION */
800
801 /* Polling API ----------------------------------------------- */
802
803 /* Check if KeyingSet can be used in the current context */
804 short ANIM_keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
805 {
806         if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
807                 KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
808                 
809                 /* get the associated 'type info' for this KeyingSet */
810                 if (ksi == NULL)
811                         return 0;
812                 // TODO: check for missing callbacks!
813                 
814                 /* check if it can be used in the current context */
815                 return (ksi->poll(ksi, C));
816         }
817         
818         return 1;
819 }
820
821 /* Special 'Overrides' Iterator for Relative KeyingSets ------ */
822
823 /* 'Data Sources' for relative Keying Set 'overrides' 
824  *      - this is basically a wrapper for PointerRNA's in a linked list
825  *      - do not allow this to be accessed from outside for now
826  */
827 typedef struct tRKS_DSource {
828         struct tRKS_DSource *next, *prev;
829         PointerRNA ptr;         /* the whole point of this exercise! */
830 } tRKS_DSource;
831
832
833 /* Iterator used for overriding the behaviour of iterators defined for 
834  * relative Keying Sets, with the main usage of this being operators 
835  * requiring Auto Keyframing. Internal Use Only!
836  */
837 static void RKS_ITER_overrides_list (KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
838 {
839         tRKS_DSource *ds;
840         
841         for (ds = dsources->first; ds; ds = ds->next) {
842                 /* run generate callback on this data */
843                 ksi->generate(ksi, C, ks, &ds->ptr);
844         }
845 }
846
847 /* Add new data source for relative Keying Sets */
848 void ANIM_relative_keyingset_add_source (ListBase *dsources, ID *id, StructRNA *srna, void *data)
849 {
850         tRKS_DSource *ds;
851         
852         /* sanity checks 
853          *      - we must have somewhere to output the data
854          *      - we must have both srna+data (and with id too optionally), or id by itself only
855          */
856         if (dsources == NULL)
857                 return;
858         if (ELEM(NULL, srna, data) && (id == NULL))
859                 return;
860         
861         /* allocate new elem, and add to the list */
862         ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
863         BLI_addtail(dsources, ds);
864         
865         /* depending on what data we have, create using ID or full pointer call */
866         if (srna && data)
867                 RNA_pointer_create(id, srna, data, &ds->ptr);
868         else
869                 RNA_id_pointer_create(id, &ds->ptr);
870 }
871
872 /* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
873
874 /* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
875  * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
876  * Returns the number of channels that keyframes were added to
877  */
878 int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
879 {
880         Scene *scene= CTX_data_scene(C);
881         ReportList *reports = CTX_wm_reports(C);
882         KS_Path *ksp;
883         int kflag=0, success= 0;
884         char *groupname= NULL;
885         
886         /* sanity checks */
887         if (ks == NULL)
888                 return 0;
889         
890         /* get flags to use */
891         if (mode == MODIFYKEY_MODE_INSERT) {
892                 /* use KeyingSet's flags as base */
893                 kflag= ks->keyingflag;
894                 
895                 /* suppliment with info from the context */
896                 kflag |= ANIM_get_keyframing_flags(scene, 1);
897         }
898         else if (mode == MODIFYKEY_MODE_DELETE)
899                 kflag= 0;
900         
901         /* if relative Keying Sets, poll and build up the paths */
902         if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
903                 KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
904                 
905                 /* clear all existing paths 
906                  * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
907                  */
908                 BKE_keyingset_free(ks);
909                 
910                 /* get the associated 'type info' for this KeyingSet */
911                 if (ksi == NULL)
912                         return MODIFYKEY_MISSING_TYPEINFO;
913                 // TODO: check for missing callbacks!
914                 
915                 /* check if it can be used in the current context */
916                 if (ksi->poll(ksi, C)) {
917                         /* if a list of data sources are provided, run a special iterator over them,
918                          * otherwise, just continue per normal
919                          */
920                         if (dsources) 
921                                 RKS_ITER_overrides_list(ksi, C, ks, dsources);
922                         else
923                                 ksi->iter(ksi, C, ks);
924                                 
925                         /* if we don't have any paths now, then this still qualifies as invalid context */
926                         if (ks->paths.first == NULL)
927                                 return MODIFYKEY_INVALID_CONTEXT;
928                 }
929                 else {
930                         /* poll callback tells us that KeyingSet is useless in current context */
931                         return MODIFYKEY_INVALID_CONTEXT;
932                 }
933         }
934         
935         /* apply the paths as specified in the KeyingSet now */
936         for (ksp= ks->paths.first; ksp; ksp= ksp->next) { 
937                 int arraylen, i;
938                 short kflag2;
939                 
940                 /* skip path if no ID pointer is specified */
941                 if (ksp->id == NULL) {
942                         BKE_reportf(reports, RPT_WARNING,
943                                 "Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])",
944                                 ks->name, ksp->rna_path, ksp->array_index);
945                         continue;
946                 }
947                 
948                 /* since keying settings can be defined on the paths too, extend the path before using it */
949                 kflag2 = (kflag | ksp->keyingflag);
950                 
951                 /* get pointer to name of group to add channels to */
952                 if (ksp->groupmode == KSP_GROUP_NONE)
953                         groupname= NULL;
954                 else if (ksp->groupmode == KSP_GROUP_KSNAME)
955                         groupname= ks->name;
956                 else
957                         groupname= ksp->group;
958                 
959                 /* init arraylen and i - arraylen should be greater than i so that
960                  * normal non-array entries get keyframed correctly
961                  */
962                 i= ksp->array_index;
963                 arraylen= i;
964                 
965                 /* get length of array if whole array option is enabled */
966                 if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
967                         PointerRNA id_ptr, ptr;
968                         PropertyRNA *prop;
969                         
970                         RNA_id_pointer_create(ksp->id, &id_ptr);
971                         if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
972                                 arraylen= RNA_property_array_length(&ptr, prop);
973                 }
974                 
975                 /* we should do at least one step */
976                 if (arraylen == i)
977                         arraylen++;
978                 
979                 /* for each possible index, perform operation 
980                  *      - assume that arraylen is greater than index
981                  */
982                 for (; i < arraylen; i++) {
983                         /* action to take depends on mode */
984                         if (mode == MODIFYKEY_MODE_INSERT)
985                                 success += insert_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
986                         else if (mode == MODIFYKEY_MODE_DELETE)
987                                 success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
988                 }
989                 
990                 /* set recalc-flags */
991                 switch (GS(ksp->id->name)) {
992                         case ID_OB: /* Object (or Object-Related) Keyframes */
993                         {
994                                 Object *ob= (Object *)ksp->id;
995                                 
996                                 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; // XXX: only object transforms only?
997                         }
998                                 break;
999                 }
1000                 
1001                 /* send notifiers for updates (this doesn't require context to work!) */
1002                 WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
1003         }
1004         
1005         /* return the number of channels successfully affected */
1006         return success;
1007 }
1008
1009 /* ************************************************** */