At last... this merge should finally do the trick!
[blender.git] / source / blender / editors / space_outliner / outliner.c
index 97f54b40361604acdb0e3b37941576cf5b434e74..6563a7dc7df77c8622480bbbc2dc26f232846b25 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
@@ -49,7 +50,7 @@
 #include "DNA_modifier_types.h"
 #include "DNA_nla_types.h"
 #include "DNA_object_types.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -63,6 +64,7 @@
 
 #include "IMB_imbuf_types.h"
 
+#include "BKE_animsys.h"
 #include "BKE_constraint.h"
 #include "BKE_context.h"
 #include "BKE_deform.h"
 #include "BKE_material.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
+#include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_scene.h"
+#include "BKE_sequence.h"
 #include "BKE_utildefines.h"
 
 #include "ED_screen.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
-#include "BIF_editarmature.h"
 
 #include "UI_interface.h"
 #include "UI_interface_icons.h"
 #include "UI_resources.h"
 #include "UI_view2d.h"
-#include "UI_text.h"
 
 #include "RNA_access.h"
 
+#include "ED_armature.h"
+#include "ED_keyframing.h"
 #include "ED_object.h"
+#include "ED_screen.h"
 
 #include "outliner_intern.h"
 
-#ifdef INTERNATIONAL
-#include "FTF_Api.h"
-#endif
-
 #include "PIL_time.h" 
 
 
 
 /* ************* XXX **************** */
 
-static void allqueue() {}
 static void BIF_undo_push() {}
 static void BIF_preview_changed() {}
-static void set_scene() {}
 static void error() {}
 static int pupmenu() {return 0;}
 
@@ -263,16 +262,19 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
                TreeStoreElem *tselem= TREESTORE(te);
                if((tselem->flag & TSE_CLOSED)==0) 
                        outliner_height(soops, &te->subtree, h);
-               (*h)++;
+               (*h) += OL_H;
                te= te->next;
        }
 }
 
+#if 0  // XXX this is currently disabled until te->xend is set correctly
 static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
 {
        TreeElement *te= lb->first;
        while(te) {
-               TreeStoreElem *tselem= TREESTORE(te);
+//             TreeStoreElem *tselem= TREESTORE(te);
+               
+               // XXX fixme... te->xend is not set yet
                if(tselem->flag & TSE_CLOSED) {
                        if (te->xend > *w)
                                *w = te->xend;
@@ -281,12 +283,14 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
                te= te->next;
        }
 }
+#endif
 
 static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int startx)
 {
        TreeElement *te= lb->first;
        while(te) {
                TreeStoreElem *tselem= TREESTORE(te);
+                       // XXX fixme... (currently, we're using a fixed length of 100)!
                /*if(te->xend) {
                        if(te->xend > *w)
                                *w = te->xend;
@@ -585,6 +589,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        te->index= index;       // for data arays
        if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP));
        else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM));
+       else if(type==TSE_ANIM_DATA);
        else {
                te->name= id->name+2; // default, can be overridden by Library or non-ID data
                te->idcode= GS(id->name);
@@ -607,6 +612,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        {
                                Object *ob= (Object *)id;
                                
+                               outliner_add_element(soops, &te->subtree, ob->adt, te, TSE_ANIM_DATA, 0);
+                               outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
+                               
                                if(ob->proxy && ob->id.lib==NULL)
                                        outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
                                
@@ -691,9 +699,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                        }
                                }
                                
-                               outliner_add_element(soops, &te->subtree, ob->ipo, te, 0, 0);
-                               outliner_add_element(soops, &te->subtree, ob->action, te, 0, 0);
-                               
                                for(a=0; a<ob->totcol; a++) 
                                        outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
                                
@@ -773,27 +778,16 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                }
                                
                                if(ob->dup_group)
-                                       outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);
-
-                               if(ob->nlastrips.first) {
-                                       bActionStrip *strip;
-                                       TreeElement *ten;
-                                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_NLA, 0);
-                                       int a= 0;
-                                       
-                                       tenla->name= "NLA strips";
-                                       for (strip=ob->nlastrips.first; strip; strip=strip->next, a++) {
-                                               ten= outliner_add_element(soops, &tenla->subtree, strip->act, tenla, TSE_NLA_ACTION, a);
-                                               if(ten) ten->directdata= strip;
-                                       }
-                               }
+                                       outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);     
                                
                        }
                        break;
                case ID_ME:
                        {
                                Mesh *me= (Mesh *)id;
-                               outliner_add_element(soops, &te->subtree, me->ipo, te, 0, 0);
+                               
+                               //outliner_add_element(soops, &te->subtree, me->adt, te, TSE_ANIM_DATA, 0);
+                               
                                outliner_add_element(soops, &te->subtree, me->key, te, 0, 0);
                                for(a=0; a<me->totcol; a++) 
                                        outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a);
@@ -804,6 +798,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                case ID_CU:
                        {
                                Curve *cu= (Curve *)id;
+                               
+                               outliner_add_element(soops, &te->subtree, cu->adt, te, TSE_ANIM_DATA, 0);
+                               
                                for(a=0; a<cu->totcol; a++) 
                                        outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a);
                        }
@@ -819,7 +816,8 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                {
                        Material *ma= (Material *)id;
                        
-                       outliner_add_element(soops, &te->subtree, ma->ipo, te, 0, 0);
+                       outliner_add_element(soops, &te->subtree, ma->adt, te, TSE_ANIM_DATA, 0);
+                       
                        for(a=0; a<MAX_MTEX; a++) {
                                if(ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a);
                        }
@@ -829,20 +827,22 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        {
                                Tex *tex= (Tex *)id;
                                
-                               outliner_add_element(soops, &te->subtree, tex->ipo, te, 0, 0);
+                               outliner_add_element(soops, &te->subtree, tex->adt, te, TSE_ANIM_DATA, 0);
                                outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0);
                        }
                        break;
                case ID_CA:
                        {
                                Camera *ca= (Camera *)id;
-                               outliner_add_element(soops, &te->subtree, ca->ipo, te, 0, 0);
+                               outliner_add_element(soops, &te->subtree, ca->adt, te, TSE_ANIM_DATA, 0);
                        }
                        break;
                case ID_LA:
                        {
                                Lamp *la= (Lamp *)id;
-                               outliner_add_element(soops, &te->subtree, la->ipo, te, 0, 0);
+                               
+                               outliner_add_element(soops, &te->subtree, la->adt, te, TSE_ANIM_DATA, 0);
+                               
                                for(a=0; a<MAX_MTEX; a++) {
                                        if(la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a);
                                }
@@ -851,7 +851,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                case ID_WO:
                        {
                                World *wrld= (World *)id;
-                               outliner_add_element(soops, &te->subtree, wrld->ipo, te, 0, 0);
+                               
+                               outliner_add_element(soops, &te->subtree, wrld->adt, te, TSE_ANIM_DATA, 0);
+                               
                                for(a=0; a<MAX_MTEX; a++) {
                                        if(wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a);
                                }
@@ -860,35 +862,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                case ID_KE:
                        {
                                Key *key= (Key *)id;
-                               outliner_add_element(soops, &te->subtree, key->ipo, te, 0, 0);
-                       }
-                       break;
-               case ID_IP:
-                       {
-                               Ipo *ipo= (Ipo *)id;
-                               IpoCurve *icu;
-                               Object *lastadded= NULL;
                                
-                               for (icu= ipo->curve.first; icu; icu= icu->next) {
-                                       if (icu->driver && icu->driver->ob) {
-                                               if (lastadded != icu->driver->ob) {
-                                                       outliner_add_element(soops, &te->subtree, icu->driver->ob, te, TSE_LINKED_OB, 0);
-                                                       lastadded= icu->driver->ob;
-                                               }
-                                       }
-                               }
+                               outliner_add_element(soops, &te->subtree, key->adt, te, TSE_ANIM_DATA, 0);
                        }
                        break;
                case ID_AC:
                        {
-                               bAction *act= (bAction *)id;
-                               bActionChannel *chan;
-                               int a= 0;
-                               
-                               tselem= TREESTORE(parent);
-                               for (chan=act->chanbase.first; chan; chan=chan->next, a++) {
-                                       outliner_add_element(soops, &te->subtree, chan->ipo, te, 0, a);
-                               }
+                               // XXX do we want to be exposing the F-Curves here?
+                               //bAction *act= (bAction *)id;
                        }
                        break;
                case ID_AR:
@@ -900,7 +881,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                        EditBone *ebone;
                                        TreeElement *ten;
                                        
-                                       for (ebone = G.edbo.first; ebone; ebone=ebone->next, a++) {
+                                       for (ebone = arm->edbo->first; ebone; ebone=ebone->next, a++) {
                                                ten= outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a);
                                                ten->directdata= ebone;
                                                ten->name= ebone->name;
@@ -935,6 +916,60 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        break;
                }
        }
+       else if(type==TSE_ANIM_DATA) {
+               AnimData *adt= (AnimData *)idv;
+               
+               /* this element's info */
+               te->name= "Animation";
+               
+               /* Action */
+               outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0);
+               
+               /* Drivers */
+               if (adt->drivers.first) {
+                       TreeElement *ted= outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
+                       ID *lastadded= NULL;
+                       FCurve *fcu;
+                       DriverTarget *dtar;
+                       
+                       ted->name= "Drivers";
+               
+                       for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
+                               if (fcu->driver && fcu->driver->targets.first)  {
+                                       for (dtar= fcu->driver->targets.first; dtar; dtar= dtar->next) {
+                                               if (lastadded != dtar->id) {
+                                                       // XXX this lastadded check is rather lame, and also fails quite badly...
+                                                       outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
+                                                       lastadded= dtar->id;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               /* NLA Data */
+               if (adt->nla_tracks.first) {
+                       TreeElement *tenla= outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0);
+                       NlaTrack *nlt;
+                       int a= 0;
+                       
+                       tenla->name= "NLA Tracks";
+                       
+                       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+                               TreeElement *tenlt= outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
+                               NlaStrip *strip;
+                               TreeElement *ten;
+                               int b= 0;
+                               
+                               tenlt->name= nlt->name;
+                               
+                               for (strip=nlt->strips.first; strip; strip=strip->next, b++) {
+                                       ten= outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
+                                       if(ten) ten->directdata= strip;
+                               }
+                       }
+               }
+       }
        else if(type==TSE_SEQUENCE) {
                Sequence *seq= (Sequence*) idv;
                Sequence *p;
@@ -996,7 +1031,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        }
        else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
                PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv;
-               PropertyRNA *prop, *iterprop, *nameprop;
+               PropertyRNA *prop, *iterprop;
                PropertyType proptype;
                PropertySubType propsubtype;
                int a, tot;
@@ -1008,20 +1043,18 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                }
                else if(type == TSE_RNA_STRUCT) {
                        /* struct */
-                       nameprop= RNA_struct_name_property(ptr);
+                       te->name= RNA_struct_name_get_alloc(ptr, NULL, 0);
 
-                       if(nameprop) {
-                               te->name= RNA_property_string_get_alloc(ptr, nameprop, NULL, 0);
+                       if(te->name)
                                te->flag |= TE_FREE_NAME;
-                       }
                        else
-                               te->name= (char*)RNA_struct_ui_name(ptr);
+                               te->name= (char*)RNA_struct_ui_name(ptr->type);
 
-                       iterprop= RNA_struct_iterator_property(ptr);
+                       iterprop= RNA_struct_iterator_property(ptr->type);
                        tot= RNA_property_collection_length(ptr, iterprop);
 
                        /* auto open these cases */
-                       if(!parent || (RNA_property_type(&parent->rnaptr, parent->directdata)) == PROP_POINTER)
+                       if(!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER)
                                if(!tselem->used)
                                        tselem->flag &= ~TSE_CLOSED;
 
@@ -1036,18 +1069,18 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                }
                else if(type == TSE_RNA_PROPERTY) {
                        /* property */
-                       iterprop= RNA_struct_iterator_property(ptr);
+                       iterprop= RNA_struct_iterator_property(ptr->type);
                        RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
 
                        prop= propptr.data;
-                       proptype= RNA_property_type(ptr, prop);
+                       proptype= RNA_property_type(prop);
 
-                       te->name= (char*)RNA_property_ui_name(ptr, prop);
+                       te->name= (char*)RNA_property_ui_name(prop);
                        te->directdata= prop;
                        te->rnaptr= *ptr;
 
                        if(proptype == PROP_POINTER) {
-                               RNA_property_pointer_get(ptr, prop, &pptr);
+                               pptr= RNA_property_pointer_get(ptr, prop);
 
                                if(pptr.data) {
                                        if(!(tselem->flag & TSE_CLOSED))
@@ -1069,7 +1102,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                                        te->flag |= TE_LAZY_CLOSED;
                        }
                        else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
-                               tot= RNA_property_array_length(ptr, prop);
+                               tot= RNA_property_array_length(prop);
 
                                if(!(tselem->flag & TSE_CLOSED)) {
                                        for(a=0; a<tot; a++)
@@ -1086,9 +1119,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                        static char *coloritem[4]= {"  r", "  g", "  b", "  a"};
 
                        prop= parent->directdata;
-                       proptype= RNA_property_type(ptr, prop);
-                       propsubtype= RNA_property_subtype(ptr, prop);
-                       tot= RNA_property_array_length(ptr, prop);
+                       proptype= RNA_property_type(prop);
+                       propsubtype= RNA_property_subtype(prop);
+                       tot= RNA_property_array_length(prop);
 
                        te->directdata= prop;
                        te->rnaptr= *ptr;
@@ -1117,6 +1150,7 @@ static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb)
        TreeStoreElem *tselem;
 
        /* build hierarchy */
+       // XXX also, set extents here...
        te= lb->first;
        while(te) {
                ten= te->next;
@@ -1198,7 +1232,7 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
        Object *ob;
        TreeElement *te=NULL, *ten;
        TreeStoreElem *tselem;
-       int show_opened= soops->treestore==NULL; /* on first view, we open scenes */
+       int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */
 
        if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
           return;
@@ -1207,13 +1241,13 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
        outliner_storage_cleanup(soops);
        
        /* clear ob id.new flags */
-       for(ob= G.main->object.first; ob; ob= ob->id.next) ob->id.newid= NULL;
+       for(ob= mainvar->object.first; ob; ob= ob->id.next) ob->id.newid= NULL;
        
        /* options */
        if(soops->outlinevis == SO_LIBRARIES) {
                Library *lib;
                
-               for(lib= G.main->library.first; lib; lib= lib->id.next) {
+               for(lib= mainvar->library.first; lib; lib= lib->id.next) {
                        ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0);
                        lib->id.newid= (ID *)ten;
                }
@@ -1232,13 +1266,13 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
                        ten= nten;
                }
                /* restore newid pointers */
-               for(lib= G.main->library.first; lib; lib= lib->id.next)
+               for(lib= mainvar->library.first; lib; lib= lib->id.next)
                        lib->id.newid= NULL;
                
        }
        else if(soops->outlinevis == SO_ALL_SCENES) {
                Scene *sce;
-               for(sce= G.main->scene.first; sce; sce= sce->id.next) {
+               for(sce= mainvar->scene.first; sce; sce= sce->id.next) {
                        te= outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0);
                        tselem= TREESTORE(te);
                        if(sce==scene && show_opened) 
@@ -1274,7 +1308,7 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
                Group *group;
                GroupObject *go;
                
-               for(group= G.main->group.first; group; group= group->id.next) {
+               for(group= mainvar->group.first; group; group= group->id.next) {
                        if(group->id.us) {
                                te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
                                tselem= TREESTORE(te);
@@ -1314,11 +1348,10 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
        }
        else if(soops->outlinevis==SO_SEQUENCE) {
                Sequence *seq;
-               Editing *ed;
+               Editing *ed= seq_give_editing(scene, FALSE);
                int op;
 
-               ed= scene->ed;
-               if(!ed)
+               if(ed==NULL)
                        return;
 
                seq= ed->seqbasep->first;
@@ -1351,7 +1384,7 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
        else if(soops->outlinevis==SO_USERDEF) {
                PointerRNA userdefptr;
 
-               RNA_pointer_create(NULL, NULL, &RNA_UserPreferences, &U, &userdefptr);
+               RNA_pointer_create(NULL, &RNA_UserPreferences, &U, &userdefptr);
 
                ten= outliner_add_element(soops, &soops->tree, (void*)&userdefptr, NULL, TSE_RNA_STRUCT, -1);
 
@@ -1430,9 +1463,6 @@ void outliner_toggle_visibility(Scene *scene, SpaceOops *soops)
        
        BIF_undo_push("Outliner toggle selectability");
 
-       allqueue(REDRAWVIEW3D, 1);
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWINFO, 1);
 }
 
 static void object_toggle_selectability_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
@@ -1453,9 +1483,6 @@ void outliner_toggle_selectability(Scene *scene, SpaceOops *soops)
        
        BIF_undo_push("Outliner toggle selectability");
 
-       allqueue(REDRAWVIEW3D, 1);
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWINFO, 1);
 }
 
 void object_toggle_renderability_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
@@ -1476,9 +1503,6 @@ void outliner_toggle_renderability(Scene *scene, SpaceOops *soops)
        
        BIF_undo_push("Outliner toggle renderability");
 
-       allqueue(REDRAWVIEW3D, 1);
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWINFO, 1);
 }
 
 void outliner_toggle_visible(SpaceOops *soops)
@@ -1606,7 +1630,6 @@ static int tree_element_active_renderlayer(TreeElement *te, TreeStoreElem *tsele
        
        if(set) {
                sce->r.actlay= tselem->nr;
-               allqueue(REDRAWBUTSSCENE, 0);
        }
        else {
                return sce->r.actlay==tselem->nr;
@@ -1632,8 +1655,7 @@ static void tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
        
        sce= (Scene *)outliner_search_back(soops, te, ID_SCE);
        if(sce && scene != sce) {
-// XXX         if(obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
-               set_scene(sce);
+               ED_screen_set_scene(C, sce);
        }
        
        /* find associated base in current scene */
@@ -1699,10 +1721,6 @@ static int tree_element_active_material(Scene *scene, SpaceOops *soops, TreeElem
        if(set) {
 // XXX         extern_set_butspace(F5KEY, 0);  // force shading buttons
                BIF_preview_changed(ID_MA);
-               allqueue(REDRAWBUTSSHADING, 1);
-               allqueue(REDRAWNODE, 0);
-               allqueue(REDRAWOOPS, 0);
-               allqueue(REDRAWIPO, 0);
        }
        return 0;
 }
@@ -1730,7 +1748,7 @@ static int tree_element_active_texture(Scene *scene, SpaceOops *soops, TreeEleme
 
                if(set) {
                        if(sbuts) {
-                               sbuts->tabo= TAB_SHADING_TEX;   // hack from header_buttonswin.c
+                               // XXX sbuts->tabo= TAB_SHADING_TEX;    // hack from header_buttonswin.c
                                sbuts->texfrom= 1;
                        }
 // XXX                 extern_set_butspace(F6KEY, 0);  // force shading buttons texture
@@ -1744,7 +1762,7 @@ static int tree_element_active_texture(Scene *scene, SpaceOops *soops, TreeEleme
                Lamp *la= (Lamp *)tselemp->id;
                if(set) {
                        if(sbuts) {
-                               sbuts->tabo= TAB_SHADING_TEX;   // hack from header_buttonswin.c
+                               // XXX sbuts->tabo= TAB_SHADING_TEX;    // hack from header_buttonswin.c
                                sbuts->texfrom= 2;
                        }
 // XXX                 extern_set_butspace(F6KEY, 0);  // force shading buttons texture
@@ -1789,9 +1807,6 @@ static int tree_element_active_lamp(Scene *scene, SpaceOops *soops, TreeElement
        if(set) {
 // XXX         extern_set_butspace(F5KEY, 0);
                BIF_preview_changed(ID_LA);
-               allqueue(REDRAWBUTSSHADING, 1);
-               allqueue(REDRAWOOPS, 0);
-               allqueue(REDRAWIPO, 0);
        }
        else return 1;
        
@@ -1812,8 +1827,7 @@ static int tree_element_active_world(Scene *scene, SpaceOops *soops, TreeElement
        
        if(set) {       // make new scene active
                if(sce && scene != sce) {
-// XXX                 if(obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
-                       set_scene(sce);
+                       // XXX ED_screen_set_scene(C, sce);
                }
        }
        
@@ -1828,75 +1842,6 @@ static int tree_element_active_world(Scene *scene, SpaceOops *soops, TreeElement
        return 0;
 }
 
-static int tree_element_active_ipo(Scene *scene, SpaceOops *soops, TreeElement *te, int set)
-{
-       TreeElement *tes;
-       TreeStoreElem *tselems=NULL;
-       Object *ob;
-       
-       /* we search for the object parent */
-       ob= (Object *)outliner_search_back(soops, te, ID_OB);
-       if(ob==NULL || ob!=OBACT) return 0;     // just paranoia
-       
-       /* the parent of ipo */
-       tes= te->parent;
-       tselems= TREESTORE(tes);
-       
-       if(set) {
-               if(tes->idcode==ID_AC) {
-                       if(ob->ipoflag & OB_ACTION_OB)
-                               ob->ipowin= ID_OB;
-                       else if(ob->ipoflag & OB_ACTION_KEY)
-                               ob->ipowin= ID_KE;
-                       else 
-                               ob->ipowin= ID_PO;
-               }
-               else ob->ipowin= tes->idcode;
-               
-               if(ob->ipowin==ID_MA) tree_element_active_material(scene, soops, tes, 1);
-               else if(ob->ipowin==ID_AC) {
-                       bActionChannel *chan;
-                       short a=0;
-                       for(chan=ob->action->chanbase.first; chan; chan= chan->next) {
-                               if(a==te->index) break;
-                               if(chan->ipo) a++;
-                       }
-// XXX                 deselect_actionchannels(ob->action, 0);
-//                     if (chan)
-//                             select_channel(ob->action, chan, SELECT_ADD);
-                       allqueue(REDRAWACTION, ob->ipowin);
-                       allqueue(REDRAWVIEW3D, ob->ipowin);
-               }
-               
-               allqueue(REDRAWIPO, ob->ipowin);
-       }
-       else {
-               if(tes->idcode==ID_AC) {
-                       if(ob->ipoflag & OB_ACTION_OB)
-                               return ob->ipowin==ID_OB;
-                       else if(ob->ipoflag & OB_ACTION_KEY)
-                               return ob->ipowin==ID_KE;
-                       else if(ob->ipowin==ID_AC) {
-                               bActionChannel *chan;
-                               short a=0;
-                               for(chan=ob->action->chanbase.first; chan; chan= chan->next) {
-                                       if(a==te->index) break;
-                                       if(chan->ipo) a++;
-                               }
-// XXX                         if(chan==get_hilighted_action_channel(ob->action)) return 1;
-                       }
-               }
-               else if(ob->ipowin==tes->idcode) {
-                       if(ob->ipowin==ID_MA) {
-                               Material *ma= give_current_material(ob, ob->actcol);
-                               if(ma==(Material *)tselems->id) return 1;
-                       }
-                       else return 1;
-               }
-       }
-       return 0;
-}      
-
 static int tree_element_active_defgroup(Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
 {
        Object *ob;
@@ -1906,7 +1851,6 @@ static int tree_element_active_defgroup(Scene *scene, TreeElement *te, TreeStore
        if(set) {
                ob->actdef= te->index+1;
                DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-               allqueue(REDRAWVIEW3D, ob->ipowin);
        }
        else {
                if(ob==OBACT)
@@ -1915,26 +1859,6 @@ static int tree_element_active_defgroup(Scene *scene, TreeElement *te, TreeStore
        return 0;
 }
 
-static int tree_element_active_nla_action(TreeElement *te, TreeStoreElem *tselem, int set)
-{
-       if(set) {
-               bActionStrip *strip= te->directdata;
-               if(strip) {
-// XXX                 deselect_nlachannel_keys(0);
-                       strip->flag |= ACTSTRIP_SELECT;
-                       allqueue(REDRAWNLA, 0);
-               }
-       }
-       else {
-               /* id in tselem is action */
-               bActionStrip *strip= te->directdata;
-               if(strip) {
-                       if(strip->flag & ACTSTRIP_SELECT) return 1;
-               }
-       }
-       return 0;
-}
-
 static int tree_element_active_posegroup(Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
 {
        Object *ob= (Object *)tselem->id;
@@ -1942,7 +1866,6 @@ static int tree_element_active_posegroup(Scene *scene, TreeElement *te, TreeStor
        if(set) {
                if (ob->pose) {
                        ob->pose->active_group= te->index+1;
-                       allqueue(REDRAWBUTSEDIT, 0);
                }
        }
        else {
@@ -1965,9 +1888,6 @@ static int tree_element_active_posechannel(Scene *scene, TreeElement *te, TreeSt
 //                     else deselectall_posearmature(ob, 0, 0);        // 0 = deselect 
                        pchan->bone->flag |= BONE_SELECTED|BONE_ACTIVE;
                        
-                       allqueue(REDRAWVIEW3D, 0);
-                       allqueue(REDRAWOOPS, 0);
-                       allqueue(REDRAWACTION, 0);
                }
        }
        else {
@@ -1989,9 +1909,6 @@ static int tree_element_active_bone(Scene *scene, TreeElement *te, TreeStoreElem
 //                     else deselectall_posearmature(OBACT, 0, 0);
                        bone->flag |= BONE_SELECTED|BONE_ACTIVE;
                        
-                       allqueue(REDRAWVIEW3D, 0);
-                       allqueue(REDRAWOOPS, 0);
-                       allqueue(REDRAWACTION, 0);
                }
        }
        else {
@@ -2021,9 +1938,6 @@ static int tree_element_active_ebone(TreeElement *te, TreeStoreElem *tselem, int
                        // flush to parent?
                        if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag |= BONE_TIPSEL;
                        
-                       allqueue(REDRAWVIEW3D, 0);
-                       allqueue(REDRAWOOPS, 0);
-                       allqueue(REDRAWACTION, 0);
                }
        }
        else {
@@ -2080,8 +1994,6 @@ static int tree_element_active(Scene *scene, SpaceOops *soops, TreeElement *te,
                        return tree_element_active_world(scene, soops, te, set);
                case ID_LA:
                        return tree_element_active_lamp(scene, soops, te, set);
-               case ID_IP:
-                       return tree_element_active_ipo(scene, soops, te, set);
                case ID_TE:
                        return tree_element_active_texture(scene, soops, te, set);
                case ID_TXT:
@@ -2111,7 +2023,6 @@ static int tree_element_active_sequence(TreeElement *te, TreeStoreElem *tselem,
 
        if(set) {
 // XXX         select_single_seq(seq, 1);
-               allqueue(REDRAWSEQ, 0);
        }
        else {
                if(seq->flag & SELECT)
@@ -2123,7 +2034,7 @@ static int tree_element_active_sequence(TreeElement *te, TreeStoreElem *tselem,
 static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
 {
        Sequence *seq, *p;
-       Editing *ed;
+       Editing *ed= seq_give_editing(scene, FALSE);
 
        seq= (Sequence*)te->directdata;
        if(set==0) {
@@ -2133,7 +2044,6 @@ static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeS
        }
 
 // XXX select_single_seq(seq, 1);
-       ed= scene->ed;
        p= ed->seqbasep->first;
        while(p) {
                if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) {
@@ -2145,7 +2055,6 @@ static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeS
 // XXX                 select_single_seq(p, 0);
                p= p->next;
        }
-       allqueue(REDRAWSEQ, 0);
        return(0);
 }
 
@@ -2155,8 +2064,6 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
 {
        
        switch(tselem->type) {
-               case TSE_NLA_ACTION:
-                       return tree_element_active_nla_action(te, tselem, set);
                case TSE_DEFGROUP:
                        return tree_element_active_defgroup(scene, te, tselem, set);
                case TSE_BONE:
@@ -2229,7 +2136,7 @@ static int do_outliner_mouse_event(bContext *C, Scene *scene, ARegion *ar, Space
                        if(event==LEFTMOUSE) {
                        
                                if (ctrl) {
-                                       if(ELEM9(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) 
+                                       if(ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) 
                                                error("Cannot edit builtin name");
                                        else if(ELEM3(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP))
                                                error("Cannot edit sequence name");
@@ -2249,8 +2156,7 @@ static int do_outliner_mouse_event(bContext *C, Scene *scene, ARegion *ar, Space
                                                /* editmode? */
                                                if(te->idcode==ID_SCE) {
                                                        if(scene!=(Scene *)tselem->id) {
-// XXX                                                         if(obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
-                                                               set_scene((Scene *)tselem->id);
+                                                               ED_screen_set_scene(C, (Scene *)tselem->id);
                                                        }
                                                }
                                                else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) {
@@ -2310,8 +2216,22 @@ static int outliner_activate_click(bContext *C, wmOperator *op, wmEvent *event)
        if(te) {
                BIF_undo_push("Outliner click event");
        }
-       else 
-               outliner_select(ar, soops);
+       else {
+               short selecting= -1;
+               int row;
+               
+               /* get row number - 100 here is just a dummy value since we don't need the column */
+               UI_view2d_listview_view_to_cell(&ar->v2d, 1000, OL_H, 0.0f, 0.0f, 
+                                               fmval[0], fmval[1], NULL, &row);
+               
+               /* select relevant row */
+               outliner_select(soops, &soops->tree, &row, &selecting);
+               
+               // XXX old flag found in old code, do we still use this?
+               //soops->storeflag |= SO_TREESTORE_REDRAW;
+               
+               BIF_undo_push("Outliner selection event");
+       }
        
        ED_region_tag_redraw(ar);
 
@@ -2527,7 +2447,7 @@ void outliner_find_panel(Scene *scene, ARegion *ar, SpaceOops *soops, int again,
 //             else return; /* XXX RETURN! XXX */
        }
 
-       /* do selection and reveil */
+       /* do selection and reveal */
        if (te) {
                tselem= TREESTORE(te);
                if (tselem) {
@@ -2614,64 +2534,46 @@ void outliner_show_hierarchy(Scene *scene, SpaceOops *soops)
        BIF_undo_push("Outliner show hierarchy");
 }
 
-#if 0
-static void do_outliner_select(SpaceOops *soops, ListBase *lb, float y1, float y2, short *selecting)
+void outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting)
 {
        TreeElement *te;
        TreeStoreElem *tselem;
        
-       if(y1>y2) SWAP(float, y1, y2);
-       
-       for(te= lb->first; te; te= te->next) {
+       for (te= lb->first; te && *index >= 0; te=te->next, (*index)--) {
                tselem= TREESTORE(te);
                
-               if(te->ys + OL_H < y1) return;
-               if(te->ys < y2) {
-                       if((te->flag & TE_ICONROW)==0) {
-                               if(*selecting == -1) {
-                                       if( tselem->flag & TSE_SELECTED) *selecting= 0;
-                                       else *selecting= 1;
+               /* if we've encountered the right item, set its 'Outliner' selection status */
+               if (*index == 0) {
+                       /* this should be the last one, so no need to do anything with index */
+                       if ((te->flag & TE_ICONROW)==0) {
+                               /* -1 value means toggle testing for now... */
+                               if (*selecting == -1) {
+                                       if (tselem->flag & TSE_SELECTED) 
+                                               *selecting= 0;
+                                       else 
+                                               *selecting= 1;
                                }
-                               if(*selecting) tselem->flag |= TSE_SELECTED;
-                               else tselem->flag &= ~TSE_SELECTED;
+                               
+                               /* set selection */
+                               if (*selecting) 
+                                       tselem->flag |= TSE_SELECTED;
+                               else 
+                                       tselem->flag &= ~TSE_SELECTED;
                        }
                }
-               if((tselem->flag & TSE_CLOSED)==0) do_outliner_select(soops, &te->subtree, y1, y2, selecting);
-       }
-}
-#endif
-
-/* its own redraw loop... urm */
-void outliner_select(ARegion *ar, SpaceOops *so)
-{
-#if 0
-       XXX
-       float fmval[2], y1, y2;
-       short yo=-1, selecting= -1;
-       
-       UI_view2d_region_to_view(&ar->v2d, event->x, event->y, fmval, fmval+1);
-       
-       y1= fmval[1];
-
-       while (get_mbut() & (L_MOUSE|R_MOUSE)) {
-               UI_view2d_region_to_view(&ar->v2d, event->x, event->y, fmval, fmval+1);
-               y2= fmval[1];
-               
-               if(yo!=mval[1]) {
-                       /* select the 'ouliner row' */
-                       do_outliner_select(so, &so->tree, y1, y2, &selecting);
-                       yo= mval[1];
-                       
-                       so->storeflag |= SO_TREESTORE_REDRAW;
-// XXX                 screen_swapbuffers();
-               
-                       y1= y2;
+               else if ((tselem->flag & TSE_CLOSED)==0) {
+                       /* Only try selecting sub-elements if we haven't hit the right element yet
+                        *
+                        * Hack warning:
+                        *      Index must be reduced before supplying it to the sub-tree to try to do
+                        *      selection, however, we need to increment it again for the next loop to 
+                        *      function correctly
+                        */
+                       (*index)--;
+                       outliner_select(soops, &te->subtree, index, selecting);
+                       (*index)++;
                }
-               else PIL_sleep_ms(30);
        }
-       
-       BIF_undo_push("Outliner selection");
-#endif
 }
 
 /* ************ SELECTION OPERATIONS ********* */
@@ -2918,7 +2820,7 @@ static void outliner_do_object_operation(Scene *scene, SpaceOops *soops, ListBas
                                // when objects selected in other scenes... dunno if that should be allowed
                                Scene *sce= (Scene *)outliner_search_back(soops, te, ID_SCE);
                                if(sce && scene != sce) {
-                                       set_scene(sce);
+// XXX                                 ED_screen_set_scene(C, sce);
                                }
                                
                                operation_cb(te, NULL, tselem);
@@ -2983,7 +2885,6 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem)
 //     Sequence *seq= (Sequence*) te->directdata;
        if(event==1) {
 // XXX         select_single_seq(seq, 1);
-               allqueue(REDRAWSEQ, 0);
        }
 }
 
@@ -3016,7 +2917,6 @@ void outliner_del(Scene *scene, ARegion *ar, SpaceOops *soops)
 //             DAG_scene_sort(scene);
 //             BIF_undo_push("Delete Objects");
 //     }
-//     allqueue(REDRAWALL, 0); 
 }
 
 
@@ -3039,7 +2939,7 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
                                Scene *sce= scene;      // to be able to delete, scenes are set...
                                outliner_do_object_operation(scene, soops, &soops->tree, object_select_cb);
                                if(scene != sce) {
-                                       set_scene(sce);
+// XXX                                 ED_screen_set_scene(C, sce);
                                }
                                
                                str= "Select Objects";
@@ -3071,7 +2971,6 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
                        }
                        
                        BIF_undo_push(str);
-                       allqueue(REDRAWALL, 0);
                }
        }
        else if(idlevel) {
@@ -3089,11 +2988,9 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
                                        case ID_MA:
                                                outliner_do_libdata_operation(soops, &soops->tree, unlink_material_cb);
                                                BIF_undo_push("Unlink material");
-                                               allqueue(REDRAWBUTSSHADING, 1);
                                                break;
                                        case ID_TE:
                                                outliner_do_libdata_operation(soops, &soops->tree, unlink_texture_cb);
-                                               allqueue(REDRAWBUTSSHADING, 1);
                                                BIF_undo_push("Unlink texture");
                                                break;
                                        case ID_GR:
@@ -3103,12 +3000,10 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
                                        default:
                                                error("Not yet...");
                                }
-                               allqueue(REDRAWALL, 0);
                        }
                        else if(event==2) {
                                outliner_do_libdata_operation(soops, &soops->tree, id_local_cb);
                                BIF_undo_push("Localized Data");
-                               allqueue(REDRAWALL, 0); 
                        }
                        else if(event==3 && idlevel==ID_GR) {
                                outliner_do_libdata_operation(soops, &soops->tree, group_linkobs2scene_cb);
@@ -3147,170 +3042,497 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
                                }
                        }
 
-                       allqueue(REDRAWOOPS, 0);
-                       allqueue(REDRAWBUTSALL, 0);
-                       allqueue(REDRAWVIEW3D, 0);
                }
        }
 }
 
+/* ***************** ANIMATO OPERATIONS ********************************** */
+/* KeyingSet and Driver Creation - Helper functions */
 
-/* ***************** DRAW *************** */
+/* specialised poll callback for these operators to work in Datablocks view only */
+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);
+               return (so->outlinevis == SO_DATABLOCKS);
+       }
+       return 0;
+}
+
+
+/* Helper func to extract an RNA path from selected tree element 
+ * NOTE: the caller must zero-out all values of the pointers that it passes here first, as
+ * this function does not do that yet 
+ */
+static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, 
+                                                       ID **id, char **path, int *array_index, short *flag, short *groupmode)
+{
+       ListBase hierarchy = {NULL, NULL};
+       LinkData *ld;
+       TreeElement *tem, *temnext, *temsub;
+       TreeStoreElem *tse, *tsenext;
+       PointerRNA *ptr, *nextptr;
+       PropertyRNA *prop;
+       char *newpath=NULL;
+       
+       /* optimise tricks:
+        *      - Don't do anything if the selected item is a 'struct', but arrays are allowed
+        */
+       if (tselem->type == TSE_RNA_STRUCT)
+               return;
+       
+       /* Overview of Algorithm:
+        *      1. Go up the chain of parents until we find the 'root', taking note of the 
+        *         levels encountered in reverse-order (i.e. items are added to the start of the list
+        *      for more convenient looping later)
+        *      2. Walk down the chain, adding from the first ID encountered 
+        *         (which will become the 'ID' for the KeyingSet Path), and build a  
+        *              path as we step through the chain
+        */
+        
+       /* step 1: flatten out hierarchy of parents into a flat chain */
+       for (tem= te->parent; tem; tem= tem->parent) {
+               ld= MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()");
+               ld->data= tem;
+               BLI_addhead(&hierarchy, ld);
+       }
+       
+       /* step 2: step down hierarchy building the path (NOTE: addhead in previous loop was needed so that we can loop like this) */
+       for (ld= hierarchy.first; ld; ld= ld->next) {
+               /* get data */
+               tem= (TreeElement *)ld->data;
+               tse= TREESTORE(tem);
+               ptr= &tem->rnaptr;
+               prop= tem->directdata;
+               
+               /* check if we're looking for first ID, or appending to path */
+               if (*id) {
+                       /* just 'append' property to path 
+                        *      - to prevent memory leaks, we must write to newpath not path, then free old path + swap them
+                        */
+                       if(tse->type == TSE_RNA_PROPERTY) {
+                               if(RNA_property_type(prop) == PROP_POINTER) {
+                                       /* for pointer we just append property name */
+                                       newpath= RNA_path_append(*path, ptr, prop, 0, NULL);
+                               }
+                               else if(RNA_property_type(prop) == PROP_COLLECTION) {
+                                       char buf[128], *name;
+
+                                       temnext= (TreeElement*)(ld->next->data);
+                                       tsenext= TREESTORE(temnext);
+                                       
+                                       nextptr= &temnext->rnaptr;
+                                       name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
+                                       
+                                       if(name) {
+                                               /* if possible, use name as a key in the path */
+                                               newpath= RNA_path_append(*path, NULL, prop, 0, name);
+                                               
+                                               if(name != buf)
+                                                       MEM_freeN(name);
+                                       }
+                                       else {
+                                               /* otherwise use index */
+                                               int index= 0;
+                                               
+                                               for(temsub=tem->subtree.first; temsub; temsub=temsub->next, index++)
+                                                       if(temsub == temnext)
+                                                               break;
+                                               
+                                               newpath= RNA_path_append(*path, NULL, prop, index, NULL);
+                                       }
+                                       
+                                       ld= ld->next;
+                               }
+                       }
+                       
+                       if(newpath) {
+                               if (*path) MEM_freeN(*path);
+                               *path= newpath;
+                               newpath= NULL;
+                       }
+               }
+               else {
+                       /* no ID, so check if entry is RNA-struct, and if that RNA-struct is an ID datablock to extract info from */
+                       if (tse->type == TSE_RNA_STRUCT) {
+                               /* ptr->data not ptr->id.data seems to be the one we want, since ptr->data is sometimes the owner of this ID? */
+                               if(RNA_struct_is_ID(ptr->type)) {
+                                       *id= (ID *)ptr->data;
+                                       
+                                       /* clear path */
+                                       if(*path) {
+                                               MEM_freeN(*path);
+                                               path= NULL;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* step 3: if we've got an ID, add the current item to the path */
+       if (*id) {
+               /* add the active property to the path */
+               ptr= &te->rnaptr;
+               prop= te->directdata;
+               
+               /* array checks */
+               if (tselem->type == TSE_RNA_ARRAY_ELEM) {
+                       /* item is part of an array, so must set the array_index */
+                       *array_index= te->index;
+               }
+               else if (RNA_property_array_length(prop)) {
+                       /* entire array was selected, so keyframe all */
+                       *flag |= KSP_FLAG_WHOLE_ARRAY;
+               }
+               
+               /* path */
+               newpath= RNA_path_append(*path, NULL, prop, 0, NULL);
+               if (*path) MEM_freeN(*path);
+               *path= newpath;
+       }
+
+       /* free temp data */
+       BLI_freelistN(&hierarchy);
+}
+
+/* ***************** KEYINGSET OPERATIONS *************** */
+
+/* These operators are only available in databrowser mode for now, as
+ * they depend on having RNA paths and/or hierarchies available.
+ */
+enum {
+       DRIVERS_EDITMODE_ADD    = 0,
+       DRIVERS_EDITMODE_REMOVE,
+} eDrivers_EditModes;
+
+/* Utilities ---------------------------------- */ 
+
+/* Recursively iterate over tree, finding and working on selected items */
+static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, short mode)
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       for (te= tree->first; te; te=te->next) {
+               tselem= TREESTORE(te);
+               
+               /* if item is selected, perform operation */
+               if (tselem->flag & TSE_SELECTED) {
+                       ID *id= NULL;
+                       char *path= NULL;
+                       int array_index= 0;
+                       short flag= 0;
+                       short groupmode= KSP_GROUP_KSNAME;
+                       
+                       /* check if RNA-property described by this selected element is an animateable prop */
+                       if ((tselem->type == TSE_RNA_PROPERTY) && RNA_property_animateable(&te->rnaptr, te->directdata)) {
+                               /* get id + path + index info from the selected element */
+                               tree_element_to_path(soops, te, tselem, 
+                                               &id, &path, &array_index, &flag, &groupmode);
+                       }
+                       
+                       /* only if ID and path were set, should we perform any actions */
+                       if (id && path) {
+                               /* action depends on mode */
+                               switch (mode) {
+                                       case DRIVERS_EDITMODE_ADD:
+                                       {
+                                               /* add a new driver with the information obtained (only if valid) */
+                                               ANIM_add_driver(id, path, array_index, flag);
+                                       }
+                                               break;
+                                       case DRIVERS_EDITMODE_REMOVE:
+                                       {
+                                               /* remove driver matching the information obtained (only if valid) */
+                                               ANIM_remove_driver(id, path, array_index, flag);
+                                       }
+                                               break;
+                               }
+                               
+                               /* free path, since it had to be generated */
+                               MEM_freeN(path);
+                       }
+                       
+                       
+               }
+               
+               /* go over sub-tree */
+               if ((tselem->flag & TSE_CLOSED)==0)
+                       do_outliner_drivers_editop(soops, &te->subtree, mode);
+       }
+}
+
+/* Add Operator ---------------------------------- */
+
+static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op)
+{
+       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       
+       /* check for invalid states */
+       if (soutliner == NULL)
+               return OPERATOR_CANCELLED;
+       
+       /* recursively go into tree, adding selected items */
+       do_outliner_drivers_editop(soutliner, &soutliner->tree, DRIVERS_EDITMODE_ADD);
+       
+       /* send notifiers */
+       WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_drivers_add(wmOperatorType *ot)
+{
+       /* api callbacks */
+       ot->idname= "OUTLINER_OT_drivers_add";
+       ot->name= "Add Drivers";
+       ot->description= "Add drivers to selected items.";
+       
+       /* api callbacks */
+       ot->exec= outliner_drivers_addsel_exec;
+       ot->poll= ed_operator_outliner_datablocks_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+}
 
-static int tselem_rna_icon(PointerRNA *ptr)
+
+/* Remove Operator ---------------------------------- */
+
+static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op)
 {
-       StructRNA *rnatype= ptr->type;
-
-       if(rnatype == &RNA_Scene)
-               return ICON_SCENE_DEHLT;
-       else if(rnatype == &RNA_World)
-               return ICON_WORLD;
-       else if(rnatype == &RNA_Object)
-               return ICON_OBJECT;
-       else if(rnatype == &RNA_Mesh)
-               return ICON_MESH;
-       else if(rnatype == &RNA_MeshVertex)
-               return ICON_VERTEXSEL;
-       else if(rnatype == &RNA_MeshEdge)
-               return ICON_EDGESEL;
-       else if(rnatype == &RNA_MeshFace)
-               return ICON_FACESEL;
-       else if(rnatype == &RNA_MeshTextureFace)
-               return ICON_FACESEL_HLT;
-       else if(rnatype == &RNA_MeshVertexGroup)
-               return ICON_VGROUP;
-       else if(rnatype == &RNA_Curve)
-               return ICON_CURVE;
-       else if(rnatype == &RNA_MetaBall)
-               return ICON_MBALL;
-       else if(rnatype == &RNA_MetaElement)
-               return ICON_OUTLINER_DATA_META;
-       else if(rnatype == &RNA_Lattice)
-               return ICON_LATTICE;
-       else if(rnatype == &RNA_Armature)
-               return ICON_ARMATURE;
-       else if(rnatype == &RNA_Bone)
-               return ICON_BONE_DEHLT;
-       else if(rnatype == &RNA_Camera)
-               return ICON_CAMERA;
-       else if(rnatype == &RNA_Lamp)
-               return ICON_LAMP;
-       else if(rnatype == &RNA_Group)
-               return ICON_GROUP;
-       else if(rnatype == &RNA_ParticleSystem)
-               return ICON_PARTICLES;
-       else if(rnatype == &RNA_ParticleSettings)
-               return ICON_PARTICLES;
-       else if(rnatype == &RNA_Material)
-               return ICON_MATERIAL;
-       else if(rnatype == &RNA_Texture)
-               return ICON_TEXTURE;
-       else if(rnatype == &RNA_Image)
-               return ICON_TEXTURE;
-       else if(rnatype == &RNA_Screen)
-               return ICON_SPLITSCREEN;
-       else if(rnatype == &RNA_NodeTree)
-               return ICON_NODE;
-       else if(rnatype == &RNA_Text)
-               return ICON_TEXT;
-       else if(rnatype == &RNA_Sound)
-               return ICON_SOUND;
-       else if(rnatype == &RNA_Brush)
-               return ICON_TPAINT_HLT;
-       else if(rnatype == &RNA_Library)
-               return ICON_LIBRARY_DEHLT;
-       /*else if(rnatype == &RNA_Action)
-               return ICON_ACTION;*/
-       else if(rnatype == &RNA_Ipo)
-               return ICON_IPO_DEHLT;
-       else if(rnatype == &RNA_Key)
-               return ICON_SHAPEKEY;
-       else if(rnatype == &RNA_Main)
-               return ICON_BLENDER;
-       else if(rnatype == &RNA_Struct)
-               return ICON_RNA;
-       else if(rnatype == &RNA_Property)
-               return ICON_RNA;
-       else if(rnatype == &RNA_BooleanProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_IntProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_FloatProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_StringProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_EnumProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_EnumPropertyItem)
-               return ICON_RNA;
-       else if(rnatype == &RNA_PointerProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_CollectionProperty)
-               return ICON_RNA;
-       else if(rnatype == &RNA_ObjectGameSettings)
-               return ICON_GAME;
-       else if(rnatype == &RNA_ScriptLink)
-               return ICON_PYTHON;
-       
-       /* modifiers */
-       else if(rnatype == &RNA_SubsurfModifier)
-               return ICON_MOD_SUBSURF;
-       else if(rnatype == &RNA_ArmatureModifier)
-               return ICON_ARMATURE;
-       else if(rnatype == &RNA_LatticeModifier)
-               return ICON_LATTICE;
-       else if(rnatype == &RNA_CurveModifier)
-               return ICON_CURVE;
-       else if(rnatype == &RNA_BuildModifier)
-               return ICON_MOD_BUILD;
-       else if(rnatype == &RNA_MirrorModifier)
-               return ICON_MOD_MIRROR;
-       else if(rnatype == &RNA_DecimateModifier)
-               return ICON_MOD_DECIM;
-       else if(rnatype == &RNA_WaveModifier)
-               return ICON_MOD_WAVE;
-       else if(rnatype == &RNA_HookModifier)
-               return ICON_HOOK;
-       else if(rnatype == &RNA_SoftbodyModifier)
-               return ICON_MOD_SOFT;
-       else if(rnatype == &RNA_BooleanModifier)
-               return ICON_MOD_BOOLEAN;
-       else if(rnatype == &RNA_ParticleInstanceModifier)
-               return ICON_MOD_PARTICLEINSTANCE;
-       else if(rnatype == &RNA_ParticleSystemModifier)
-               return ICON_MOD_PARTICLES;
-       else if(rnatype == &RNA_EdgeSplitModifier)
-               return ICON_MOD_EDGESPLIT;
-       else if(rnatype == &RNA_ArrayModifier)
-               return ICON_MOD_ARRAY;
-       else if(rnatype == &RNA_UVProjectModifier)
-               return ICON_MOD_UVPROJECT;
-       else if(rnatype == &RNA_DisplaceModifier)
-               return ICON_MOD_DISPLACE;
-       
-       else
-               return ICON_DOT;
+       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       
+       /* check for invalid states */
+       if (soutliner == NULL)
+               return OPERATOR_CANCELLED;
+       
+       /* recursively go into tree, adding selected items */
+       do_outliner_drivers_editop(soutliner, &soutliner->tree, DRIVERS_EDITMODE_REMOVE);
+       
+       /* send notifiers */
+       WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
+       
+       return OPERATOR_FINISHED;
 }
 
+void OUTLINER_OT_drivers_delete(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->idname= "OUTLINER_OT_drivers_delete";
+       ot->name= "Delete Drivers";
+       ot->description= "Delete drivers assigned to selected items.";
+       
+       /* api callbacks */
+       ot->exec= outliner_drivers_deletesel_exec;
+       ot->poll= ed_operator_outliner_datablocks_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+}
+
+/* ***************** KEYINGSET OPERATIONS *************** */
+
+/* These operators are only available in databrowser mode for now, as
+ * they depend on having RNA paths and/or hierarchies available.
+ */
+enum {
+       KEYINGSET_EDITMODE_ADD  = 0,
+       KEYINGSET_EDITMODE_REMOVE,
+} eKeyingSet_EditModes;
+
+/* Utilities ---------------------------------- */ 
+/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */
+// TODO: should this be an API func?
+static KeyingSet *verify_active_keyingset(Scene *scene, short add)
+{
+       KeyingSet *ks= NULL;
+       
+       /* sanity check */
+       if (scene == NULL)
+               return NULL;
+       
+       /* try to find one from scene */
+       if (scene->active_keyingset > 0)
+               ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+               
+       /* add if none found */
+       // XXX the default settings have yet to evolve
+       if ((add) && (ks==NULL)) {
+               ks= BKE_keyingset_add(&scene->keyingsets, "Keying Set", KEYINGSET_ABSOLUTE, 0);
+               scene->active_keyingset= BLI_countlist(&scene->keyingsets);
+       }
+       
+       return ks;
+}
+
+/* Recursively iterate over tree, finding and working on selected items */
+static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode)
+{
+       TreeElement *te;
+       TreeStoreElem *tselem;
+       
+       for (te= tree->first; te; te=te->next) {
+               tselem= TREESTORE(te);
+               
+               /* if item is selected, perform operation */
+               if (tselem->flag & TSE_SELECTED) {
+                       ID *id= NULL;
+                       char *path= NULL;
+                       int array_index= 0;
+                       short flag= 0;
+                       short groupmode= KSP_GROUP_KSNAME;
+                       
+                       /* check if RNA-property described by this selected element is an animateable prop */
+                       if ((tselem->type == TSE_RNA_PROPERTY) && RNA_property_animateable(&te->rnaptr, te->directdata)) {
+                               /* get id + path + index info from the selected element */
+                               tree_element_to_path(soops, te, tselem, 
+                                               &id, &path, &array_index, &flag, &groupmode);
+                       }
+                       
+                       /* only if ID and path were set, should we perform any actions */
+                       if (id && path) {
+                               /* action depends on mode */
+                               switch (mode) {
+                                       case KEYINGSET_EDITMODE_ADD:
+                                       {
+                                               /* add a new path with the information obtained (only if valid) */
+                                               // TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name
+                                               BKE_keyingset_add_destination(ks, id, NULL, path, array_index, flag, groupmode);
+                                       }
+                                               break;
+                                       case KEYINGSET_EDITMODE_REMOVE:
+                                       {
+                                               /* find the relevant path, then remove it from the KeyingSet */
+                                               KS_Path *ksp= BKE_keyingset_find_destination(ks, id, NULL, path, array_index, groupmode);
+                                               
+                                               if (ksp) {
+                                                       /* free path's data */
+                                                       // TODO: we probably need an API method for this 
+                                                       if (ksp->rna_path) MEM_freeN(ksp->rna_path);
+                                                       
+                                                       /* remove path from set */
+                                                       BLI_freelinkN(&ks->paths, ksp);
+                                               }
+                                       }
+                                               break;
+                               }
+                               
+                               /* free path, since it had to be generated */
+                               MEM_freeN(path);
+                       }
+                       
+                       
+               }
+               
+               /* go over sub-tree */
+               if ((tselem->flag & TSE_CLOSED)==0)
+                       do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
+       }
+}
+
+/* Add Operator ---------------------------------- */
+
+static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
+{
+       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks= verify_active_keyingset(scene, 1);
+       
+       /* check for invalid states */
+       if (ks == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set");
+               return OPERATOR_CANCELLED;
+       }
+       if (soutliner == NULL)
+               return OPERATOR_CANCELLED;
+       
+       /* recursively go into tree, adding selected items */
+       do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD);
+       
+       /* send notifiers */
+       WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->idname= "OUTLINER_OT_keyingset_add_selected";
+       ot->name= "Keyingset Add Selected";
+       
+       /* api callbacks */
+       ot->exec= outliner_keyingset_additems_exec;
+       ot->poll= ed_operator_outliner_datablocks_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+}
+
+
+/* Remove Operator ---------------------------------- */
+
+static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *op)
+{
+       SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C);
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks= verify_active_keyingset(scene, 1);
+       
+       /* check for invalid states */
+       if (soutliner == NULL)
+               return OPERATOR_CANCELLED;
+       
+       /* recursively go into tree, adding selected items */
+       do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE);
+       
+       /* send notifiers */
+       WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->idname= "OUTLINER_OT_keyingset_remove_selected";
+       ot->name= "Keyingset Remove Selected";
+       
+       /* api callbacks */
+       ot->exec= outliner_keyingset_removeitems_exec;
+       ot->poll= ed_operator_outliner_datablocks_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_UNDO;
+}
+
+/* ***************** DRAW *************** */
+
 static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElement *te)
 {
        if(tselem->type) {
                switch( tselem->type) {
+                       case TSE_ANIM_DATA:
+                               UI_icon_draw(x, y, ICON_ANIM_DATA); break; // xxx
                        case TSE_NLA:
                                UI_icon_draw(x, y, ICON_NLA); break;
+                       case TSE_NLA_TRACK:
+                               UI_icon_draw(x, y, ICON_NLA); break; // XXX
                        case TSE_NLA_ACTION:
                                UI_icon_draw(x, y, ICON_ACTION); break;
                        case TSE_DEFGROUP_BASE:
-                               UI_icon_draw(x, y, ICON_VGROUP); break;
+                               UI_icon_draw(x, y, ICON_GROUP_VERTEX); break;
                        case TSE_BONE:
                        case TSE_EBONE:
-                               UI_icon_draw(x, y, ICON_BONE_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_BONE_DATA); break;
                        case TSE_CONSTRAINT_BASE:
                                UI_icon_draw(x, y, ICON_CONSTRAINT); break;
                        case TSE_MODIFIER_BASE:
                                UI_icon_draw(x, y, ICON_MODIFIER); break;
                        case TSE_LINKED_OB:
-                               UI_icon_draw(x, y, ICON_OBJECT); break;
+                               UI_icon_draw(x, y, ICON_OBJECT_DATA); break;
                        case TSE_LINKED_PSYS:
                                UI_icon_draw(x, y, ICON_PARTICLES); break;
                        case TSE_MODIFIER:
@@ -3321,11 +3543,11 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                        case eModifierType_Subsurf: 
                                                UI_icon_draw(x, y, ICON_MOD_SUBSURF); break;
                                        case eModifierType_Armature: 
-                                               UI_icon_draw(x, y, ICON_ARMATURE); break;
+                                               UI_icon_draw(x, y, ICON_MOD_ARMATURE); break;
                                        case eModifierType_Lattice: 
-                                               UI_icon_draw(x, y, ICON_LATTICE); break;
+                                               UI_icon_draw(x, y, ICON_MOD_LATTICE); break;
                                        case eModifierType_Curve: 
-                                               UI_icon_draw(x, y, ICON_CURVE); break;
+                                               UI_icon_draw(x, y, ICON_MOD_CURVE); break;
                                        case eModifierType_Build: 
                                                UI_icon_draw(x, y, ICON_MOD_BUILD); break;
                                        case eModifierType_Mirror: 
@@ -3341,7 +3563,7 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                        case eModifierType_Boolean: 
                                                UI_icon_draw(x, y, ICON_MOD_BOOLEAN); break;
                                        case eModifierType_ParticleSystem: 
-                                               UI_icon_draw(x, y, ICON_MOD_PARTICLEINSTANCE); break;
+                                               UI_icon_draw(x, y, ICON_MOD_PARTICLES); break;
                                        case eModifierType_ParticleInstance:
                                                UI_icon_draw(x, y, ICON_MOD_PARTICLES); break;
                                        case eModifierType_EdgeSplit:
@@ -3352,6 +3574,30 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                                UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break;
                                        case eModifierType_Displace:
                                                UI_icon_draw(x, y, ICON_MOD_DISPLACE); break;
+                                       case eModifierType_Shrinkwrap:
+                                               UI_icon_draw(x, y, ICON_MOD_SHRINKWRAP); break;
+                                       case eModifierType_Cast:
+                                               UI_icon_draw(x, y, ICON_MOD_CAST); break;
+                                       case eModifierType_MeshDeform:
+                                               UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break;
+                                       case eModifierType_Bevel:
+                                               UI_icon_draw(x, y, ICON_MOD_BEVEL); break;
+                                       case eModifierType_Smooth:
+                                               UI_icon_draw(x, y, ICON_MOD_SMOOTH); break;
+                                       case eModifierType_SimpleDeform:
+                                               UI_icon_draw(x, y, ICON_MOD_SIMPLEDEFORM); break;
+                                       case eModifierType_Mask:
+                                               UI_icon_draw(x, y, ICON_MOD_MASK); break;
+                                       case eModifierType_Cloth:
+                                               UI_icon_draw(x, y, ICON_MOD_CLOTH); break;
+                                       case eModifierType_Explode:
+                                               UI_icon_draw(x, y, ICON_MOD_EXPLODE); break;
+                                       case eModifierType_Collision:
+                                               UI_icon_draw(x, y, ICON_MOD_PHYSICS); break;
+                                       case eModifierType_Fluidsim:
+                                               UI_icon_draw(x, y, ICON_MOD_FLUIDSIM); break;
+                                       case eModifierType_Multires:
+                                               UI_icon_draw(x, y, ICON_MOD_MULTIRES); break;
                                        default:
                                                UI_icon_draw(x, y, ICON_DOT); break;
                                }
@@ -3360,19 +3606,19 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                        case TSE_SCRIPT_BASE:
                                UI_icon_draw(x, y, ICON_TEXT); break;
                        case TSE_POSE_BASE:
-                               UI_icon_draw(x, y, ICON_ARMATURE); break;
+                               UI_icon_draw(x, y, ICON_ARMATURE_DATA); break;
                        case TSE_POSE_CHANNEL:
-                               UI_icon_draw(x, y, ICON_BONE_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_BONE_DATA); break;
                        case TSE_PROXY:
                                UI_icon_draw(x, y, ICON_GHOST); break;
                        case TSE_R_LAYER_BASE:
-                               UI_icon_draw(x, y, ICON_RESTRICT_RENDER_OFF); break;
+                               UI_icon_draw(x, y, ICON_RENDERLAYERS); break;
                        case TSE_R_LAYER:
-                               UI_icon_draw(x, y, ICON_IMAGE_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_RENDER_RESULT); break;
                        case TSE_LINKED_LAMP:
-                               UI_icon_draw(x, y, ICON_LAMP_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_LAMP_DATA); break;
                        case TSE_LINKED_MAT:
-                               UI_icon_draw(x, y, ICON_MATERIAL_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_MATERIAL_DATA); break;
                        case TSE_POSEGRP_BASE:
                                UI_icon_draw(x, y, ICON_VERTEXSEL); break;
                        case TSE_SEQUENCE:
@@ -3390,13 +3636,13 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                        UI_icon_draw(x, y, ICON_PARTICLES);
                                break;
                        case TSE_SEQ_STRIP:
-                               UI_icon_draw(x, y, ICON_LIBRARY_DEHLT);
+                               UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT);
                                break;
                        case TSE_SEQUENCE_DUP:
-                               UI_icon_draw(x, y, ICON_OBJECT);
+                               UI_icon_draw(x, y, ICON_OBJECT_DATA);
                                break;
                        case TSE_RNA_STRUCT:
-                               UI_icon_draw(x, y, tselem_rna_icon(&te->rnaptr));
+                               UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type));
                                break;
                        default:
                                UI_icon_draw(x, y, ICON_DOT); break;
@@ -3419,6 +3665,10 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                UI_icon_draw(x, y, ICON_OUTLINER_OB_LATTICE); break;
                        case OB_ARMATURE: 
                                UI_icon_draw(x, y, ICON_OUTLINER_OB_ARMATURE); break;
+                       case OB_FONT: 
+                               UI_icon_draw(x, y, ICON_OUTLINER_OB_FONT); break;
+                       case OB_SURF: 
+                               UI_icon_draw(x, y, ICON_OUTLINER_OB_SURFACE); break;
                        case OB_EMPTY: 
                                UI_icon_draw(x, y, ICON_OUTLINER_OB_EMPTY); break;
                
@@ -3427,7 +3677,7 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
        else {
                switch( GS(tselem->id->name)) {
                        case ID_SCE:
-                               UI_icon_draw(x, y, ICON_SCENE_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_SCENE_DATA); break;
                        case ID_ME:
                                UI_icon_draw(x, y, ICON_OUTLINER_DATA_MESH); break;
                        case ID_CU:
@@ -3437,15 +3687,31 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                        case ID_LT:
                                UI_icon_draw(x, y, ICON_OUTLINER_DATA_LATTICE); break;
                        case ID_LA:
-                               UI_icon_draw(x, y, ICON_OUTLINER_DATA_LAMP); break;
+                       {
+                               Lamp *la= (Lamp *)tselem->id;
+                               
+                               switch(la->type) {
+                                       case LA_LOCAL:
+                                               UI_icon_draw(x, y, ICON_LAMP_POINT); break;
+                                       case LA_SUN:
+                                               UI_icon_draw(x, y, ICON_LAMP_SUN); break;
+                                       case LA_SPOT:
+                                               UI_icon_draw(x, y, ICON_LAMP_SPOT); break;
+                                       case LA_HEMI:
+                                               UI_icon_draw(x, y, ICON_LAMP_HEMI); break;
+                                       case LA_AREA:
+                                               UI_icon_draw(x, y, ICON_LAMP_AREA); break;
+                                       default:
+                                               UI_icon_draw(x, y, ICON_OUTLINER_DATA_LAMP); break;
+                               }
+                               break;
+                       }
                        case ID_MA:
-                               UI_icon_draw(x, y, ICON_MATERIAL_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_MATERIAL_DATA); break;
                        case ID_TE:
-                               UI_icon_draw(x, y, ICON_TEXTURE_DEHLT); break;
-                       case ID_IP:
-                               UI_icon_draw(x, y, ICON_IPO_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_TEXTURE_DATA); break;
                        case ID_IM:
-                               UI_icon_draw(x, y, ICON_IMAGE_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_IMAGE_DATA); break;
                        case ID_SO:
                                UI_icon_draw(x, y, ICON_SPEAKER); break;
                        case ID_AR:
@@ -3453,9 +3719,9 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                        case ID_CA:
                                UI_icon_draw(x, y, ICON_OUTLINER_DATA_CAMERA); break;
                        case ID_KE:
-                               UI_icon_draw(x, y, ICON_SHAPEKEY); break;
+                               UI_icon_draw(x, y, ICON_SHAPEKEY_DATA); break;
                        case ID_WO:
-                               UI_icon_draw(x, y, ICON_WORLD_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_WORLD_DATA); break;
                        case ID_AC:
                                UI_icon_draw(x, y, ICON_ACTION); break;
                        case ID_NLA:
@@ -3465,7 +3731,7 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                        case ID_GR:
                                UI_icon_draw(x, y, ICON_GROUP); break;
                        case ID_LI:
-                               UI_icon_draw(x, y, ICON_LIBRARY_DEHLT); break;
+                               UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT); break;
                }
        }
 }
@@ -3580,7 +3846,7 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo
                /* open/close icon, only when sublevels, except for scene */
                if(te->subtree.first || (tselem->type==0 && te->idcode==ID_SCE) || (te->flag & TE_LAZY_CLOSED)) {
                        int icon_x;
-                       if((tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) || ELEM4(te->idcode,ID_VN,ID_VS, ID_MS, ID_SS))
+                       if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE))
                                icon_x = startx;
                        else
                                icon_x = startx+5;
@@ -3606,9 +3872,9 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo
                if(tselem->type==0 && tselem->id->lib) {
                        glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
                        if(tselem->id->flag & LIB_INDIRECT)
-                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_HLT);
+                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_INDIRECT);
                        else
-                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DEHLT);
+                               UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_DIRECT);
                        glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
                        offsx+= OL_X;
                }               
@@ -3618,10 +3884,10 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo
                if(active==1) UI_ThemeColor(TH_TEXT_HI);
                else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f);
                else UI_ThemeColor(TH_TEXT);
-               glRasterPos2i(startx+offsx, *starty+5);
-               UI_RasterPos((float)startx+offsx, (float)*starty+5);
-               UI_DrawString(G.font, te->name, 0);
-               offsx+= (int)(OL_X + UI_GetStringWidth(G.font, te->name, 0));
+               
+               UI_DrawString(startx+offsx, *starty+5, te->name);
+               
+               offsx+= (int)(OL_X + UI_GetStringWidth(te->name));
                
                /* closed item, we draw the icons, not when it's a scene, or master-server list though */
                if(tselem->flag & TSE_CLOSED) {
@@ -3672,7 +3938,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
                tselem= TREESTORE(te);
                
                /* horizontal line? */
-               if((tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE)) || ELEM4(te->idcode,ID_VS,ID_VN,ID_MS,ID_SS))
+               if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE))
                        glRecti(startx, *starty, startx+OL_X, *starty-1);
                        
                *starty-= OL_H;
@@ -3685,7 +3951,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
        te= lb->last;
        if(te->parent || lb->first!=lb->last) {
                tselem= TREESTORE(te);
-               if((tselem->type==0 && te->idcode==ID_OB) || ELEM4(te->idcode,ID_VS,ID_VN,ID_MS,ID_SS)) {
+               if(tselem->type==0 && te->idcode==ID_OB) {
                        
                        glRecti(startx, y1+OL_H, startx+1, y2);
                }
@@ -3709,7 +3975,7 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
                if((tselem->flag & TSE_CLOSED)==0) {
                        outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
                        if(tselem->type == TSE_RNA_STRUCT)
-                               fdrawline(0, *starty+OL_H-1, (int)ar->v2d.cur.xmax, *starty+OL_H-1);
+                               fdrawline(0, (float)*starty+OL_H-1, ar->v2d.cur.xmax, (float)*starty+OL_H-1);
                }
        }
 }
@@ -3739,26 +4005,28 @@ static void outliner_draw_tree(Scene *scene, ARegion *ar, SpaceOops *soops)
        float col[4];
        
 #if 0 // XXX was #ifdef INTERNATIONAL
+       /* Maybe the INTERNATIONAL was really for check about freetype2 ?
+        * anyway I think that we can remove this now - Diego
+        */
        FTF_SetFontSize('l');
        BIF_SetScale(1.0);
 #endif
        
        glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA); // only once
        
-       if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
-               // struct marks
+       if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
+               /* struct marks */
                UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
                //UI_ThemeColorShade(TH_BACK, -20);
                starty= (int)ar->v2d.tot.ymax-OL_H;
                outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
        }
-       else {
-               // selection first
-               UI_GetThemeColor3fv(TH_BACK, col);
-               glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f);
-               starty= (int)ar->v2d.tot.ymax-OL_H;
-               outliner_draw_selection(ar, soops, &soops->tree, &starty);
-       }
+       
+       /* always draw selection fill before hierarchy */
+       UI_GetThemeColor3fv(TH_BACK, col);
+       glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f);
+       starty= (int)ar->v2d.tot.ymax-OL_H;
+       outliner_draw_selection(ar, soops, &soops->tree, &starty);
        
        // grey hierarchy lines
        UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.2f);
@@ -3846,8 +4114,6 @@ static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
                }
        }
 
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWVIEW3D, 0);
 }
 
 static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2)
@@ -3869,21 +4135,15 @@ static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2)
                }
        }
 
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWVIEW3D, 0);
 }
 
 static void restrictbutton_rend_cb(bContext *C, void *poin, void *poin2)
 {
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWVIEW3D, 0);
 }
 
 static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *poin2)
 {
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWNODE, 0);
-       allqueue(REDRAWBUTSSCENE, 0);
+       /* XXX redraws */
 }
 
 static void restrictbutton_modifier_cb(bContext *C, void *poin, void *poin2)
@@ -3892,19 +4152,13 @@ static void restrictbutton_modifier_cb(bContext *C, void *poin, void *poin2)
        Object *ob = (Object *)poin2;
        
        DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-       object_handle_update(ob);
+       object_handle_update(scene, ob);
 
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWBUTSEDIT, 0);
-       allqueue(REDRAWBUTSOBJECT, 0);
 }
 
 static void restrictbutton_bone_cb(bContext *C, void *poin, void *poin2)
 {
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWBUTSEDIT, 0);
+       /* XXX redraws */
 }
 
 static void namebutton_cb(bContext *C, void *tep, void *oldnamep)
@@ -3934,7 +4188,6 @@ static void namebutton_cb(bContext *C, void *tep, void *oldnamep)
                        switch(tselem->type) {
                        case TSE_DEFGROUP:
                                unique_vertexgroup_name(te->directdata, (Object *)tselem->id); //       id = object
-                               allqueue(REDRAWBUTSEDIT, 0);
                                break;
                        case TSE_NLA_ACTION:
                                test_idbutton(tselem->id->name+2);
@@ -3951,9 +4204,6 @@ static void namebutton_cb(bContext *C, void *tep, void *oldnamep)
                                        BLI_strncpy(ebone->name, oldnamep, 32);
 // XXX                                 armature_bone_rename(obedit->data, oldnamep, newname);
                                }
-                               allqueue(REDRAWOOPS, 0);
-                               allqueue(REDRAWVIEW3D, 1);
-                               allqueue(REDRAWBUTSEDIT, 0);
                        }
                                break;
 
@@ -3972,9 +4222,6 @@ static void namebutton_cb(bContext *C, void *tep, void *oldnamep)
                                        BLI_strncpy(bone->name, oldnamep, 32);
 // XXX                                 armature_bone_rename(ob->data, oldnamep, newname);
                                }
-                               allqueue(REDRAWOOPS, 0);
-                               allqueue(REDRAWVIEW3D, 1);
-                               allqueue(REDRAWBUTSEDIT, 0);
                                break;
                        case TSE_POSE_CHANNEL:
                                {
@@ -3991,22 +4238,16 @@ static void namebutton_cb(bContext *C, void *tep, void *oldnamep)
                                        BLI_strncpy(pchan->name, oldnamep, 32);
 // XXX                                 armature_bone_rename(ob->data, oldnamep, newname);
                                }
-                               allqueue(REDRAWOOPS, 0);
-                               allqueue(REDRAWVIEW3D, 1);
-                               allqueue(REDRAWBUTSEDIT, 0);
                                break;
                        case TSE_POSEGRP:
                                {
                                        Object *ob= (Object *)tselem->id; // id = object
                                        bActionGroup *grp= te->directdata;
                                        
-                                       BLI_uniquename(&ob->pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
-                                       allqueue(REDRAWBUTSEDIT, 0);
+                                       BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), 32);
                                }
                                break;
                        case TSE_R_LAYER:
-                               allqueue(REDRAWOOPS, 0);
-                               allqueue(REDRAWBUTSSCENE, 0);
                                break;
                        }
                }
@@ -4028,20 +4269,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                ob = (Object *)tselem->id;
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
-                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, REDRAWALL, ICON_RESTRICT_VIEW_OFF, 
+                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, 0, ICON_RESTRICT_VIEW_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                                
-                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_SELECT, REDRAWALL, ICON_RESTRICT_SELECT_OFF, 
+                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_SELECT, 0, ICON_RESTRICT_SELECT_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
                                uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                                
-                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_RENDER, REDRAWALL, ICON_RESTRICT_RENDER_OFF, 
+                               bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_RENDER, 0, ICON_RESTRICT_RENDER_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (short)te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow renderability");
                                uiButSetFunc(bt, restrictbutton_rend_cb, NULL, NULL);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                                
                                uiBlockSetEmboss(block, UI_EMBOSS);
                        }
@@ -4049,7 +4287,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                        else if(tselem->type==TSE_R_LAYER) {
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                
-                               bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1, 
+                               bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1, 
                                                                         (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
                                
@@ -4060,13 +4298,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                uiBlockSetEmboss(block, UI_EMBOSSN);
                                
                                /* NOTE: tselem->nr is short! */
-                               bt= uiDefIconButBitI(block, ICONTOG, tselem->nr, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1, 
+                               bt= uiDefIconButBitI(block, ICONTOG, tselem->nr, 0, ICON_CHECKBOX_HLT-1, 
                                                                         (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
                                
                                layflag++;      /* is lay_xor */
                                if(ELEM6(tselem->nr, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_RADIO))
-                                       bt= uiDefIconButBitI(block, TOG, tselem->nr, REDRAWBUTSSCENE, (*layflag & tselem->nr)?ICON_DOT:ICON_BLANK1, 
+                                       bt= uiDefIconButBitI(block, TOG, tselem->nr, 0, (*layflag & tselem->nr)?ICON_DOT:ICON_BLANK1, 
                                                                         (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
                                uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
                                
@@ -4077,34 +4315,30 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
                                ob = (Object *)tselem->id;
                                
                                uiBlockSetEmboss(block, UI_EMBOSSN);
-                               bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, REDRAWALL, ICON_RESTRICT_VIEW_OFF, 
+                               bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                                
-                               bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, REDRAWALL, ICON_RESTRICT_RENDER_OFF, 
+                               bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (short)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
                                uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                        }
                        else if(tselem->type==TSE_POSE_CHANNEL)  {
                                bPoseChannel *pchan= (bPoseChannel *)te->directdata;
                                Bone *bone = pchan->bone;
 
                                uiBlockSetEmboss(block, UI_EMBOSSN);
-                               bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, REDRAWALL, ICON_RESTRICT_VIEW_OFF, 
+                               bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                        }
                        else if(tselem->type==TSE_EBONE)  {
                                EditBone *ebone= (EditBone *)te->directdata;
 
                                uiBlockSetEmboss(block, UI_EMBOSSN);
-                               bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, REDRAWALL, ICON_RESTRICT_VIEW_OFF, 
+                               bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, 
                                                (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
                                uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
-                               uiButSetFlag(bt, UI_NO_HILITE);
                        }
                }
                
@@ -4114,93 +4348,20 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
 
 static void outliner_draw_rnacols(ARegion *ar, SpaceOops *soops, int sizex)
 {
-       int xstart= MAX2(OL_RNA_COLX, sizex+OL_RNA_COL_SPACEX);
+       View2D *v2d= &ar->v2d;
        
        UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
 
-       /* view */
-       fdrawline(xstart,
-               ar->v2d.cur.ymax,
-               xstart,
-               ar->v2d.cur.ymin);
+       /* draw column separator lines */
+       fdrawline((float)sizex,
+               v2d->cur.ymax,
+               (float)sizex,
+               v2d->cur.ymin);
 
-       fdrawline(xstart+OL_RNA_COL_SIZEX,
-               ar->v2d.cur.ymax,
-               xstart+OL_RNA_COL_SIZEX,
-               ar->v2d.cur.ymin);
-}
-
-static uiBut *outliner_draw_rnabut(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, int x1, int y1, int x2, int y2)
-{
-       uiBut *but=NULL;
-       const char *propname= RNA_property_identifier(ptr, prop);
-       int arraylen= RNA_property_array_length(ptr, prop);
-
-       switch(RNA_property_type(ptr, prop)) {
-               case PROP_BOOLEAN: {
-                       int value, length;
-
-                       if(arraylen && index == -1)
-                               return NULL;
-
-                       length= RNA_property_array_length(ptr, prop);
-
-                       if(length)
-                               value= RNA_property_boolean_get_array(ptr, prop, index);
-                       else
-                               value= RNA_property_boolean_get(ptr, prop);
-
-                       but= uiDefButR(block, TOG, 0, (value)? "True": "False", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
-                       break;
-               }
-               case PROP_INT:
-               case PROP_FLOAT:
-                       if(arraylen && index == -1) {
-                               if(RNA_property_subtype(ptr, prop) == PROP_COLOR)
-                                       but= uiDefButR(block, COL, 0, "", x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
-                       }
-                       else
-                               but= uiDefButR(block, NUM, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
-                       break;
-               case PROP_ENUM:
-                       but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
-                       break;
-               case PROP_STRING:
-                       but= uiDefButR(block, TEX, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
-                       break;
-               case PROP_POINTER: {
-                       PointerRNA pptr;
-                       PropertyRNA *nameprop;
-                       char *text, *descr, textbuf[256];
-                       int icon;
-
-                       RNA_property_pointer_get(ptr, prop, &pptr);
-
-                       if(!pptr.data)
-                               return NULL;
-
-                       icon= tselem_rna_icon(&pptr);
-                       nameprop= RNA_struct_name_property(&pptr);
-
-                       if(nameprop) {
-                               text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
-                               descr= (char*)RNA_property_ui_description(&pptr, prop);
-                               but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
-                               if(text != textbuf)
-                                       MEM_freeN(text);
-                       }
-                       else {
-                               text= (char*)RNA_struct_ui_name(&pptr);
-                               descr= (char*)RNA_property_ui_description(&pptr, prop);
-                               but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
-                       }
-               }
-               default:
-                       but= NULL;
-                       break;
-       }
-
-       return but;
+       fdrawline((float)sizex+OL_RNA_COL_SIZEX,
+               v2d->cur.ymax,
+               (float)sizex+OL_RNA_COL_SIZEX,
+               v2d->cur.ymin);
 }
 
 static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb)
@@ -4209,7 +4370,6 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
        TreeStoreElem *tselem;
        PointerRNA *ptr;
        PropertyRNA *prop;
-       int xstart= MAX2(OL_RNA_COLX, sizex+OL_RNA_COL_SPACEX);
        
        uiBlockSetEmboss(block, UI_EMBOSST);
 
@@ -4219,15 +4379,15 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
                        if(tselem->type == TSE_RNA_PROPERTY) {
                                ptr= &te->rnaptr;
                                prop= te->directdata;
-
-                               if(!(RNA_property_type(ptr, prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
-                                       outliner_draw_rnabut(block, ptr, prop, -1, xstart, te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+                               
+                               if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
+                                       uiDefAutoButR(block, ptr, prop, -1, "", 0, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
                        }
                        else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
                                ptr= &te->rnaptr;
                                prop= te->directdata;
-
-                               outliner_draw_rnabut(block, ptr, prop, te->index, xstart, te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+                               
+                               uiDefAutoButR(block, ptr, prop, te->index, "", 0, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
                        }
                }
                
@@ -4257,7 +4417,7 @@ static void outliner_buttons(uiBlock *block, ARegion *ar, SpaceOops *soops, List
                                else if(tselem->id && GS(tselem->id->name)==ID_LI) len = sizeof(((Library*) 0)->name);
                                else len= sizeof(((ID*) 0)->name)-2;
                                
-                               dx= (int)UI_GetStringWidth(G.font, te->name, 0);
+                               dx= (int)UI_GetStringWidth(te->name);
                                if(dx<50) dx= 50;
                                
                                bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "",  (short)te->xs+2*OL_X-4, (short)te->ys, dx+10, OL_H-1, te->name, 1.0, (float)len-1, 0, 0, "");
@@ -4280,54 +4440,61 @@ void draw_outliner(const bContext *C)
        Main *mainvar= CTX_data_main(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);
        uiBlock *block;
-       int sizey= 0, sizex= 0;
+       int sizey= 0, sizex= 0, sizex_rna= 0;
        
        outliner_build_tree(mainvar, scene, soops); // always 
-
-       outliner_height(soops, &soops->tree, &sizey);
-       outliner_width(soops, &soops->tree, &sizex);
        
-       /* we init all tot rect vars, only really needed on window size change though */
-       ar->v2d.tot.xmin= 0.0f;
-       ar->v2d.tot.xmax= (float)(ar->v2d.mask.xmax-ar->v2d.mask.xmin);
-       if(soops->flag & SO_HIDE_RESTRICTCOLS) {
-               if(ar->v2d.tot.xmax <= sizex)
-                       ar->v2d.tot.xmax= (float)2*sizex;
+       /* get extents of data */
+       outliner_height(soops, &soops->tree, &sizey);
+
+       if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
+               /* RNA has two columns:
+                *      - column 1 is (max_width + OL_RNA_COL_SPACEX) or
+                *                               (OL_RNA_COL_X), whichever is wider...
+                *      - column 2 is fixed at OL_RNA_COL_SIZEX
+                *
+                *  (*) XXX max width for now is a fixed factor of OL_X*(max_indention+100)
+                */
+                
+               /* get actual width of column 1 */
+               outliner_rna_width(soops, &soops->tree, &sizex_rna, 0);
+               sizex_rna= MAX2(OL_RNA_COLX, sizex_rna+OL_RNA_COL_SPACEX);
+               
+               /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
+               sizex= sizex_rna + OL_RNA_COL_SIZEX + 50;
        }
        else {
-               if(ar->v2d.tot.xmax-OL_TOGW <= sizex)
-                       ar->v2d.tot.xmax= (float)2*sizex;
+               /* width must take into account restriction columns (if visible) so that entries will still be visible */
+               //outliner_width(soops, &soops->tree, &sizex);
+               outliner_rna_width(soops, &soops->tree, &sizex, 0); // XXX should use outliner_width instead when te->xend will be set correctly...
+               
+               /* constant offset for restriction columns */
+               // XXX this isn't that great yet...
+               if ((soops->flag & SO_HIDE_RESTRICTCOLS)==0)
+                       sizex += OL_TOGW*3;
        }
-       ar->v2d.tot.ymax= 0.0f;
-       ar->v2d.tot.ymin= (float)-sizey*OL_H;
        
        /* update size of tot-rect (extents of data/viewable area) */
-       UI_view2d_totRect_set(&ar->v2d, sizex, sizey);
-
-       // align on top window if cur bigger than tot
-       if(ar->v2d.cur.ymax-ar->v2d.cur.ymin > sizey*OL_H) {
-               ar->v2d.cur.ymax= 0.0f;
-               ar->v2d.cur.ymin= (float)-(ar->v2d.mask.ymax-ar->v2d.mask.ymin);
-       }
+       UI_view2d_totRect_set(v2d, sizex, sizey);
 
        /* set matrix for 2d-view controls */
-       UI_view2d_view_ortho(C, &ar->v2d);
+       UI_view2d_view_ortho(C, v2d);
 
        /* draw outliner stuff (background and hierachy lines) */
        outliner_back(ar, soops);
        outliner_draw_tree(scene, ar, soops);
 
        /* draw icons and names */
-       block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS, UI_HELV);
+       block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS);
        outliner_buttons(block, ar, soops, &soops->tree);
        
        if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
                /* draw rna buttons */
-               outliner_rna_width(soops, &soops->tree, &sizex, 0);
-               outliner_draw_rnacols(ar, soops, sizex);
-               outliner_draw_rnabuts(block, scene, ar, soops, sizex, &soops->tree);
+               outliner_draw_rnacols(ar, soops, sizex_rna);
+               outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree);
        }
        else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
                /* draw restriction columns */