2.5/Posemode:
[blender-staging.git] / source / blender / editors / space_outliner / outliner.c
index 40a365f956c65533ac6942ffb732ba8b5b9d2987..33119317a6da246d837e834fa7dcba6eeea95e90 100644 (file)
@@ -561,7 +561,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        TreeElement *te;
        TreeStoreElem *tselem;
        ID *id= idv;
-       int a;
+       int a = 0;
        
        if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
                id= ((PointerRNA*)idv)->id.data;
@@ -620,7 +620,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                        
                                        tenla->name= "Pose";
                                        
-                                       if(arm->edbo==NULL && (ob->flag & OB_POSEMODE)) {       // channels undefined in editmode, but we want the 'tenla' pose icon itself
+                                       if(arm->edbo==NULL && (ob->mode & OB_MODE_POSE)) {      // channels undefined in editmode, but we want the 'tenla' pose icon itself
                                                int a= 0, const_index= 1000;    /* ensure unique id for bone constraints */
                                                
                                                for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) {
@@ -887,7 +887,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                else {
                                        /* do not extend Armature when we have posemode */
                                        tselem= TREESTORE(te->parent);
-                                       if( GS(tselem->id->name)==ID_OB && ((Object *)tselem->id)->flag & OB_POSEMODE);
+                                       if( GS(tselem->id->name)==ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE);
                                        else {
                                                Bone *curBone;
                                                for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
@@ -1016,7 +1016,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv;
                PropertyRNA *prop, *iterprop;
                PropertyType proptype;
-               PropertySubType propsubtype;
                int a, tot;
 
                /* we do lazy build, for speed and to avoid infinite recusion */
@@ -1096,32 +1095,61 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        }
                }
                else if(type == TSE_RNA_ARRAY_ELEM) {
-                       /* array property element */
-                       static char *vectoritem[4]= {"  x", "  y", "  z", "  w"};
-                       static char *quatitem[4]= {"  w", "  x", "  y", "  z"};
-                       static char *coloritem[4]= {"  r", "  g", "  b", "  a"};
+                       char c;
 
                        prop= parent->directdata;
-                       proptype= RNA_property_type(prop);
-                       propsubtype= RNA_property_subtype(prop);
-                       tot= RNA_property_array_length(prop);
 
                        te->directdata= prop;
                        te->rnaptr= *ptr;
                        te->index= index;
 
-                       if(tot == 4 && propsubtype == PROP_ROTATION)
-                               te->name= quatitem[index];
-                       else if(tot <= 4 && (propsubtype == PROP_VECTOR || propsubtype == PROP_ROTATION))
-                               te->name= vectoritem[index];
-                       else if(tot <= 4 && propsubtype == PROP_COLOR)
-                               te->name= coloritem[index];
-                       else {
-                               te->name= MEM_callocN(sizeof(char)*20, "OutlinerRNAArrayName");
-                               sprintf(te->name, "  %d", index+1);
-                               te->flag |= TE_FREE_NAME;
+                       c= RNA_property_array_item_char(prop, index);
+
+                       te->name= MEM_callocN(sizeof(char)*20, "OutlinerRNAArrayName");
+                       if(c) sprintf(te->name, "  %c", c);
+                       else sprintf(te->name, "  %d", index+1);
+                       te->flag |= TE_FREE_NAME;
+               }
+       }
+       else if(type == TSE_KEYMAP) {
+               wmKeyMap *km= (wmKeyMap *)idv;
+               wmKeymapItem *kmi;
+               char opname[OP_MAX_TYPENAME];
+               
+               te->directdata= idv;
+               te->name= km->nameid;
+               
+               if(!(tselem->flag & TSE_CLOSED)) {
+                       a= 0;
+                       
+                       for (kmi= km->keymap.first; kmi; kmi= kmi->next, a++) {
+                               const char *key= WM_key_event_string(kmi->type);
+                               
+                               if(key[0]) {
+                                       wmOperatorType *ot= NULL;
+                                       
+                                       if(kmi->propvalue);
+                                       else ot= WM_operatortype_find(kmi->idname, 0);
+                                       
+                                       if(ot || kmi->propvalue) {
+                                               TreeElement *ten= outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
+                                               
+                                               ten->directdata= kmi;
+                                               
+                                               if(kmi->propvalue) {
+                                                       ten->name= "Modal map, not yet";
+                                               }
+                                               else {
+                                                       WM_operator_py_idname(opname, ot->idname);
+                                                       ten->name= BLI_strdup(opname);
+                                                       ten->flag |= TE_FREE_NAME;
+                                               }
+                                       }
+                               }
                        }
                }
+               else 
+                       te->flag |= TE_LAZY_CLOSED;
        }
 
        return te;
@@ -1376,6 +1404,14 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
                        tselem->flag &= ~TSE_CLOSED;
                }
        }
+       else if(soops->outlinevis==SO_KEYMAP) {
+               wmWindowManager *wm= mainvar->wm.first;
+               wmKeyMap *km;
+               
+               for(km= wm->keymaps.first; km; km= km->next) {
+                       ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0);
+               }
+       }
        else {
                ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
                if(ten) ten->directdata= BASACT;
@@ -1442,7 +1478,7 @@ void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te, Tre
 
 static int outliner_toggle_visibility_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        
@@ -1481,7 +1517,7 @@ static void object_toggle_selectability_cb(bContext *C, Scene *scene, TreeElemen
 
 static int outliner_toggle_selectability_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        
@@ -1520,7 +1556,7 @@ void object_toggle_renderability_cb(bContext *C, Scene *scene, TreeElement *te,
 
 static int outliner_toggle_renderability_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        
@@ -1549,7 +1585,7 @@ void OUTLINER_OT_renderability_toggle(wmOperatorType *ot)
 
 static int outliner_toggle_expanded_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        ARegion *ar= CTX_wm_region(C);
        
        if (outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1))
@@ -1580,7 +1616,7 @@ void OUTLINER_OT_expanded_toggle(wmOperatorType *ot)
 
 static int outliner_toggle_selected_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        ARegion *ar= CTX_wm_region(C);
        
        if (outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1))
@@ -1633,7 +1669,7 @@ static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curleve
 
 static int outliner_one_level_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        ARegion *ar= CTX_wm_region(C);
        int add= RNA_boolean_get(op->ptr, "open");
        int level;
@@ -2141,13 +2177,13 @@ static int tree_element_active_pose(bContext *C, Scene *scene, TreeElement *te,
                if(scene->obedit) 
                        ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
                
-               if(ob->flag & OB_POSEMODE) 
+               if(ob->mode & OB_MODE_POSE) 
                        ED_armature_exit_posemode(C, base);
                else 
                        ED_armature_enter_posemode(C, base);
        }
        else {
-               if(ob->flag & OB_POSEMODE) return 1;
+               if(ob->mode & OB_MODE_POSE) return 1;
        }
        return 0;
 }
@@ -2193,6 +2229,21 @@ static int tree_element_active_sequence_dup(bContext *C, Scene *scene, TreeEleme
        return(0);
 }
 
+static int tree_element_active_keymap_item(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set)
+{
+       wmKeymapItem *kmi= te->directdata;
+       
+       if(set==0) {
+               if(kmi->inactive) return 0;
+               return 1;
+       }
+       else {
+               kmi->inactive= !kmi->inactive;
+       }
+       return 0;
+}
+
+
 /* generic call for non-id data to make/check active in UI */
 /* Context can be NULL when set==0 */
 static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set)
@@ -2213,10 +2264,8 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
                        break;
                case TSE_LINKED_PSYS:
                        return tree_element_active_psys(C, scene, te, tselem, set);
-                       break;
                case TSE_POSE_BASE:
                        return tree_element_active_pose(C, scene, te, tselem, set);
-                       break;
                case TSE_POSE_CHANNEL:
                        return tree_element_active_posechannel(C, scene, te, tselem, set);
                case TSE_CONSTRAINT:
@@ -2227,10 +2276,11 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
                        return tree_element_active_posegroup(C, scene, te, tselem, set);
                case TSE_SEQUENCE:
                        return tree_element_active_sequence(C, te, tselem, set);
-                       break;
                case TSE_SEQUENCE_DUP:
                        return tree_element_active_sequence_dup(C, scene, te, tselem, set);
-                       break;
+               case TSE_KEYMAP_ITEM:
+                       return tree_element_active_keymap_item(C, te, tselem, set);
+                       
        }
        return 0;
 }
@@ -2259,7 +2309,6 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
                                else tselem->flag |= TSE_CLOSED;
                                
                        }
-                       soops->storeflag |= SO_TREESTORE_REDRAW;
 
                        return 1;
                }
@@ -2307,7 +2356,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
 {
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        TreeElement *te;
        float fmval[2];
        int extend= RNA_boolean_get(op->ptr, "extend");
@@ -2371,8 +2420,6 @@ static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement
                        if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED;
                        else tselem->flag |= TSE_CLOSED;
                }
-               
-               soops->storeflag |= SO_TREESTORE_REDRAW;
 
                return 1;
        }
@@ -2389,7 +2436,7 @@ static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement
 static int outliner_item_openclose(bContext *C, wmOperator *op, wmEvent *event)
 {
        ARegion *ar= CTX_wm_region(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        TreeElement *te;
        float fmval[2];
        int all= RNA_boolean_get(op->ptr, "all");
@@ -2456,7 +2503,7 @@ static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, T
 static int outliner_item_rename(bContext *C, wmOperator *op, wmEvent *event)
 {
        ARegion *ar= CTX_wm_region(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        TreeElement *te;
        float fmval[2];
        
@@ -2534,7 +2581,7 @@ static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id)
 
 static int outliner_show_active_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *so= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        View2D *v2d= &ar->v2d;
@@ -2764,7 +2811,7 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
 /* show entire object level hierarchy */
 static int outliner_show_hierarchy_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        ARegion *ar= CTX_wm_region(C);
        Scene *scene= CTX_data_scene(C);
        
@@ -3014,10 +3061,6 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeSto
                if(scene->obedit==base->object) 
                        ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
                
-               if(base==BASACT) {
-                       ED_view3d_exit_paint_modes(C);
-               }
-               
                ED_base_object_free_and_unlink(scene, base);
                te->directdata= NULL;
                tselem->id= NULL;
@@ -3189,7 +3232,7 @@ static EnumPropertyItem prop_object_op_types[] = {
 static int outliner_object_operation_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        int event;
        char *str;
        
@@ -3271,7 +3314,7 @@ static EnumPropertyItem prop_group_op_types[] = {
 static int outliner_group_operation_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        int event;
        
        /* check for invalid states */
@@ -3328,7 +3371,7 @@ static EnumPropertyItem prop_id_op_types[] = {
 static int outliner_id_operation_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
        int event;
        
@@ -3395,7 +3438,7 @@ static EnumPropertyItem prop_data_op_types[] = {
 
 static int outliner_data_operation_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
        int event;
        
@@ -3517,7 +3560,7 @@ static int outliner_operation(bContext *C, wmOperator *op, wmEvent *event)
 {
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        TreeElement *te;
        float fmval[2];
        
@@ -3551,7 +3594,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C)
 {
        ScrArea *sa= CTX_wm_area(C);
        if ((sa) && (sa->spacetype==SPACE_OUTLINER)) {
-               SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C);
+               SpaceOops *so= CTX_wm_space_outliner(C);
                return (so->outlinevis == SO_DATABLOCKS);
        }
        return 0;
@@ -3615,7 +3658,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
                                }
                                else if(RNA_property_type(prop) == PROP_COLLECTION) {
                                        char buf[128], *name;
-
+                                       
                                        temnext= (TreeElement*)(ld->next->data);
                                        tsenext= TREESTORE(temnext);
                                        
@@ -3764,7 +3807,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, short m
 
 static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soutliner= CTX_wm_space_outliner(C);
        
        /* check for invalid states */
        if (soutliner == NULL)
@@ -3799,7 +3842,7 @@ void OUTLINER_OT_drivers_add(wmOperatorType *ot)
 
 static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soutliner= CTX_wm_space_outliner(C);
        
        /* check for invalid states */
        if (soutliner == NULL)
@@ -3934,7 +3977,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
 
 static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soutliner= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        KeyingSet *ks= verify_active_keyingset(scene, 1);
        
@@ -3974,7 +4017,7 @@ void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
 
 static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *op)
 {
-       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soutliner= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        KeyingSet *ks= verify_active_keyingset(scene, 1);
        
@@ -4119,13 +4162,13 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                        case TSE_POSEGRP_BASE:
                                UI_icon_draw(x, y, ICON_VERTEXSEL); break;
                        case TSE_SEQUENCE:
-                               if((te->idcode==SEQ_MOVIE) || (te->idcode==SEQ_MOVIE_AND_HD_SOUND))
+                               if(te->idcode==SEQ_MOVIE)
                                        UI_icon_draw(x, y, ICON_SEQUENCE);
                                else if(te->idcode==SEQ_META)
                                        UI_icon_draw(x, y, ICON_DOT);
                                else if(te->idcode==SEQ_SCENE)
                                        UI_icon_draw(x, y, ICON_SCENE);
-                               else if((te->idcode==SEQ_RAM_SOUND) || (te->idcode==SEQ_HD_SOUND))
+                               else if(te->idcode==SEQ_SOUND)
                                        UI_icon_draw(x, y, ICON_SOUND);
                                else if(te->idcode==SEQ_IMAGE)
                                        UI_icon_draw(x, y, ICON_IMAGE_COL);
@@ -4656,7 +4699,7 @@ static void restrictbutton_bone_cb(bContext *C, void *poin, void *poin2)
 
 static void namebutton_cb(bContext *C, void *tsep, char *oldname)
 {
-       SpaceOops *soops= (SpaceOops *)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        TreeStore *ts= soops->treestore;
@@ -4905,6 +4948,241 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
        }
 }
 
+static void operator_call_cb(struct bContext *C, void *arg_kmi, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       wmKeymapItem *kmi= arg_kmi;
+       
+       if(ot)
+               BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg_kmi, char *str, uiSearchItems *items)
+{
+       wmOperatorType *ot = WM_operatortype_first();
+       
+       for(; ot; ot= ot->next) {
+               
+               if(BLI_strcasestr(ot->idname, str)) {
+                       char name[OP_MAX_TYPENAME];
+                       
+                       /* display name for menu */
+                       WM_operator_py_idname(name, ot->idname);
+                       
+                       if(0==uiSearchItemAdd(items, name, ot, 0))
+                               break;
+               }
+       }
+}
+
+/* operator Search browse menu, open */
+static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
+{
+       static char search[OP_MAX_TYPENAME];
+       wmEvent event;
+       wmWindow *win= CTX_wm_window(C);
+       wmKeymapItem *kmi= arg_kmi;
+       wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0);
+       uiBlock *block;
+       uiBut *but;
+       
+       /* clear initial search string, then all items show */
+       search[0]= 0;
+       
+       block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+       uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+       
+       /* fake button, it holds space for search items */
+       uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+       
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+       uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
+       
+       uiBoundsBlock(block, 6);
+       uiBlockSetDirection(block, UI_DOWN);    
+       uiEndBlock(C, block);
+       
+       event= *(win->eventstate);      /* XXX huh huh? make api call */
+       event.type= EVT_BUT_OPEN;
+       event.val= KM_PRESS;
+       event.customdata= but;
+       event.customdatafree= FALSE;
+       wm_event_add(win, &event);
+       
+       return block;
+}
+
+#define OL_KM_KEYBOARD         0
+#define OL_KM_MOUSE                    1
+#define OL_KM_TWEAK                    2
+#define OL_KM_SPECIALS         3
+
+static short keymap_menu_type(short type)
+{
+       if(ISKEYBOARD(type)) return OL_KM_KEYBOARD;
+       if(WM_key_event_is_tweak(type)) return OL_KM_TWEAK;
+       if(type >= LEFTMOUSE && type <= WHEELOUTMOUSE) return OL_KM_MOUSE;
+//     return OL_KM_SPECIALS;
+       return 0;
+}
+
+static char *keymap_type_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Event Type %%t");
+       
+       str += sprintf(str, formatstr, "Keyboard", OL_KM_KEYBOARD);
+       str += sprintf(str, formatstr, "Mouse", OL_KM_MOUSE);
+       str += sprintf(str, formatstr, "Tweak", OL_KM_TWEAK);
+//     str += sprintf(str, formatstr, "Specials", OL_KM_SPECIALS);
+       
+       return string;
+}      
+
+static char *keymap_mouse_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Mouse Event %%t");
+       
+       str += sprintf(str, formatstr, "Left Mouse", LEFTMOUSE);
+       str += sprintf(str, formatstr, "Middle Mouse", MIDDLEMOUSE);
+       str += sprintf(str, formatstr, "Right Mouse", RIGHTMOUSE);
+       str += sprintf(str, formatstr, "Action Mouse", ACTIONMOUSE);
+       str += sprintf(str, formatstr, "Select Mouse", SELECTMOUSE);
+       str += sprintf(str, formatstr, "Mouse Move", MOUSEMOVE);
+       str += sprintf(str, formatstr, "Wheel Up", WHEELUPMOUSE);
+       str += sprintf(str, formatstr, "Wheel Down", WHEELDOWNMOUSE);
+       str += sprintf(str, formatstr, "Wheel In", WHEELINMOUSE);
+       str += sprintf(str, formatstr, "Wheel Out", WHEELOUTMOUSE);
+       
+       return string;
+}
+
+static char *keymap_tweak_menu(void)
+{
+       static char string[500];
+       static char formatstr[] = "|%s %%x%d";
+       char *str= string;
+       
+       str += sprintf(str, "Tweak Event %%t");
+       
+       str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L);
+       str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M);
+       str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R);
+       str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A);
+       str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S);
+       
+       return string;
+}
+
+static void keymap_type_cb(bContext *C, void *kmi_v, void *unused_v)
+{
+       wmKeymapItem *kmi= kmi_v;
+       short maptype= keymap_menu_type(kmi->type);
+       
+       if(maptype!=kmi->maptype) {
+               switch(kmi->maptype) {
+                       case OL_KM_KEYBOARD:
+                               kmi->type= AKEY;
+                               kmi->val= KM_PRESS;
+                               break;
+                       case OL_KM_MOUSE:
+                               kmi->type= LEFTMOUSE;
+                               kmi->val= KM_PRESS;
+                               break;
+                       case OL_KM_TWEAK:
+                               kmi->type= EVT_TWEAK_L;
+                               kmi->val= KM_ANY;
+                               break;
+                       case OL_KM_SPECIALS:
+                               kmi->type= AKEY;
+                               kmi->val= KM_PRESS;
+               }
+               ED_region_tag_redraw(CTX_wm_region(C));
+       }
+}
+
+static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       uiBlockSetEmboss(block, UI_EMBOSST);
+       
+       for(te= lb->first; te; te= te->next) {
+               tselem= TREESTORE(te);
+               if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+                       uiBut *but;
+                       char *str;
+                       int xstart= 240;
+                       int butw1= 20; /* operator */
+                       int butw2= 90; /* event type, menus */
+                       int butw3= 43; /* modifiers */
+
+                       if(tselem->type == TSE_KEYMAP_ITEM) {
+                               wmKeymapItem *kmi= te->directdata;
+                               
+                               /* modal map? */
+                               if(kmi->propvalue);
+                               else {
+                                       uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator");
+                               }
+                               xstart+= butw1+10;
+                               
+                               /* map type button */
+                               kmi->maptype= keymap_menu_type(kmi->type);
+                               
+                               str= keymap_type_menu();
+                               but= uiDefButS(block, MENU, 0, str,     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+                               uiButSetFunc(but, keymap_type_cb, kmi, NULL);
+                               xstart+= butw2+5;
+                               
+                               /* edit actual event */
+                               switch(kmi->maptype) {
+                                       case OL_KM_KEYBOARD:
+                                               uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code");
+                                               xstart+= butw2+5;
+                                               break;
+                                       case OL_KM_MOUSE:
+                                               str= keymap_mouse_menu();
+                                               uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Mouse button");   
+                                               xstart+= butw2+5;
+                                               break;
+                                       case OL_KM_TWEAK:
+                                               str= keymap_tweak_menu();
+                                               uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0,  "Tweak gesture"); 
+                                               xstart+= butw2+5;
+                                               break;
+                               }
+                               
+                               /* modifiers */
+                               uiBlockBeginAlign(block);
+                               uiDefButS(block, OPTION, 0, "Shift",    xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
+                               uiDefButS(block, OPTION, 0, "Ctrl",     xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Alt",      xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               uiDefButS(block, OPTION, 0, "Cmd",      xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+                               xstart+= 5;
+                               uiBlockEndAlign(block);
+                               
+                               /* rna property */
+                               if(kmi->ptr && kmi->ptr->data)
+                                       uiDefBut(block, LABEL, 0, "(RNA property)",     xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
+                                       
+                               
+                       }
+               }
+               
+               if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
+       }
+}
+
+
 static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
 {
        uiBut *bt;
@@ -4950,7 +5228,7 @@ void draw_outliner(const bContext *C)
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        View2D *v2d= &ar->v2d;
-       SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C);
+       SpaceOops *soops= CTX_wm_space_outliner(C);
        uiBlock *block;
        int sizey= 0, sizex= 0, sizex_rna= 0;
        
@@ -4959,7 +5237,7 @@ void draw_outliner(const bContext *C)
        /* get extents of data */
        outliner_height(soops, &soops->tree, &sizey);
 
-       if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
+       if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) {
                /* RNA has two columns:
                 *      - column 1 is (max_width + OL_RNA_COL_SPACEX) or
                 *                               (OL_RNA_COL_X), whichever is wider...
@@ -5005,6 +5283,9 @@ void draw_outliner(const bContext *C)
                outliner_draw_rnacols(ar, soops, sizex_rna);
                outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree);
        }
+       else if(soops->outlinevis == SO_KEYMAP) {
+               outliner_draw_keymapbuts(block, ar, soops, &soops->tree);
+       }
        else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
                /* draw restriction columns */
                outliner_draw_restrictcols(ar, soops);