Merged changes in the trunk up to revision 55357.
[blender.git] / source / blender / editors / animation / anim_filter.c
index f1dfbd40c11b93d0de37a28fa07400cf0b1fdcfe..7648d99821637fae372ccf945ede3db4f9b21482 100644 (file)
 #include "DNA_camera_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_lattice_types.h"
-#include "DNA_linestyle_types.h"
+#ifdef WITH_FREESTYLE
+#  include "DNA_linestyle_types.h"
+#endif
 #include "DNA_key_types.h"
+#include "DNA_mask_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meta_types.h"
@@ -87,8 +90,8 @@
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_node.h"
+#include "BKE_mask.h"
 #include "BKE_sequencer.h"
-#include "BKE_utildefines.h"
 
 #include "ED_anim_api.h"
 #include "ED_markers.h"
 /* ----------- Private Stuff - Action Editor ------------- */
 
 /* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */
-/* Note: there's a similar function in key.c (ob_get_key) */
-static Key *actedit_get_shapekeys (bAnimContext *ac) 
+/* Note: there's a similar function in key.c (BKE_key_from_object) */
+static Key *actedit_get_shapekeys(bAnimContext *ac)
 {
-       Scene *scene= ac->scene;
+       Scene *scene = ac->scene;
        Object *ob;
        Key *key;
        
@@ -114,7 +117,7 @@ static Key *actedit_get_shapekeys (bAnimContext *ac)
        //if (saction->pin) return NULL;
        
        /* shapekey data is stored with geometry data */
-       key= ob_get_key(ob);
+       key = BKE_key_from_object(ob);
        
        if (key) {
                if (key->type == KEY_RELATIVE)
@@ -125,7 +128,7 @@ static Key *actedit_get_shapekeys (bAnimContext *ac)
 }
 
 /* Get data being edited in Action Editor (depending on current 'mode') */
-static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
+static short actedit_get_context(bAnimContext *ac, SpaceAction *saction)
 {
        /* get dopesheet */
        ac->ads = &saction->ads;
@@ -134,51 +137,77 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
        switch (saction->mode) {
                case SACTCONT_ACTION: /* 'Action Editor' */
                        /* if not pinned, sync with active object */
-                       if (/*saction->pin == 0*/1) {
+                       if (/*saction->pin == 0*/ 1) {
                                if (ac->obact && ac->obact->adt)
                                        saction->action = ac->obact->adt->action;
                                else
-                                       saction->action= NULL;
+                                       saction->action = NULL;
                        }
                        
-                       ac->datatype= ANIMCONT_ACTION;
-                       ac->data= saction->action;
+                       ac->datatype = ANIMCONT_ACTION;
+                       ac->data = saction->action;
                        
-                       ac->mode= saction->mode;
+                       ac->mode = saction->mode;
                        return 1;
                        
                case SACTCONT_SHAPEKEY: /* 'ShapeKey Editor' */
-                       ac->datatype= ANIMCONT_SHAPEKEY;
-                       ac->data= actedit_get_shapekeys(ac);
+                       ac->datatype = ANIMCONT_SHAPEKEY;
+                       ac->data = actedit_get_shapekeys(ac);
                        
-                       ac->mode= saction->mode;
-                       return 1;
+                       /* if not pinned, sync with active object */
+                       if (/*saction->pin == 0*/ 1) {
+                               Key *key = (Key *)ac->data;
+                               
+                               if (key && key->adt)
+                                       saction->action = key->adt->action;
+                               else
+                                       saction->action = NULL;
+                       }
                        
-               case SACTCONT_GPENCIL: /* Grease Pencil */ // XXX review how this mode is handled...
+                       ac->mode = saction->mode;
+                       return 1;
+               
+               case SACTCONT_GPENCIL: /* Grease Pencil */ /* XXX review how this mode is handled... */
                        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
-                       saction->ads.source= (ID *)ac->scene;
+                       saction->ads.source = (ID *)ac->scene;
                        
-                       ac->datatype= ANIMCONT_GPENCIL;
-                       ac->data= &saction->ads;
+                       ac->datatype = ANIMCONT_GPENCIL;
+                       ac->data = &saction->ads;
                        
-                       ac->mode= saction->mode;
+                       ac->mode = saction->mode;
                        return 1;
                        
+               case SACTCONT_MASK: /* Mask */ /* XXX review how this mode is handled... */
+               {
+                       /* TODO, other methods to get the mask */
+                       // Sequence *seq = BKE_sequencer_active_get(ac->scene);
+                       //MovieClip *clip = ac->scene->clip;
+//                     struct Mask *mask = seq ? seq->mask : NULL;
+                       
+                       /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+                       saction->ads.source = (ID *)ac->scene;
+                       
+                       ac->datatype = ANIMCONT_MASK;
+                       ac->data = &saction->ads;
+                       
+                       ac->mode = saction->mode;
+                       return 1;
+               }
                case SACTCONT_DOPESHEET: /* DopeSheet */
                        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
-                       saction->ads.source= (ID *)ac->scene;
+                       saction->ads.source = (ID *)ac->scene;
                        
-                       ac->datatype= ANIMCONT_DOPESHEET;
-                       ac->data= &saction->ads;
+                       ac->datatype = ANIMCONT_DOPESHEET;
+                       ac->data = &saction->ads;
                        
-                       ac->mode= saction->mode;
+                       ac->mode = saction->mode;
                        return 1;
                
                default: /* unhandled yet */
-                       ac->datatype= ANIMCONT_NONE;
-                       ac->data= NULL;
+                       ac->datatype = ANIMCONT_NONE;
+                       ac->data = NULL;
                        
-                       ac->mode= -1;
+                       ac->mode = -1;
                        return 0;
        }
 }
@@ -186,12 +215,12 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
 /* ----------- Private Stuff - Graph Editor ------------- */
 
 /* Get data being edited in Graph Editor (depending on current 'mode') */
-static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
+static short graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo)
 {
        /* init dopesheet data if non-existant (i.e. for old files) */
        if (sipo->ads == NULL) {
-               sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
-               sipo->ads->source= (ID *)ac->scene;
+               sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
+               sipo->ads->source = (ID *)ac->scene;
        }
        ac->ads = sipo->ads;
        
@@ -203,33 +232,33 @@ static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
        
        /* sync settings with current view status, then return appropriate data */
        switch (sipo->mode) {
-               case SIPO_MODE_ANIMATION:       /* Animation F-Curve Editor */
+               case SIPO_MODE_ANIMATION:  /* Animation F-Curve Editor */
                        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
-                       sipo->ads->source= (ID *)ac->scene;
+                       sipo->ads->source = (ID *)ac->scene;
                        sipo->ads->filterflag &= ~ADS_FILTER_ONLYDRIVERS;
                        
-                       ac->datatype= ANIMCONT_FCURVES;
-                       ac->data= sipo->ads;
+                       ac->datatype = ANIMCONT_FCURVES;
+                       ac->data = sipo->ads;
                        
-                       ac->mode= sipo->mode;
+                       ac->mode = sipo->mode;
                        return 1;
                
-               case SIPO_MODE_DRIVERS:         /* Driver F-Curve Editor */
+               case SIPO_MODE_DRIVERS:  /* Driver F-Curve Editor */
                        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
-                       sipo->ads->source= (ID *)ac->scene;
+                       sipo->ads->source = (ID *)ac->scene;
                        sipo->ads->filterflag |= ADS_FILTER_ONLYDRIVERS;
                        
-                       ac->datatype= ANIMCONT_DRIVERS;
-                       ac->data= sipo->ads;
+                       ac->datatype = ANIMCONT_DRIVERS;
+                       ac->data = sipo->ads;
                        
-                       ac->mode= sipo->mode;
+                       ac->mode = sipo->mode;
                        return 1;
                
                default: /* unhandled yet */
-                       ac->datatype= ANIMCONT_NONE;
-                       ac->data= NULL;
+                       ac->datatype = ANIMCONT_NONE;
+                       ac->data = NULL;
                        
-                       ac->mode= -1;
+                       ac->mode = -1;
                        return 0;
        }
 }
@@ -237,20 +266,20 @@ static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
 /* ----------- Private Stuff - NLA Editor ------------- */
 
 /* Get data being edited in Graph Editor (depending on current 'mode') */
-static short nlaedit_get_context (bAnimContext *ac, SpaceNla *snla)
+static short nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
 {
        /* init dopesheet data if non-existant (i.e. for old files) */
        if (snla->ads == NULL)
-               snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
+               snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
        ac->ads = snla->ads;
        
        /* sync settings with current view status, then return appropriate data */
        /* update scene-pointer (no need to check for pinning yet, as not implemented) */
-       snla->ads->source= (ID *)ac->scene;
+       snla->ads->source = (ID *)ac->scene;
        snla->ads->filterflag |= ADS_FILTER_ONLYNLA;
        
-       ac->datatype= ANIMCONT_NLA;
-       ac->data= snla->ads;
+       ac->datatype = ANIMCONT_NLA;
+       ac->data = snla->ads;
        
        return 1;
 }
@@ -261,42 +290,39 @@ static short nlaedit_get_context (bAnimContext *ac, SpaceNla *snla)
  *     - AnimContext to write to is provided as pointer to var on stack so that we don't have
  *       allocation/freeing costs (which are not that avoidable with channels).
  */
-short ANIM_animdata_context_getdata (bAnimContext *ac)
+short ANIM_animdata_context_getdata(bAnimContext *ac)
 {
        SpaceLink *sl = ac->sl;
-       short ok= 0;
+       short ok = FALSE;
        
        /* context depends on editor we are currently in */
        if (sl) {
                switch (ac->spacetype) {
                        case SPACE_ACTION:
                        {
-                               SpaceAction *saction= (SpaceAction *)sl;
-                               ok= actedit_get_context(ac, saction);
+                               SpaceAction *saction = (SpaceAction *)sl;
+                               ok = actedit_get_context(ac, saction);
                        }
-                               break;
+                       break;
                                
                        case SPACE_IPO:
                        {
-                               SpaceIpo *sipo= (SpaceIpo *)sl;
-                               ok= graphedit_get_context(ac, sipo);
+                               SpaceIpo *sipo = (SpaceIpo *)sl;
+                               ok = graphedit_get_context(ac, sipo);
                        }
-                               break;
+                       break;
                                
                        case SPACE_NLA:
                        {
-                               SpaceNla *snla= (SpaceNla *)sl;
-                               ok= nlaedit_get_context(ac, snla);
+                               SpaceNla *snla = (SpaceNla *)sl;
+                               ok = nlaedit_get_context(ac, snla);
                        }
-                               break;
+                       break;
                }
        }
        
        /* check if there's any valid data */
-       if (ok && ac->data)
-               return 1;
-       else
-               return 0;
+       return (ok && ac->data);
 }
 
 /* Obtain current anim-data context from Blender Context info 
@@ -304,30 +330,31 @@ short ANIM_animdata_context_getdata (bAnimContext *ac)
  *       allocation/freeing costs (which are not that avoidable with channels).
  *     - Clears data and sets the information from Blender Context which is useful
  */
-short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
+short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
 {
-       ScrArea *sa= CTX_wm_area(C);
-       ARegion *ar= CTX_wm_region(C);
-       SpaceLink *sl= CTX_wm_space_data(C);
-       Scene *scene= CTX_data_scene(C);
+       ScrArea *sa = CTX_wm_area(C);
+       ARegion *ar = CTX_wm_region(C);
+       SpaceLink *sl = CTX_wm_space_data(C);
+       Scene *scene = CTX_data_scene(C);
        
        /* clear old context info */
        if (ac == NULL) return 0;
        memset(ac, 0, sizeof(bAnimContext));
        
        /* get useful default context settings from context */
-       ac->scene= scene;
+       ac->scene = scene;
        if (scene) {
-               ac->markers= ED_context_get_markers(C);         
-               ac->obact= (scene->basact)?  scene->basact->object : NULL;
+               ac->markers = ED_context_get_markers(C);
+               ac->obact = (scene->basact) ?  scene->basact->object : NULL;
        }
-       ac->sa= sa;
-       ac->ar= ar;
-       ac->sl= sl;
-       ac->spacetype= (sa) ? sa->spacetype : 0;
-       ac->regiontype= (ar) ? ar->regiontype : 0;
+       ac->sa = sa;
+       ac->ar = ar;
+       ac->sl = sl;
+       ac->spacetype = (sa) ? sa->spacetype : 0;
+       ac->regiontype = (ar) ? ar->regiontype : 0;
        
        /* get data context info */
+       // XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
        return ANIM_animdata_context_getdata(ac);
 }
 
@@ -346,28 +373,31 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
  *        dealt with by the recursive detection idiom in place.
  *
  * Implementation Note:
- *     YES the _doSubChannels variable is NOT read anywhere. BUT, this is NOT an excuse
- *     to go steamrolling the logic into a single-line expression as from experience,
- *     those are notoriously difficult to read + debug when extending later on. The code
- *     below is purposefully laid out so that each case noted above corresponds clearly to
- *     one case below.
+ *  YES the _doSubChannels variable is NOT read anywhere. BUT, this is NOT an excuse
+ *  to go steamrolling the logic into a single-line expression as from experience,
+ *  those are notoriously difficult to read + debug when extending later on. The code
+ *  below is purposefully laid out so that each case noted above corresponds clearly to
+ *  one case below.
  */
 #define BEGIN_ANIMFILTER_SUBCHANNELS(expanded_check) \
        { \
                int _filter = filter_mode; \
                short _doSubChannels = 0; \
                if (!(filter_mode & ANIMFILTER_LIST_VISIBLE) || (expanded_check)) \
-                       _doSubChannels=1; \
+                       _doSubChannels = 1; \
                else if (!(filter_mode & ANIMFILTER_LIST_CHANNELS)) \
-                       _doSubChannels=2; \
-               else {\
+                       _doSubChannels = 2; \
+               else { \
                        filter_mode |= ANIMFILTER_TMP_PEEK; \
                } \
-               (void) _doSubChannels;
-               /* ... standard sub-channel filtering can go on here now ... */
+                \
+               { \
+                       (void) _doSubChannels; \
+               }
+/* ... standard sub-channel filtering can go on here now ... */
 #define END_ANIMFILTER_SUBCHANNELS \
                filter_mode = _filter; \
-       }
+       } (void)0
 
 /* ............................... */
 
@@ -387,16 +417,16 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
  *
  * For this to work correctly, a standard set of data needs to be available within the scope that this
  * gets called in: 
- *     - ListBase anim_data;
- *     - bDopeSheet *ads;
- *     - bAnimListElem *ale;
- *     - size_t items;
+ *  - ListBase anim_data;
+ *  - bDopeSheet *ads;
+ *  - bAnimListElem *ale;
+ *  - size_t items;
  *
- *     - id: ID block which should have an AnimData pointer following it immediately, to use
- *     - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
- *     - nlaOk: line or block of code to execute for NLA tracks+strips case
- *     - driversOk: line or block of code to execute for Drivers case
- *     - keysOk: line or block of code for Keyframes case
+ *  - id: ID block which should have an AnimData pointer following it immediately, to use
+ *  - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
+ *  - nlaOk: line or block of code to execute for NLA tracks+strips case
+ *  - driversOk: line or block of code to execute for Drivers case
+ *  - keysOk: line or block of code for Keyframes case
  *
  * The checks for the various cases are as follows:
  *     0) top level: checks for animdata and also that all the F-Curves for the block will be visible
@@ -409,33 +439,33 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
  *     4) normal keyframes: only when there is an active action
  */
 #define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
-       {\
-               if ((id)->adt) {\
-                       if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) {\
-                               if (filter_mode & ANIMFILTER_ANIMDATA) {\
-                                       adtOk\
-                               }\
-                               else if (ads->filterflag & ADS_FILTER_ONLYNLA) {\
-                                       if (ANIMDATA_HAS_NLA(id)) {\
-                                               nlaOk\
-                                       }\
-                                       else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) && ANIMDATA_HAS_KEYS(id)) {\
-                                               nlaOk\
-                                       }\
-                               }\
-                               else if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) {\
-                                       if (ANIMDATA_HAS_DRIVERS(id)) {\
-                                               driversOk\
-                                       }\
-                               }\
-                               else {\
-                                       if (ANIMDATA_HAS_KEYS(id)) {\
-                                               keysOk\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
+       { \
+               if ((id)->adt) { \
+                       if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) { \
+                               if (filter_mode & ANIMFILTER_ANIMDATA) { \
+                                       adtOk \
+                               } \
+                               else if (ads->filterflag & ADS_FILTER_ONLYNLA) { \
+                                       if (ANIMDATA_HAS_NLA(id)) { \
+                                               nlaOk \
+                                       } \
+                                       else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || ANIMDATA_HAS_KEYS(id)) { \
+                                               nlaOk \
+                                       } \
+                               } \
+                               else if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) { \
+                                       if (ANIMDATA_HAS_DRIVERS(id)) { \
+                                               driversOk \
+                                       } \
+                               } \
+                               else { \
+                                       if (ANIMDATA_HAS_KEYS(id)) { \
+                                               keysOk \
+                                       } \
+                               } \
+                       } \
+               } \
+       } (void)0
 
 /* ............................... */
 
@@ -449,13 +479,13 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
        if (filter_mode & ANIMFILTER_TMP_PEEK) \
                return 1; \
        else { \
-               bAnimListElem *ale= make_new_animlistelem(channel_data, channel_type, (ID *)owner_id); \
-               if (ale) {\
+               bAnimListElem *ale = make_new_animlistelem(channel_data, channel_type, (ID *)owner_id); \
+               if (ale) { \
                        BLI_addtail(anim_data, ale); \
-                       items++; \
+                       items ++; \
                        ale_statement \
                } \
-       }
+       } (void)0
        
 #define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \
        ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {})
@@ -464,13 +494,13 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
        
 /* quick macro to test if an anim-channel representing an AnimData block is suitably active */
 #define ANIMCHANNEL_ACTIVEOK(ale) \
-       ( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
+       (!(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
 
 /* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
 #define ANIMCHANNEL_SELOK(test_func) \
-               ( !(filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) || \
-                 ((filter_mode & ANIMFILTER_SEL) && test_func) || \
-                 ((filter_mode & ANIMFILTER_UNSEL) && test_func==0) ) 
+       (!(filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) || \
+        ((filter_mode & ANIMFILTER_SEL) && test_func) || \
+        ((filter_mode & ANIMFILTER_UNSEL) && test_func == 0) )
                  
 /* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes 
  *     - _SELEDIT means that only selected curves will have visible+editable keyframes
@@ -481,29 +511,29 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
  *     3) test_func (i.e. selection test) - only if selected, this test will pass
  */
 #define ANIMCHANNEL_SELEDITOK(test_func) \
-               ( !(filter_mode & ANIMFILTER_SELEDIT) || \
-                 !(filter_mode & ANIMFILTER_FOREDIT) || \
-                 (test_func) )
+       (!(filter_mode & ANIMFILTER_SELEDIT) || \
+        !(filter_mode & ANIMFILTER_FOREDIT) || \
+        (test_func) )
 
 /* ----------- 'Private' Stuff --------------- */
 
 /* this function allocates memory for a new bAnimListElem struct for the 
  * provided animation channel-data. 
  */
-static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *owner_id)
+static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owner_id)
 {
-       bAnimListElem *ale= NULL;
+       bAnimListElem *ale = NULL;
        
        /* only allocate memory if there is data to convert */
        if (data) {
                /* allocate and set generic data */
-               ale= MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
+               ale = MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
                
-               ale->data= data;
-               ale->type= datatype;
+               ale->data = data;
+               ale->type = datatype;
                
-               ale->id= owner_id;
-               ale->adt= BKE_animdata_from_id(owner_id);
+               ale->id = owner_id;
+               ale->adt = BKE_animdata_from_id(owner_id);
                
                /* do specifics */
                switch (datatype) {
@@ -512,320 +542,333 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *own
                                /* nothing to include for now... this is just a dummy wrappy around all the other channels 
                                 * in the DopeSheet, and gets included at the start of the list
                                 */
-                               ale->key_data= NULL;
-                               ale->datatype= ALE_ALL;
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_ALL;
                        }
-                               break;
+                       break;
                        
                        case ANIMTYPE_SCENE:
                        {
-                               Scene *sce= (Scene *)data;
+                               Scene *sce = (Scene *)data;
                                
-                               ale->flag= sce->flag;
+                               ale->flag = sce->flag;
                                
-                               ale->key_data= sce;
-                               ale->datatype= ALE_SCE;
+                               ale->key_data = sce;
+                               ale->datatype = ALE_SCE;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_OBJECT:
                        {
-                               Base *base= (Base *)data;
-                               Object *ob= base->object;
+                               Base *base = (Base *)data;
+                               Object *ob = base->object;
                                
-                               ale->flag= ob->flag;
+                               ale->flag = ob->flag;
                                
-                               ale->key_data= ob;
-                               ale->datatype= ALE_OB;
+                               ale->key_data = ob;
+                               ale->datatype = ALE_OB;
                                
-                               ale->adt= BKE_animdata_from_id(&ob->id);
+                               ale->adt = BKE_animdata_from_id(&ob->id);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_FILLACTD:
                        {
-                               bAction *act= (bAction *)data;
+                               bAction *act = (bAction *)data;
                                
-                               ale->flag= act->flag;
+                               ale->flag = act->flag;
                                
-                               ale->key_data= act;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = act;
+                               ale->datatype = ALE_ACT;
                        }
-                               break;
+                       break;
                        case ANIMTYPE_FILLDRIVERS:
                        {
-                               AnimData *adt= (AnimData *)data;
+                               AnimData *adt = (AnimData *)data;
                                
-                               ale->flag= adt->flag;
+                               ale->flag = adt->flag;
                                
-                                       // XXX... drivers don't show summary for now
-                               ale->key_data= NULL;
-                               ale->datatype= ALE_NONE;
+                               // XXX... drivers don't show summary for now
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_NONE;
                        }
-                               break;
+                       break;
                        
                        case ANIMTYPE_DSMAT:
                        {
-                               Material *ma= (Material *)data;
-                               AnimData *adt= ma->adt;
+                               Material *ma = (Material *)data;
+                               AnimData *adt = ma->adt;
                                
-                               ale->flag= FILTER_MAT_OBJD(ma);
+                               ale->flag = FILTER_MAT_OBJD(ma);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSLAM:
                        {
-                               Lamp *la= (Lamp *)data;
-                               AnimData *adt= la->adt;
+                               Lamp *la = (Lamp *)data;
+                               AnimData *adt = la->adt;
                                
-                               ale->flag= FILTER_LAM_OBJD(la);
+                               ale->flag = FILTER_LAM_OBJD(la);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSCAM:
                        {
-                               Camera *ca= (Camera *)data;
-                               AnimData *adt= ca->adt;
+                               Camera *ca = (Camera *)data;
+                               AnimData *adt = ca->adt;
                                
-                               ale->flag= FILTER_CAM_OBJD(ca);
+                               ale->flag = FILTER_CAM_OBJD(ca);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSCUR:
                        {
-                               Curve *cu= (Curve *)data;
-                               AnimData *adt= cu->adt;
+                               Curve *cu = (Curve *)data;
+                               AnimData *adt = cu->adt;
                                
-                               ale->flag= FILTER_CUR_OBJD(cu);
+                               ale->flag = FILTER_CUR_OBJD(cu);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSARM:
                        {
-                               bArmature *arm= (bArmature *)data;
-                               AnimData *adt= arm->adt;
+                               bArmature *arm = (bArmature *)data;
+                               AnimData *adt = arm->adt;
                                
-                               ale->flag= FILTER_ARM_OBJD(arm);
+                               ale->flag = FILTER_ARM_OBJD(arm);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSMESH:
                        {
-                               Mesh *me= (Mesh *)data;
-                               AnimData *adt= me->adt;
+                               Mesh *me = (Mesh *)data;
+                               AnimData *adt = me->adt;
                                
-                               ale->flag= FILTER_MESH_OBJD(me);
+                               ale->flag = FILTER_MESH_OBJD(me);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSLAT:
                        {
-                               Lattice *lt= (Lattice *)data;
-                               AnimData *adt= lt->adt;
+                               Lattice *lt = (Lattice *)data;
+                               AnimData *adt = lt->adt;
                                
-                               ale->flag= FILTER_LATTICE_OBJD(lt);
+                               ale->flag = FILTER_LATTICE_OBJD(lt);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
-                       }       
-                               break;
+                               ale->adt = BKE_animdata_from_id(data);
+                       }
+                       break;
                        case ANIMTYPE_DSSPK:
                        {
-                               Speaker *spk= (Speaker *)data;
-                               AnimData *adt= spk->adt;
-
-                               ale->flag= FILTER_SPK_OBJD(spk);
-
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
-
-                               ale->adt= BKE_animdata_from_id(data);
+                               Speaker *spk = (Speaker *)data;
+                               AnimData *adt = spk->adt;
+                               
+                               ale->flag = FILTER_SPK_OBJD(spk);
+                               
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
+                               
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSSKEY:
                        {
-                               Key *key= (Key *)data;
-                               AnimData *adt= key->adt;
+                               Key *key = (Key *)data;
+                               AnimData *adt = key->adt;
                                
-                               ale->flag= FILTER_SKE_OBJD(key); 
+                               ale->flag = FILTER_SKE_OBJD(key);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSWOR:
                        {
-                               World *wo= (World *)data;
-                               AnimData *adt= wo->adt;
+                               World *wo = (World *)data;
+                               AnimData *adt = wo->adt;
                                
-                               ale->flag= FILTER_WOR_SCED(wo); 
+                               ale->flag = FILTER_WOR_SCED(wo);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSNTREE:
                        {
-                               bNodeTree *ntree= (bNodeTree *)data;
-                               AnimData *adt= ntree->adt;
+                               bNodeTree *ntree = (bNodeTree *)data;
+                               AnimData *adt = ntree->adt;
                                
-                               ale->flag= FILTER_NTREE_DATA(ntree); 
+                               ale->flag = FILTER_NTREE_DATA(ntree);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
+#ifdef WITH_FREESTYLE
                        case ANIMTYPE_DSLINESTYLE:
                        {
-                               FreestyleLineStyle *linestyle= (FreestyleLineStyle *)data;
-                               AnimData *adt= linestyle->adt;
+                               FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
+                               AnimData *adt = linestyle->adt;
                                
-                               ale->flag= FILTER_LS_SCED(linestyle); 
+                               ale->flag = FILTER_LS_SCED(linestyle); 
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
                                break;
+#endif
                        case ANIMTYPE_DSPART:
                        {
-                               ParticleSettings *part= (ParticleSettings*)ale->data;
-                               AnimData *adt= part->adt;
+                               ParticleSettings *part = (ParticleSettings *)ale->data;
+                               AnimData *adt = part->adt;
                                
-                               ale->flag= FILTER_PART_OBJD(part); 
+                               ale->flag = FILTER_PART_OBJD(part);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                        case ANIMTYPE_DSTEX:
                        {
-                               Tex *tex= (Tex *)data;
-                               AnimData *adt= tex->adt;
+                               Tex *tex = (Tex *)data;
+                               AnimData *adt = tex->adt;
                                
-                               ale->flag= FILTER_TEX_DATA(tex); 
+                               ale->flag = FILTER_TEX_DATA(tex);
                                
-                               ale->key_data= (adt) ? adt->action : NULL;
-                               ale->datatype= ALE_ACT;
+                               ale->key_data = (adt) ? adt->action : NULL;
+                               ale->datatype = ALE_ACT;
                                
-                               ale->adt= BKE_animdata_from_id(data);
+                               ale->adt = BKE_animdata_from_id(data);
                        }
-                               break;
+                       break;
                                
                        case ANIMTYPE_GROUP:
                        {
-                               bActionGroup *agrp= (bActionGroup *)data;
+                               bActionGroup *agrp = (bActionGroup *)data;
                                
-                               ale->flag= agrp->flag;
+                               ale->flag = agrp->flag;
                                
-                               ale->key_data= NULL;
-                               ale->datatype= ALE_GROUP;
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_GROUP;
                        }
-                               break;
+                       break;
                        case ANIMTYPE_FCURVE:
                        {
-                               FCurve *fcu= (FCurve *)data;
+                               FCurve *fcu = (FCurve *)data;
                                
-                               ale->flag= fcu->flag;
+                               ale->flag = fcu->flag;
                                
-                               ale->key_data= fcu;
-                               ale->datatype= ALE_FCURVE;
+                               ale->key_data = fcu;
+                               ale->datatype = ALE_FCURVE;
                        }
-                               break;
+                       break;
                                
                        case ANIMTYPE_SHAPEKEY:
                        {
-                               KeyBlock *kb= (KeyBlock *)data;
-                               Key *key= (Key *)ale->id;
+                               KeyBlock *kb = (KeyBlock *)data;
+                               Key *key = (Key *)ale->id;
                                
-                               ale->flag= kb->flag;
+                               ale->flag = kb->flag;
                                
                                /* whether we have keyframes depends on whether there is a Key block to find it from */
                                if (key) {
                                        /* index of shapekey is defined by place in key's list */
-                                       ale->index= BLI_findindex(&key->block, kb);
+                                       ale->index = BLI_findindex(&key->block, kb);
                                        
                                        /* the corresponding keyframes are from the animdata */
                                        if (ale->adt && ale->adt->action) {
-                                               bAction *act= ale->adt->action;
-                                               char *rna_path = key_get_curValue_rnaPath(key, kb);
+                                               bAction *act = ale->adt->action;
+                                               char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
                                                
                                                /* try to find the F-Curve which corresponds to this exactly,
                                                 * then free the MEM_alloc'd string
                                                 */
                                                if (rna_path) {
-                                                       ale->key_data= (void *)list_find_fcurve(&act->curves, rna_path, 0);
+                                                       ale->key_data = (void *)list_find_fcurve(&act->curves, rna_path, 0);
                                                        MEM_freeN(rna_path);
                                                }
                                        }
-                                       ale->datatype= (ale->key_data)? ALE_FCURVE : ALE_NONE;
+                                       ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE;
                                }
-                       }       
-                               break;
+                       }
+                       break;
                        
                        case ANIMTYPE_GPLAYER:
                        {
-                               bGPDlayer *gpl= (bGPDlayer *)data;
+                               bGPDlayer *gpl = (bGPDlayer *)data;
                                
-                               ale->flag= gpl->flag;
+                               ale->flag = gpl->flag;
                                
-                               ale->key_data= NULL;
-                               ale->datatype= ALE_GPFRAME;
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_GPFRAME;
                        }
-                               break;
+                       break;
+                       
+                       case ANIMTYPE_MASKLAYER:
+                       {
+                               MaskLayer *masklay = (MaskLayer *)data;
+                               
+                               ale->flag = masklay->flag;
                                
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_MASKLAY;
+                       }
+                       break;
+                       
                        case ANIMTYPE_NLATRACK:
                        {
-                               NlaTrack *nlt= (NlaTrack *)data;
+                               NlaTrack *nlt = (NlaTrack *)data;
                                
-                               ale->flag= nlt->flag;
+                               ale->flag = nlt->flag;
                                
-                               ale->key_data= &nlt->strips;
-                               ale->datatype= ALE_NLASTRIP;
+                               ale->key_data = &nlt->strips;
+                               ale->datatype = ALE_NLASTRIP;
                        }
-                               break;
+                       break;
                        case ANIMTYPE_NLAACTION:
                        {
                                /* nothing to include for now... nothing editable from NLA-perspective here */
-                               ale->key_data= NULL;
-                               ale->datatype= ALE_NONE;
+                               ale->key_data = NULL;
+                               ale->datatype = ALE_NONE;
                        }
-                               break;
+                       break;
                }
        }
        
@@ -835,13 +878,16 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *own
  
 /* ----------------------------------------- */
 
-/* 'Only Selected' selected data filtering
+/* 'Only Selected' selected data and/or 'Include Hidden' filtering
  * NOTE: when this function returns true, the F-Curve is to be skipped 
  */
-static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
+static short skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
 {
+       /* hidden items should be skipped if we only care about visible data, but we aren't interested in hidden stuff */
+       short skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
+       
        if (GS(owner_id->name) == ID_OB) {
-               Object *ob= (Object *)owner_id;
+               Object *ob = (Object *)owner_id;
                
                /* only consider if F-Curve involves pose.bones */
                if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
@@ -849,24 +895,29 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
                        char *bone_name;
                        
                        /* get bone-name, and check if this bone is selected */
-                       bone_name= BLI_getQuotedStr(fcu->rna_path, "pose.bones[");
-                       pchan= get_pose_channel(ob->pose, bone_name);
+                       bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
+                       pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
                        if (bone_name) MEM_freeN(bone_name);
                        
                        /* check whether to continue or skip */
                        if ((pchan) && (pchan->bone)) {
                                /* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
-                               if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
-                                       bArmature *arm= (bArmature *)ob->data;
+                               if (skip_hidden) {
+                                       bArmature *arm = (bArmature *)ob->data;
                                        
+                                       /* skipping - not visible on currently visible layers */
                                        if ((arm->layer & pchan->bone->layer) == 0)
                                                return 1;
-                                       // TODO: manually hidden using flags
+                                       /* skipping - is currently hidden */
+                                       if (pchan->bone->flag & BONE_HIDDEN_P)
+                                               return 1;
                                }
                                
                                /* can only add this F-Curve if it is selected */
-                               if ((pchan->bone->flag & BONE_SELECTED) == 0)
-                                       return 1;
+                               if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+                                       if ((pchan->bone->flag & BONE_SELECTED) == 0)
+                                               return 1;
+                               }
                        }
                }
        }
@@ -875,36 +926,42 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
                
                /* only consider if F-Curve involves sequence_editor.sequences */
                if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
-                       Editing *ed= seq_give_editing(scene, FALSE);
-                       Sequence *seq;
+                       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+                       Sequence *seq = NULL;
                        char *seq_name;
                        
-                       /* get strip name, and check if this strip is selected */
-                       seq_name= BLI_getQuotedStr(fcu->rna_path, "sequences_all[");
-                       seq = get_seq_by_name(ed->seqbasep, seq_name, FALSE);
-                       if (seq_name) MEM_freeN(seq_name);
+                       if (ed) {
+                               /* get strip name, and check if this strip is selected */
+                               seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
+                               seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, FALSE);
+                               if (seq_name) MEM_freeN(seq_name);
+                       }
                        
                        /* can only add this F-Curve if it is selected */
-                       if (seq==NULL || (seq->flag & SELECT)==0)
-                               return 1;
+                       if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+                               if ((seq == NULL) || (seq->flag & SELECT) == 0)
+                                       return 1;
+                       }
                }
        }
        else if (GS(owner_id->name) == ID_NT) {
                bNodeTree *ntree = (bNodeTree *)owner_id;
                
-               /* check for selected  nodes */
+               /* check for selected nodes */
                if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
                        bNode *node;
                        char *node_name;
                        
                        /* get strip name, and check if this strip is selected */
-                       node_name= BLI_getQuotedStr(fcu->rna_path, "nodes[");
+                       node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
                        node = nodeFindNodebyName(ntree, node_name);
                        if (node_name) MEM_freeN(node_name);
                        
                        /* can only add this F-Curve if it is selected */
-                       if ((node) && (node->flag & NODE_SELECT)==0)
-                               return 1;
+                       if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+                               if ((node) && (node->flag & NODE_SELECT) == 0)
+                                       return 1;
+                       }
                }
        }
        return 0;
@@ -913,7 +970,7 @@ static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner
 /* (Display-)Name-based F-Curve filtering
  * NOTE: when this function returns true, the F-Curve is to be skipped 
  */
-static short skip_fcurve_with_name (bDopeSheet *ads, FCurve *fcu, ID *owner_id)
+static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id)
 {
        bAnimListElem ale_dummy = {NULL};
        bAnimChannelType *acf;
@@ -941,26 +998,66 @@ static short skip_fcurve_with_name (bDopeSheet *ads, FCurve *fcu, ID *owner_id)
        return 1;
 }
 
+/* Check if F-Curve has errors and/or is disabled 
+ * > returns: (bool) True if F-Curve has errors/is disabled
+ */
+static bool fcurve_has_errors(FCurve *fcu)
+{
+       /* F-Curve disabled - path eval error */
+       if (fcu->flag & FCURVE_DISABLED) {
+               return true;
+       }
+       
+       /* driver? */
+       if (fcu->driver) {
+               ChannelDriver *driver = fcu->driver;
+               DriverVar *dvar;
+               
+               /* error flag on driver usually means that there is an error
+                * BUT this may not hold with PyDrivers as this flag gets cleared
+                *     if no critical errors prevent the driver from working...
+                */
+               if (driver->flag & DRIVER_FLAG_INVALID)
+                       return true;
+                       
+               /* check variables for other things that need linting... */
+               // TODO: maybe it would be more efficient just to have a quick flag for this?
+               for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+                       DRIVER_TARGETS_USED_LOOPER(dvar)
+                       {
+                               if (dtar->flag & DTAR_FLAG_INVALID)
+                                       return true;
+                       }
+                       DRIVER_TARGETS_LOOPER_END
+               }
+       }
+       
+       /* no errors found */
+       return false;
+}
+
 /* find the next F-Curve that is usable for inclusion */
-static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
+static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
 {
        FCurve *fcu = NULL;
        
        /* loop over F-Curves - assume that the caller of this has already checked that these should be included 
         * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
         */
-       for (fcu= first; ((fcu) && (fcu->grp==grp)); fcu= fcu->next) {
+       for (fcu = first; ((fcu) && (fcu->grp == grp)); fcu = fcu->next) {
                /* special exception for Pose-Channel/Sequence-Strip/Node Based F-Curves:
-                *      - the 'Only Selected' data filter should be applied to Pose-Channel data too, but those are
-                *        represented as F-Curves. The way the filter for objects worked was to be the first check
-                *        after 'normal' visibility, so this is done first here too...
+                *      - the 'Only Selected' and 'Include Hidden' data filters should be applied to sub-ID data which
+                *        can be independently selected/hidden, such as Pose-Channels, Sequence Strips, and Nodes.
+                *        Since these checks were traditionally done as first check for objects, we do the same here
                 *      - we currently use an 'approximate' method for getting these F-Curves that doesn't require
                 *        carefully checking the entire path
                 *      - this will also affect things like Drivers, and also works for Bone Constraints
                 */
-               if ( ((ads) && (ads->filterflag & ADS_FILTER_ONLYSEL)) && (owner_id) ) {
-                       if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
-                               continue;
+               if (ads && owner_id) {
+                       if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN) == 0) {
+                               if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
+                                       continue;
+                       }
                }
                
                /* only include if visible (Graph Editor check, not channels check) */
@@ -968,7 +1065,7 @@ static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGr
                        /* only work with this channel and its subchannels if it is editable */
                        if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
                                /* only include this curve if selected in a way consistent with the filtering requirements */
-                               if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu)) ) {
+                               if (ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu))) {
                                        /* only include if this curve is active */
                                        if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
                                                /* name based filtering... */
@@ -977,6 +1074,13 @@ static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGr
                                                                continue;
                                                }
                                                
+                                               /* error-based filtering... */
+                                               if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
+                                                       /* skip if no errors... */
+                                                       if (fcurve_has_errors(fcu) == false)
+                                                               continue;
+                                               }
+                                               
                                                /* this F-Curve can be used, so return it */
                                                return fcu;
                                        }
@@ -989,7 +1093,7 @@ static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGr
        return NULL;
 }
 
-static size_t animfilter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
+static size_t animfilter_fcurves(ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
 {
        FCurve *fcu;
        size_t items = 0;
@@ -1003,8 +1107,7 @@ static size_t animfilter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *
         *              4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through 
         *                 the rest of the F-Curve list without an eternal loop. Back to step 2 :)
         */
-       for (fcu=first; ( (fcu = animfilter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next)
-       {
+       for (fcu = first; ( (fcu = animfilter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu = fcu->next) {
                ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id);
        }
        
@@ -1012,7 +1115,7 @@ static size_t animfilter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *
        return items;
 }
 
-static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *UNUSED(act), bActionGroup *agrp, int filter_mode, ID *owner_id)
+static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *UNUSED(act), bActionGroup *agrp, int filter_mode, ID *owner_id)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
@@ -1021,12 +1124,12 @@ static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDope
        
        /* if we care about the selection status of the channels, 
         * but the group isn't expanded (1)...
-        *      (1) this only matters if we actually care about the hierarchy though.
+        *  (1) this only matters if we actually care about the hierarchy though.
         *              - Hierarchy matters: this hack should be applied
         *              - Hierarchy ignored: cases like [#21276] won't work properly, unless we skip this hack
         */
-       if ( ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp)==0) &&         /* care about hierarchy but group isn't expanded */
-                 (filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) )                                                   /* care about selection status */        
+       if ( ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp) == 0) &&     /* care about hierarchy but group isn't expanded */
+            (filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) )                          /* care about selection status */
        {
                /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
                if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
@@ -1040,7 +1143,7 @@ static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDope
                 *      - pasting keyframes
                 *      - creating ghost curves in Graph Editor
                 */
-               filter_mode &= ~(ANIMFILTER_SEL|ANIMFILTER_UNSEL|ANIMFILTER_LIST_VISIBLE);
+               filter_mode &= ~(ANIMFILTER_SEL | ANIMFILTER_UNSEL | ANIMFILTER_LIST_VISIBLE);
        }
        
        /* add grouped F-Curves */
@@ -1052,8 +1155,7 @@ static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDope
                         * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing 
                         * all its sub-curves to be shown
                         */
-                       if ( !(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) )
-                       {
+                       if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE)) {
                                /* group must be editable for its children to be editable (if we care about this) */
                                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
                                        /* get first F-Curve which can be used here */
@@ -1075,7 +1177,7 @@ static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDope
                        //filter_mode = ofilter;
                        
                        /* filter selection of channel specially here again, since may be open and not subject to previous test */
-                       if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
+                       if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
                                ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id);
                        }
                }
@@ -1090,7 +1192,7 @@ static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDope
        return items;
 }
 
-static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
+static size_t animfilter_action(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
 {
        bActionGroup *agrp;
        FCurve *lastchan = NULL;
@@ -1099,7 +1201,6 @@ static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeShe
        /* don't include anything from this action if it is linked in from another file,
         * and we're getting stuff for editing...
         */
-       // TODO: need a way of tagging other channels that may also be affected...
        if ((filter_mode & ANIMFILTER_FOREDIT) && (act->id.lib))
                return 0;
                
@@ -1108,15 +1209,15 @@ static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeShe
        for (agrp = act->groups.first; agrp; agrp = agrp->next) {
                /* store reference to last channel of group */
                if (agrp->channels.last) 
-                       lastchan= agrp->channels.last;
+                       lastchan = agrp->channels.last;
                        
                /* action group's channels */
                items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
        }
        
        /* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
-       if (!(filter_mode & ANIMFILTER_ACTGROUPED))  {
-               FCurve *firstfcu = (lastchan)? (lastchan->next) : (act->curves.first);
+       if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
+               FCurve *firstfcu = (lastchan) ? (lastchan->next) : (act->curves.first);
                items += animfilter_fcurves(anim_data, ads, firstfcu, NULL, filter_mode, owner_id);
        }
        
@@ -1132,10 +1233,10 @@ static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeShe
  *     - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation
  *       order, i.e. first to last. Otherwise, some tools may get screwed up.
  */
-static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
+static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
 {
        NlaTrack *nlt;
-       NlaTrack *first=NULL, *next=NULL;
+       NlaTrack *first = NULL, *next = NULL;
        size_t items = 0;
        
        /* if showing channels, include active action */
@@ -1145,33 +1246,33 @@ static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDo
                 */
                if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
                        /* there isn't really anything editable here, so skip if need editable */
-                       if ((filter_mode & ANIMFILTER_FOREDIT) == 0) { 
+                       if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
                                /* just add the action track now (this MUST appear for drawing)
                                 *      - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
                                 *        overwrite this with the real value - REVIEW THIS...
                                 */
                                ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id, 
                                        {
-                                               ale->data= adt->action ? adt->action : NULL; 
+                                               ale->data = adt->action ? adt->action : NULL; 
                                        });
                        }
                }
                
                /* first track to include will be the last one if we're filtering by channels */
-               first= adt->nla_tracks.last;
+               first = adt->nla_tracks.last;
        }
        else {
                /* first track to include will the the first one (as per normal) */
-               first= adt->nla_tracks.first;
+               first = adt->nla_tracks.first;
        }
        
        /* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
-       for (nlt= first; nlt; nlt= next) {
+       for (nlt = first; nlt; nlt = next) {
                /* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) 
-                       next= nlt->prev;
+                       next = nlt->prev;
                else
-                       next= nlt->next;
+                       next = nlt->next;
                
                /* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now 
                 *      - active track should still get shown though (even though it has disabled flag set)
@@ -1183,7 +1284,7 @@ static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDo
                /* only work with this channel and its subchannels if it is editable */
                if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
                        /* only include this track if selected in a way consistent with the filtering requirements */
-                       if ( ANIMCHANNEL_SELOK(SEL_NLT(nlt)) ) {
+                       if (ANIMCHANNEL_SELOK(SEL_NLT(nlt))) {
                                /* only include if this track is active */
                                if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
                                        ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id);
@@ -1197,15 +1298,15 @@ static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDo
 }
 
 /* determine what animation data from AnimData block should get displayed */
-static size_t animfilter_block_data (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
+static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
 {
        AnimData *adt = BKE_animdata_from_id(id);
        size_t items = 0;
-
+       
        /* image object datablocks have no anim-data so check for NULL */
-       if(adt) {
-               IdAdtTemplate *iat = (IdAdtTemplate*)id;
-
+       if (adt) {
+               IdAdtTemplate *iat = (IdAdtTemplate *)id;
+               
                /* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
                 * in a few places in he rest of the code still - notably for the few cases where special mode-based
                 * different types of data expanders are required.
@@ -1213,7 +1314,9 @@ static size_t animfilter_block_data (bAnimContext *ac, ListBase *anim_data, bDop
                ANIMDATA_FILTER_CASES(iat,
                        { /* AnimData */
                                /* specifically filter animdata block */
-                               ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+                               if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) {
+                                       ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+                               }
                        },
                        { /* NLA */
                                items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
@@ -1226,14 +1329,14 @@ static size_t animfilter_block_data (bAnimContext *ac, ListBase *anim_data, bDop
                        }
                );
        }
-
+       
        return items;
 }
 
 
 
 /* Include ShapeKey Data for ShapeKey Editor */
-static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
+static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
 {
        size_t items = 0;
        
@@ -1242,15 +1345,14 @@ static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, K
                KeyBlock *kb;
                
                /* loop through the channels adding ShapeKeys as appropriate */
-               for (kb= key->block.first; kb; kb= kb->next) {
-                       /* skip the first one, since that's the non-animateable basis */
-                       // XXX maybe in future this may become handy?
+               for (kb = key->block.first; kb; kb = kb->next) {
+                       /* skip the first one, since that's the non-animatable basis */
                        if (kb == key->block.first) continue;
                        
                        /* only work with this channel and its subchannels if it is editable */
                        if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
                                /* only include this track if selected in a way consistent with the filtering requirements */
-                               if ( ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
+                               if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
                                        // TODO: consider 'active' too?
                                        
                                        /* owner-id here must be key so that the F-Curve can be resolved... */
@@ -1264,10 +1366,12 @@ static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, K
                // TODO: somehow manage to pass dopesheet info down here too?
                if (key->adt) {
                        if (filter_mode & ANIMFILTER_ANIMDATA) {
-                               ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+                               if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) {
+                                       ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+                               }
                        }
                        else if (key->adt->action) {
-                               items= animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
+                               items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
                        }
                }
        }
@@ -1276,15 +1380,16 @@ static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, K
        return items;
 }
 
-static size_t animdata_filter_gpencil_data (ListBase *anim_data, bGPdata *gpd, int filter_mode)
+/* Helper for Grease Pencil - layers within a datablock */
+static size_t animdata_filter_gpencil_data(ListBase *anim_data, bGPdata *gpd, int filter_mode)
 {
        bGPDlayer *gpl;
        size_t items = 0;
        
        /* loop over layers as the conditions are acceptable */
-       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+       for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
                /* only if selected */
-               if ( ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
+               if (ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
                        /* only if editable */
                        if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
                                /* active... */
@@ -1299,9 +1404,9 @@ static size_t animdata_filter_gpencil_data (ListBase *anim_data, bGPdata *gpd, i
        return items;
 }
 
-/* Grab all Grase Pencil datablocks in file */
+/* Grab all Grease Pencil datablocks in file */
 // TODO: should this be amalgamated with the dopesheet filtering code?
-static size_t animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int filter_mode)
+static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), int filter_mode)
 {
        bGPdata *gpd;
        size_t items = 0;
@@ -1342,9 +1447,76 @@ static size_t animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data),
        return items;
 }
 
+/* Helper for Mask Editing - mask layers */
+static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode)
+{
+       MaskLayer *masklay_act = BKE_mask_layer_active(mask);
+       MaskLayer *masklay;
+       size_t items = 0;
+
+       /* loop over layers as the conditions are acceptable */
+       for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+               /* only if selected */
+               if (ANIMCHANNEL_SELOK(SEL_MASKLAY(masklay)) ) {
+                       /* only if editable */
+                       if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_MASK(masklay)) {
+                               /* active... */
+                               if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) {
+                                       /* add to list */
+                                       ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask);
+                               }
+                       }
+               }
+       }
+
+       return items;
+}
+
+/* Grab all mask data */
+static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode)
+{
+       Mask *mask;
+       size_t items = 0;
+       
+       /* for now, grab mask datablocks directly from main */
+       // XXX: this is not good...
+       for (mask = G.main->mask.first; mask; mask = mask->id.next) {
+               ListBase tmp_data = {NULL, NULL};
+               size_t tmp_items = 0;
+               
+               /* only show if mask is used by something... */
+               if (ID_REAL_USERS(mask) < 1)
+                       continue;
+               
+               /* add mask animation channels */
+               BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
+               {
+                       tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);
+               }
+               END_ANIMFILTER_SUBCHANNELS;
+               
+               /* did we find anything? */
+               if (tmp_items) {
+                       /* include data-expand widget first */
+                       if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+                               /* add gpd as channel too (if for drawing, and it has layers) */
+                               ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL);
+                       }
+                       
+                       /* now add the list of collected channels */
+                       BLI_movelisttolist(anim_data, &tmp_data);
+                       BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
+                       items += tmp_items;
+               }
+       }
+       
+       /* return the number of items added to the list */
+       return items;
+}
+
 /* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */
 // TODO: how to handle group nodes is still unclear...
-static size_t animdata_filter_ds_nodetree (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
+static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
@@ -1363,7 +1535,7 @@ static size_t animdata_filter_ds_nodetree (bAnimContext *ac, ListBase *anim_data
                /* include data-expand widget first */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                        /* check if filtering by active status */
-                       if ANIMCHANNEL_ACTIVEOK(ntree) {
+                       if (ANIMCHANNEL_ACTIVEOK(ntree)) {
                                ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id);
                        }
                }
@@ -1378,12 +1550,13 @@ static size_t animdata_filter_ds_nodetree (bAnimContext *ac, ListBase *anim_data
        return items;
 }
 
+#ifdef WITH_FREESTYLE
 static size_t animdata_filter_ds_linestyle (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
 {
        SceneRenderLayer *srl;
        size_t items = 0;
 
-       for (srl= sce->r.layers.first; srl; srl= srl->next) {
+       for (srl = sce->r.layers.first; srl; srl = srl->next) {
                FreestyleLineSet *lineset;
 
                /* skip render layers without Freestyle enabled */
@@ -1391,7 +1564,7 @@ static size_t animdata_filter_ds_linestyle (bAnimContext *ac, ListBase *anim_dat
                        continue;
 
                /* loop over linesets defined in the render layer */
-               for (lineset= srl->freestyleConfig.linesets.first; lineset; lineset= lineset->next) {
+               for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
                        FreestyleLineStyle *linestyle = lineset->linestyle;
                        ListBase tmp_data = {NULL, NULL};
                        size_t tmp_items = 0;
@@ -1425,13 +1598,14 @@ static size_t animdata_filter_ds_linestyle (bAnimContext *ac, ListBase *anim_dat
        /* return the number of items added to the list */
        return items;
 }
+#endif
 
 /* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */
-static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
+static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
 {
        MTex **mtex = NULL;
-       size_t items=0;
-       int a=0;
+       size_t items = 0;
+       int a = 0;
        
        /* get datatype specific data first */
        if (owner_id == NULL)
@@ -1440,34 +1614,34 @@ static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data
        switch (GS(owner_id->name)) {
                case ID_MA:
                {
-                       Material *ma= (Material *)owner_id;
-                       mtex= (MTex**)(&ma->mtex);
+                       Material *ma = (Material *)owner_id;
+                       mtex = (MTex **)(&ma->mtex);
                }
-                       break;
+               break;
                case ID_LA:
                {
-                       Lamp *la= (Lamp *)owner_id;
-                       mtex= (MTex**)(&la->mtex);
+                       Lamp *la = (Lamp *)owner_id;
+                       mtex = (MTex **)(&la->mtex);
                }
-                       break;
+               break;
                case ID_WO:
                {
-                       World *wo= (World *)owner_id;
-                       mtex= (MTex**)(&wo->mtex);
+                       World *wo = (World *)owner_id;
+                       mtex = (MTex **)(&wo->mtex);
                }
-                       break;
+               break;
                default: 
                {
                        /* invalid/unsupported option */
-                       if (G.f & G_DEBUG)
-                               printf("ERROR: unsupported owner_id (i.e. texture stack) for filter textures - %s \n", owner_id->name);
+                       if (G.debug & G_DEBUG)
+                               printf("ERROR: unsupported owner_id (i.e. texture stack) for filter textures - %s\n", owner_id->name);
                        return 0;
                }
        }
        
        /* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
-       for (a=0; a < MAX_MTEX; a++) {
-               Tex *tex= (mtex[a]) ? mtex[a]->tex : NULL;
+       for (a = 0; a < MAX_MTEX; a++) {
+               Tex *tex = (mtex[a]) ? mtex[a]->tex : NULL;
                ListBase tmp_data = {NULL, NULL};
                size_t tmp_items = 0;
                
@@ -1496,7 +1670,7 @@ static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data
                        /* include texture-expand widget? */
                        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                                /* check if filtering by active status */
-                               if ANIMCHANNEL_ACTIVEOK(tex) {
+                               if (ANIMCHANNEL_ACTIVEOK(tex)) {
                                        ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id);
                                }
                        }
@@ -1512,51 +1686,82 @@ static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data
        return items;
 }
 
-static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+
+static size_t animdata_filter_ds_material(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode)
 {
-       size_t items=0;
-       int a=0;
+       ListBase tmp_data = {NULL, NULL};
+       size_t tmp_items = 0;
+       size_t items = 0;
        
-       /* firstly check that we actuallly have some materials, by gathering all materials in a temp list */
-       for (a=1; a <= ob->totcol; a++) {
-               Material *ma= give_current_material(ob, a);
-               ListBase tmp_data = {NULL, NULL};
-               size_t tmp_items = 0;
+       /* add material's animation data to temp collection */
+       BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
+       {
+               /* material's animation data */
+               tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
+                       
+               /* textures */
+               if (!(ads->filterflag & ADS_FILTER_NOTEX))
+                       tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode);
+                       
+               /* nodes */
+               if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
+                       tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
+       }
+       END_ANIMFILTER_SUBCHANNELS;
+       
+       /* did we find anything? */
+       if (tmp_items) {
+               /* include material-expand widget first */
+               if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+                       /* check if filtering by active status */
+                       if (ANIMCHANNEL_ACTIVEOK(ma)) {
+                               ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
+                       }
+               }
                
-               /* if no material returned, skip - so that we don't get weird blank entries... */
-               if (ma == NULL) continue;
+               /* now add the list of collected channels */
+               BLI_movelisttolist(anim_data, &tmp_data);
+               BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
+               items += tmp_items;
+       }
+       
+       return items;
+}
+
+static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+{
+       short has_nested = 0;
+       size_t items = 0;
+       int a = 0;
+       
+       /* first pass: take the materials referenced via the Material slots of the object */
+       for (a = 1; a <= ob->totcol; a++) {
+               Material *ma = give_current_material(ob, a);
                
-               /* add material's animation data to temp collection */
-               BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
-               {
-                       /* material's animation data */
-                       tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-                               
-                       /* textures */
-                       if (!(ads->filterflag & ADS_FILTER_NOTEX))
-                               tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-                               
-                       /* nodes */
-                       if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) 
-                               tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
+               /* if material is valid, try to add relevant contents from here */
+               if (ma) {
+                       /* add channels */
+                       items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+                       
+                       /* for optimising second pass - check if there's a nested material here to come back for */
+                       if (has_nested == 0)
+                               has_nested = give_node_material(ma) != NULL;
                }
-               END_ANIMFILTER_SUBCHANNELS;
-               
-               /* did we find anything? */
-               if (tmp_items) {
-                       /* include material-expand widget first */
-                       // hmm... do we need to store the index of this material in the array anywhere?
-                       if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
-                               /* check if filtering by active status */
-                               if ANIMCHANNEL_ACTIVEOK(ma) {
-                                       ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
-                               }
-                       }
+       }
+       
+       /* second pass: go through a second time looking for "nested" materials (material.material references)
+        *
+        * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
+        *       disappearing/not available, since the relationships between these is not that clear
+        */
+       if (has_nested) {
+               for (a = 1; a <= ob->totcol; a++) {
+                       Material *base = give_current_material(ob, a);
+                       Material *ma   = give_node_material(base);
                        
-                       /* now add the list of collected channels */
-                       BLI_movelisttolist(anim_data, &tmp_data);
-                       BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL));
-                       items += tmp_items;
+                       /* add channels from the nested material if it exists */
+                       if (ma)
+                               items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
                }
        }
        
@@ -1564,12 +1769,12 @@ static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_dat
        return items;
 }
 
-static size_t animdata_filter_ds_particles (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 {
        ParticleSystem *psys;
-       size_t items= 0;
+       size_t items = 0;
 
-       for (psys = ob->particlesystem.first; psys; psys=psys->next) {
+       for (psys = ob->particlesystem.first; psys; psys = psys->next) {
                ListBase tmp_data = {NULL, NULL};
                size_t tmp_items = 0;
                
@@ -1590,7 +1795,7 @@ static size_t animdata_filter_ds_particles (bAnimContext *ac, ListBase *anim_dat
                        /* include particle-expand widget first */
                        if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                                /* check if filtering by active status */
-                               if ANIMCHANNEL_ACTIVEOK(psys->part) {
+                               if (ANIMCHANNEL_ACTIVEOK(psys->part)) {
                                        ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part);
                                }
                        }
@@ -1606,85 +1811,85 @@ static size_t animdata_filter_ds_particles (bAnimContext *ac, ListBase *anim_dat
        return items;
 }
 
-static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
-       size_t items= 0;
+       size_t items = 0;
        
-       IdAdtTemplate *iat= ob->data;
-       short type=0, expanded=0;
+       IdAdtTemplate *iat = ob->data;
+       short type = 0, expanded = 0;
        
        /* get settings based on data type */
        switch (ob->type) {
                case OB_CAMERA: /* ------- Camera ------------ */
                {
-                       Camera *ca= (Camera *)ob->data;
+                       Camera *ca = (Camera *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOCAM)
                                return 0;
                        
-                       type= ANIMTYPE_DSCAM;
-                       expanded= FILTER_CAM_OBJD(ca);
+                       type = ANIMTYPE_DSCAM;
+                       expanded = FILTER_CAM_OBJD(ca);
                }
-                       break;
+               break;
                case OB_LAMP: /* ---------- Lamp ----------- */
                {
-                       Lamp *la= (Lamp *)ob->data;
+                       Lamp *la = (Lamp *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOLAM)
                                return 0;
                        
-                       type= ANIMTYPE_DSLAM;
-                       expanded= FILTER_LAM_OBJD(la);
+                       type = ANIMTYPE_DSLAM;
+                       expanded = FILTER_LAM_OBJD(la);
                }
-                       break;
+               break;
                case OB_CURVE: /* ------- Curve ---------- */
                case OB_SURF: /* ------- Nurbs Surface ---------- */
                case OB_FONT: /* ------- Text Curve ---------- */
                {
-                       Curve *cu= (Curve *)ob->data;
+                       Curve *cu = (Curve *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOCUR)
                                return 0;
                        
-                       type= ANIMTYPE_DSCUR;
-                       expanded= FILTER_CUR_OBJD(cu);
+                       type = ANIMTYPE_DSCUR;
+                       expanded = FILTER_CUR_OBJD(cu);
                }
-                       break;
+               break;
                case OB_MBALL: /* ------- MetaBall ---------- */
                {
-                       MetaBall *mb= (MetaBall *)ob->data;
+                       MetaBall *mb = (MetaBall *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOMBA)
                                return 0;
                        
-                       type= ANIMTYPE_DSMBALL;
-                       expanded= FILTER_MBALL_OBJD(mb);
+                       type = ANIMTYPE_DSMBALL;
+                       expanded = FILTER_MBALL_OBJD(mb);
                }
-                       break;
+               break;
                case OB_ARMATURE: /* ------- Armature ---------- */
                {
-                       bArmature *arm= (bArmature *)ob->data;
+                       bArmature *arm = (bArmature *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOARM)
                                return 0;
                        
-                       type= ANIMTYPE_DSARM;
-                       expanded= FILTER_ARM_OBJD(arm);
+                       type = ANIMTYPE_DSARM;
+                       expanded = FILTER_ARM_OBJD(arm);
                }
-                       break;
+               break;
                case OB_MESH: /* ------- Mesh ---------- */
                {
-                       Mesh *me= (Mesh *)ob->data;
+                       Mesh *me = (Mesh *)ob->data;
                        
                        if (ads->filterflag & ADS_FILTER_NOMESH)
                                return 0;
                        
-                       type= ANIMTYPE_DSMESH;
-                       expanded= FILTER_MESH_OBJD(me);
+                       type = ANIMTYPE_DSMESH;
+                       expanded = FILTER_MESH_OBJD(me);
                }
-                       break;
+               break;
                case OB_LATTICE: /* ---- Lattice ---- */
                {
                        Lattice *lt = (Lattice *)ob->data;
@@ -1692,18 +1897,18 @@ static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data,
                        if (ads->filterflag & ADS_FILTER_NOLAT)
                                return 0;
                        
-                       type= ANIMTYPE_DSLAT;
-                       expanded= FILTER_LATTICE_OBJD(lt);
+                       type = ANIMTYPE_DSLAT;
+                       expanded = FILTER_LATTICE_OBJD(lt);
                }
-                       break;
+               break;
                case OB_SPEAKER: /* ---------- Speaker ----------- */
                {
-                       Speaker *spk= (Speaker *)ob->data;
+                       Speaker *spk = (Speaker *)ob->data;
                        
-                       type= ANIMTYPE_DSSPK;
-                       expanded= FILTER_SPK_OBJD(spk);
+                       type = ANIMTYPE_DSSPK;
+                       expanded = FILTER_SPK_OBJD(spk);
                }
-                       break;
+               break;
        }
        
        /* add object data animation channels */
@@ -1714,13 +1919,20 @@ static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data,
                
                /* sub-data filtering... */
                switch (ob->type) {
-                       case OB_LAMP:   /* lamp - textures */
+                       case OB_LAMP:  /* lamp - textures + nodetree */
                        {
+                               Lamp *la = ob->data;
+                               bNodeTree *ntree = la->nodetree;
+                               
+                               /* nodetree */
+                               if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+                                       tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, &la->id, ntree, filter_mode);
+                               
                                /* textures */
                                if (!(ads->filterflag & ADS_FILTER_NOTEX))
-                                       tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, ob->data, filter_mode);
+                                       tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, &la->id, filter_mode);
                        }
-                               break;
+                       break;
                }
        }
        END_ANIMFILTER_SUBCHANNELS;
@@ -1730,7 +1942,7 @@ static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data,
                /* include data-expand widget first */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                        /* check if filtering by active status */
-                       if ANIMCHANNEL_ACTIVEOK(iat) {
+                       if (ANIMCHANNEL_ACTIVEOK(iat)) {
                                ANIMCHANNEL_NEW_CHANNEL(iat, type, iat);
                        }
                }
@@ -1746,7 +1958,7 @@ static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data,
 }
 
 /* shapekey-level animation */
-static size_t animdata_filter_ds_keyanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
+static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
@@ -1764,7 +1976,7 @@ static size_t animdata_filter_ds_keyanim (bAnimContext *ac, ListBase *anim_data,
        if (tmp_items) {
                /* include key-expand widget first */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
-                       if ANIMCHANNEL_ACTIVEOK(key) {
+                       if (ANIMCHANNEL_ACTIVEOK(key)) {
                                ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob);
                        }
                }
@@ -1780,27 +1992,27 @@ static size_t animdata_filter_ds_keyanim (bAnimContext *ac, ListBase *anim_data,
 }
 
 /* object-level animation */
-static size_t animdata_filter_ds_obanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
        size_t items = 0;
        
        AnimData *adt = ob->adt;
-       short type=0, expanded=1;
+       short type = 0, expanded = 1;
        void *cdata = NULL;
-       
+
        /* determine the type of expander channels to use */
-       // this is the best way to do this for now...
+       /* this is the best way to do this for now... */
        ANIMDATA_FILTER_CASES(ob,
-               {/* AnimData - no channel, but consider data */},
-               {/* NLA - no channel, but consider data */},
-               {/* Drivers */
+               { /* AnimData - no channel, but consider data */ },
+               { /* NLA - no channel, but consider data */ },
+               { /* Drivers */
                        type = ANIMTYPE_FILLDRIVERS;
                        cdata = adt;
                        expanded = EXPANDED_DRVD(adt);
                },
-               {/* Keyframes */
+               { /* Keyframes */
                        type = ANIMTYPE_FILLACTD;
                        cdata = adt->action;
                        expanded = EXPANDED_ACTC(adt->action);
@@ -1835,17 +2047,17 @@ static size_t animdata_filter_ds_obanim (bAnimContext *ac, ListBase *anim_data,
 }
 
 /* get animation channels from object2 */
-static size_t animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
-       Object *ob= base->object;
+       Object *ob = base->object;
        size_t tmp_items = 0;
        size_t items = 0;
        
        /* filter data contained under object first */
        BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
        {
-               Key *key= ob_get_key(ob);
+               Key *key = BKE_key_from_object(ob);
                
                /* object-level animation */
                if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
@@ -1881,7 +2093,7 @@ static size_t animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_dat
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                        /* check if filtering by selection */
                        // XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
-                       if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
+                       if (ANIMCHANNEL_SELOK((base->flag & SELECT))) {
                                /* check if filtering by active status */
                                if (ANIMCHANNEL_ACTIVEOK(ob)) {
                                        ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob);
@@ -1899,7 +2111,7 @@ static size_t animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_dat
        return items;
 }
 
-static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
+static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
@@ -1926,7 +2138,7 @@ static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, b
                /* include data-expand widget first */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                        /* check if filtering by active status */
-                       if ANIMCHANNEL_ACTIVEOK(wo) {
+                       if (ANIMCHANNEL_ACTIVEOK(wo)) {
                                ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce);
                        }
                }
@@ -1941,27 +2153,27 @@ static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, b
        return items;
 }
 
-static size_t animdata_filter_ds_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
        size_t items = 0;
        
        AnimData *adt = sce->adt;
-       short type=0, expanded=1;
+       short type = 0, expanded = 1;
        void *cdata = NULL;
        
        /* determine the type of expander channels to use */
        // this is the best way to do this for now...
        ANIMDATA_FILTER_CASES(sce,
-               {/* AnimData - no channel, but consider data */},
-               {/* NLA - no channel, but consider data */},
-               {/* Drivers */
+               { /* AnimData - no channel, but consider data */},
+               { /* NLA - no channel, but consider data */},
+               { /* Drivers */
                        type = ANIMTYPE_FILLDRIVERS;
                        cdata = adt;
                        expanded = EXPANDED_DRVD(adt);
                },
-               {/* Keyframes */
+               { /* Keyframes */
                        type = ANIMTYPE_FILLACTD;
                        cdata = adt->action;
                        expanded = EXPANDED_ACTC(adt->action);
@@ -1995,7 +2207,7 @@ static size_t animdata_filter_ds_scene (bAnimContext *ac, ListBase *anim_data, b
        return items;
 }
 
-static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
 {
        ListBase tmp_data = {NULL, NULL};
        size_t tmp_items = 0;
@@ -2004,8 +2216,8 @@ static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_
        /* filter data contained under object first */
        BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
        {
-               bNodeTree *ntree= sce->nodetree;
-               World *wo= sce->world;
+               bNodeTree *ntree = sce->nodetree;
+               World *wo = sce->world;
                
                /* Action, Drivers, or NLA for Scene */
                if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
@@ -2021,22 +2233,24 @@ static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_
                if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
                        tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
                }
-
+               
+#ifdef WITH_FREESTYLE
                /* line styles */
                if ((ads->filterflag & ADS_FILTER_NOLINESTYLE) == 0) {
                        tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode);
                }
+#endif
                
-               // TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here
+               /* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
        }
        END_ANIMFILTER_SUBCHANNELS;
-       
+
        /* if we collected some channels, add these to the new list... */
        if (tmp_items) {
                /* firstly add object expander if required */
                if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
                        /* check if filtering by selection */
-                       if ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED)) {
+                       if (ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED))) {
                                /* NOTE: active-status doesn't matter for this! */
                                ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce);
                        }
@@ -2053,17 +2267,17 @@ static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_
 }
 
 // TODO: implement pinning... (if and when pinning is done, what we need to do is to provide freeing mechanisms - to protect against data that was deleted)
-static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
+static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
 {
-       Scene *sce= (Scene *)ads->source;
+       Scene *sce = (Scene *)ads->source;
        Base *base;
        size_t items = 0;
        
        /* check that we do indeed have a scene */
-       if ((ads->source == NULL) || (GS(ads->source->name)!=ID_SCE)) {
+       if ((ads->source == NULL) || (GS(ads->source->name) != ID_SCE)) {
                printf("DopeSheet Error: Not scene!\n");
-               if (G.f & G_DEBUG)
-                       printf("\tPointer = %p, Name = '%s' \n", (void *)ads->source, (ads->source)?ads->source->name:NULL);
+               if (G.debug & G_DEBUG)
+                       printf("\tPointer = %p, Name = '%s'\n", (void *)ads->source, (ads->source) ? ads->source->name : NULL);
                return 0;
        }
        
@@ -2079,10 +2293,10 @@ static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data,
        items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode);
        
        /* loop over all bases (i.e.objects) in the scene */
-       for (base= sce->base.first; base; base= base->next) {
+       for (base = sce->base.first; base; base = base->next) {
                /* check if there's an object (all the relevant checks are done in the ob-function) */
                if (base->object) {
-                       Object *ob= base->object;
+                       Object *ob = base->object;
                        
                        /* firstly, check if object can be included, by the following factors:
                         *      - if only visible, must check for layer and also viewport visibility
@@ -2095,7 +2309,7 @@ static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data,
                         */
                        if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
                                /* layer visibility - we check both object and base, since these may not be in sync yet */
-                               if ((sce->lay & (ob->lay|base->lay))==0) continue;
+                               if ((sce->lay & (ob->lay | base->lay)) == 0) continue;
                                
                                /* outliner restrict-flag */
                                if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
@@ -2110,7 +2324,7 @@ static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data,
                        }
                        
                        /* check selection and object type filters */
-                       if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) )  {
+                       if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) ) {
                                /* only selected should be shown */
                                continue;
                        }
@@ -2134,9 +2348,9 @@ static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data,
 }
 
 /* Summary track for DopeSheet/Action Editor 
- *     - return code is whether the summary lets the other channels get drawn
+ *  - return code is whether the summary lets the other channels get drawn
  */
-static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
+static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
 {
        bDopeSheet *ads = NULL;
        
@@ -2146,8 +2360,8 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
         *        being applicable.
         */
        if ((ac && ac->sl) && (ac->spacetype == SPACE_ACTION)) {
-               SpaceAction *saction= (SpaceAction *)ac->sl;
-               ads= &saction->ads;
+               SpaceAction *saction = (SpaceAction *)ac->sl;
+               ads = &saction->ads;
        }
        else {
                /* invalid space type - skip this summary channels */
@@ -2159,7 +2373,7 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
         *      - only useful for DopeSheet/Action/etc. editors where it is actually useful
         */
        if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
-               bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL);
+               bAnimListElem *ale = make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL);
                if (ale) {
                        BLI_addtail(anim_data, ale);
                        (*items)++;
@@ -2179,12 +2393,12 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
 /* ......................... */
 
 /* filter data associated with a channel - usually for handling summary-channels in DopeSheet */
-static size_t animdata_filter_animchan (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
+static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
 {
        size_t items = 0;
        
        /* data to filter depends on channel type */
-       // XXX: only common channel-types have been handled for now
+       /* NOTE: only common channel-types have been handled for now. More can be added as necessary */
        switch (channel->type) {
                case ANIMTYPE_SUMMARY:
                        items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
@@ -2197,6 +2411,14 @@ static size_t animdata_filter_animchan (bAnimContext *ac, ListBase *anim_data, b
                case ANIMTYPE_OBJECT:
                        items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
                        break;
+                       
+               case ANIMTYPE_ANIMDATA:
+                       items += animfilter_block_data(ac, anim_data, ads, channel->id, filter_mode);
+                       break;
+                       
+               default:
+                       printf("ERROR: Unsupported channel type (%d) in animdata_filter_animchan()\n", channel->type);
+                       break;
        }
        
        return items;
@@ -2205,14 +2427,14 @@ static size_t animdata_filter_animchan (bAnimContext *ac, ListBase *anim_data, b
 /* ----------- Cleanup API --------------- */
 
 /* Remove entries with invalid types in animation channel list */
-static size_t animdata_filter_remove_invalid (ListBase *anim_data)
+static size_t animdata_filter_remove_invalid(ListBase *anim_data)
 {
        bAnimListElem *ale, *next;
        size_t items = 0;
        
        /* only keep entries with valid types */
-       for (ale= anim_data->first; ale; ale= next) {
-               next= ale->next;
+       for (ale = anim_data->first; ale; ale = next) {
+               next = ale->next;
                
                if (ale->type == ANIMTYPE_NONE)
                        BLI_freelinkN(anim_data, ale);
@@ -2224,7 +2446,7 @@ static size_t animdata_filter_remove_invalid (ListBase *anim_data)
 }
 
 /* Remove duplicate entries in animation channel list */
-static size_t animdata_filter_remove_duplis (ListBase *anim_data)
+static size_t animdata_filter_remove_duplis(ListBase *anim_data)
 {
        bAnimListElem *ale, *next;
        GHash *gh;
@@ -2233,7 +2455,7 @@ static size_t animdata_filter_remove_duplis (ListBase *anim_data)
        /* build new hashtable to efficiently store and retrieve which entries have been 
         * encountered already while searching
         */
-       gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "animdata_filter_duplis_remove gh");
+       gh = BLI_ghash_ptr_new("animdata_filter_duplis_remove gh");
        
        /* loop through items, removing them from the list if a similar item occurs already */
        for (ale = anim_data->first; ale; ale = next) {
@@ -2266,11 +2488,11 @@ static size_t animdata_filter_remove_duplis (ListBase *anim_data)
 /* This function filters the active data source to leave only animation channels suitable for
  * usage by the caller. It will return the length of the list 
  * 
- *     *anim_data: is a pointer to a ListBase, to which the filtered animation channels
+ *  *anim_data: is a pointer to a ListBase, to which the filtered animation channels
  *             will be placed for use.
  *     filter_mode: how should the data be filtered - bitmapping accessed flags
  */
-size_t ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
+size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
 {
        size_t items = 0;
        
@@ -2279,48 +2501,56 @@ size_t ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_m
                
                /* firstly filter the data */
                switch (datatype) {
-                       case ANIMCONT_ACTION:   /* 'Action Editor' */
+                       case ANIMCONT_ACTION:   /* 'Action Editor' */
                        {
-                               Object *obact= ac->obact;
+                               Object *obact = ac->obact;
                                SpaceAction *saction = (SpaceAction *)ac->sl;
-                               bDopeSheet *ads = (saction)? &saction->ads : NULL;
+                               bDopeSheet *ads = (saction) ? &saction->ads : NULL;
                                
                                /* the check for the DopeSheet summary is included here since the summary works here too */
                                if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
                                        items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
                        }
-                               break;
-                               
+                       break;
+                       
                        case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
                        {
                                /* the check for the DopeSheet summary is included here since the summary works here too */
                                if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
-                                       items= animdata_filter_shapekey(ac, anim_data, data, filter_mode);
+                                       items = animdata_filter_shapekey(ac, anim_data, data, filter_mode);
                        }
-                               break;
+                       break;
                                
                        case ANIMCONT_GPENCIL:
                        {
-                               items= animdata_filter_gpencil(anim_data, data, filter_mode);
+                               if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+                                       items = animdata_filter_gpencil(anim_data, data, filter_mode);
                        }
-                               break;
-                               
+                       break;
+                       
+                       case ANIMCONT_MASK:
+                       {
+                               if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+                                       items = animdata_filter_mask(anim_data, data, filter_mode);
+                       }
+                       break;
+                       
                        case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */
                        {
                                /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */
                                if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
                                        items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
                        }
-                               break;
+                       break;
                                
-                       case ANIMCONT_FCURVES: /* Graph Editor -> FCurves/Animation Editing */
+                       case ANIMCONT_FCURVES: /* Graph Editor -> F-Curves/Animation Editing */
                        case ANIMCONT_DRIVERS: /* Graph Editor -> Drivers Editing */
-                       case ANIMCONT_NLA: /* NLA Editor */
+                       case ANIMCONT_NLA:     /* NLA Editor */
                        {
                                /* all of these editors use the basic DopeSheet data for filtering options, but don't have all the same features */
                                items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
                        }
-                               break;
+                       break;
                        
                        case ANIMCONT_CHANNEL: /* animation channel */
                        {
@@ -2329,7 +2559,7 @@ size_t ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_m
                                /* based on the channel type, filter relevant data for this */
                                items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
                        }
-                               break;
+                       break;
                }
                        
                /* remove any 'weedy' entries */