Bugfix #20664: NLA Editor - Hiding stuff causes instant crash ..
[blender.git] / source / blender / editors / animation / anim_channels_edit.c
index 530e91794749cd5028020dd299f6b20838c1477d..f756c5b3158640025e37b1ed4f0a92271c975af8 100644 (file)
@@ -205,7 +205,7 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
  *     - test: check if deselecting instead of selecting
  *     - sel: eAnimChannels_SetFlag;
  */
-void ANIM_deselect_anim_channels (void *data, short datatype, short test, short sel)
+void ANIM_deselect_anim_channels (bAnimContext *ac, void *data, short datatype, short test, short sel)
 {
        ListBase anim_data = {NULL, NULL};
        bAnimListElem *ale;
@@ -213,7 +213,7 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
        
        /* filter data */
        filter= ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS;
-       ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
+       ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
        
        /* See if we should be selecting or deselecting */
        if (test) {
@@ -372,6 +372,10 @@ void ANIM_flush_setting_anim_channels (bAnimContext *ac, ListBase *anim_data, bA
        bAnimListElem *ale, *match=NULL;
        int prevLevel=0, matchLevel=0;
        
+       /* sanity check */
+       if (ELEM(NULL, anim_data, anim_data->first))
+               return;
+       
        /* find the channel that got changed */
        for (ale= anim_data->first; ale; ale= ale->next) {
                /* compare data, and type as main way of identifying the channel */
@@ -391,6 +395,11 @@ void ANIM_flush_setting_anim_channels (bAnimContext *ac, ListBase *anim_data, bA
        else {
                bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale_setting);
                
+               if (acf == NULL) {
+                       printf("ERROR: no channel info for the changed channel \n");
+                       return;
+               }
+               
                /* get the level of the channel that was affected
                 *       - we define the level as simply being the offset for the start of the channel
                 */
@@ -416,6 +425,10 @@ void ANIM_flush_setting_anim_channels (bAnimContext *ac, ListBase *anim_data, bA
                        bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
                        int level;
                        
+                       /* if no channel info was found, skip, since this type might not have any useful info */
+                       if (acf == NULL)
+                               continue;
+                       
                        /* get the level of the current channel traversed 
                         *       - we define the level as simply being the offset for the start of the channel
                         */
@@ -445,6 +458,10 @@ void ANIM_flush_setting_anim_channels (bAnimContext *ac, ListBase *anim_data, bA
                        bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
                        int level;
                        
+                       /* if no channel info was found, skip, since this type might not have any useful info */
+                       if (acf == NULL)
+                               continue;
+                       
                        /* get the level of the current channel traversed 
                         *       - we define the level as simply being the offset for the start of the channel
                         */
@@ -1260,7 +1277,7 @@ void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
                /* flag-setting mode */
        RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
                /* setting to set */
-       RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+       ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
 }
 
 void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
@@ -1282,7 +1299,7 @@ void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
                /* flag-setting mode */
        RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
                /* setting to set */
-       RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+       ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
 }
 
 void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
@@ -1304,7 +1321,7 @@ void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
                /* flag-setting mode */
        RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
                /* setting to set */
-       RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+       ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
 }
 
 // XXX currently, this is a separate operator, but perhaps we could in future specify in keymaps whether to call invoke or exec?
@@ -1368,7 +1385,7 @@ void ANIM_OT_channels_expand (wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_boolean(ot->srna, "all", 0, "All", "Expand all channels (not just selected ones)");
+       RNA_def_boolean(ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
 }
 
 /* ********************** Collapse Channels Operator *********************** */
@@ -1410,7 +1427,7 @@ void ANIM_OT_channels_collapse (wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_boolean(ot->srna, "all", 0, "All", "Collapse all channels (not just selected ones)");
+       RNA_def_boolean(ot->srna, "all", 1, "All", "Collapse all channels (not just selected ones)");
 }
 
 /* ********************** Select All Operator *********************** */
@@ -1425,9 +1442,9 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
                
        /* 'standard' behaviour - check if selected, then apply relevant selection */
        if (RNA_boolean_get(op->ptr, "invert"))
-               ANIM_deselect_anim_channels(ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_TOGGLE);
+               ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_TOGGLE);
        else
-               ANIM_deselect_anim_channels(ac.data, ac.datatype, 1, ACHANNEL_SETFLAG_ADD);
+               ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 1, ACHANNEL_SETFLAG_ADD);
        
        /* send notifier that things have changed */
        WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_SELECT, NULL);
@@ -1676,7 +1693,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
                                }
                                else {
                                        /* select AnimData block by itself */
-                                       ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+                                       ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
                                        ale->adt->flag |= ADT_UI_SELECTED;
                                }
                                
@@ -1703,7 +1720,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
                                FCurve *fcu;
                                
                                /* deselect all other channels */
-                               ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+                               ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
                                
                                /* only select channels in group and group itself */
                                for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next)
@@ -1712,7 +1729,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
                        }
                        else {
                                /* select group by itself */
-                               ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+                               ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
                                agrp->flag |= AGRP_SELECTED;
                        }
                        
@@ -1734,7 +1751,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
                        }
                        else {
                                /* select F-Curve by itself */
-                               ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+                               ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
                                fcu->flag |= FCURVE_SELECTED;
                        }
                        
@@ -1756,7 +1773,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
                        }
                        else {
                                /* select ShapeKey by itself */
-                               ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+                               ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
                                kb->flag |= KEYBLOCK_SEL;
                        }
                                
@@ -1914,6 +1931,7 @@ void ED_operatortypes_animchannels(void)
        WM_operatortype_append(ANIM_OT_channels_visibility_set);
 }
 
+// TODO: check on a poll callback for this, to get hotkeys into menus
 void ED_keymap_animchannels(wmKeyConfig *keyconf)
 {
        wmKeyMap *keymap = WM_keymap_find(keyconf, "Animation Channels", 0, 0);
@@ -1949,8 +1967,8 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0);
        
-       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
-       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 0);
        
        /* rearranging - actions only */
        //WM_keymap_add_item(keymap, "ANIM_OT_channels_move_up", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0);