Index: source/blender/makesdna/DNA_space_types.h =================================================================== --- source/blender/makesdna/DNA_space_types.h (revision 12580) +++ source/blender/makesdna/DNA_space_types.h (working copy) @@ -214,6 +214,17 @@ short type, outlinevis, storeflag; short deps_flags; + + /* custom view. */ + char custom_string[32]; + short custom_view_type; + char pad[6]; + + /* this is to remember the "pattern" in all the custom mode. */ + char custom_active[32]; + char custom_selected[32]; + char custom_library[32]; + char custom_groups[32]; } SpaceOops; @@ -549,7 +560,15 @@ #define SO_LIBRARIES 7 #define SO_VERSE_SESSION 8 #define SO_VERSE_MS 9 +#define SO_CUSTOM_SEARCH 10 +/* SpaceOops->custom_view_type */ +#define SO_CUSTOM_CUR_SCENE 0 +#define SO_CUSTOM_ACTIVE 1 +#define SO_CUSTOM_SELECTED 2 +#define SO_CUSTOM_LIBRARY 3 +#define SO_CUSTOM_GROUPS 4 + /* SpaceOops->storeflag */ #define SO_TREESTORE_CLEANUP 1 /* if set, it allows redraws. gets set for some allqueue events */ Index: source/blender/src/header_oops.c =================================================================== --- source/blender/src/header_oops.c (revision 12580) +++ source/blender/src/header_oops.c (working copy) @@ -60,6 +60,7 @@ #include "BSE_headerbuttons.h" #include "blendef.h" +#include "mydevice.h" #include "BKE_depsgraph.h" @@ -68,6 +69,11 @@ static int viewmovetemp = 0; +void oops_custom_cb ( void *unused, void *unused1 ) +{ + allqueue (REDRAWOOPS, 0); +} + void do_oops_buttons(short event) { float dx, dy; @@ -424,6 +430,7 @@ SpaceOops *soops; Oops *oops; uiBlock *block; + uiBut *bt; short xco, xmax; char naam[256]; @@ -558,16 +565,35 @@ else { if(G.main->library.first) #ifdef WITH_VERSE - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Verse Servers %x9|Verse Sessions %x8|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Verse Servers %x9|Verse Sessions %x8|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Custom Tree %x10", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); #else - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Custom Tree %x10", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); #endif /* WITH_VERSE */ else #ifdef WITH_VERSE - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Verse Servers %x9|Verse Sessions %x8|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Verse Servers %x9|Verse Sessions %x8|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Custom Tree %x10", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); #else - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Custom Tree %x10", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); #endif /* WITH_VERSE */ + if(soops->outlinevis==SO_CUSTOM_SEARCH) { + xco+= 100; + uiDefButS(block, MENU, B_REDR, "Filter%t|Current Scene %x0|Active %x1|Selected %x2|Library %x3|Groups %x4", + xco, 0, 100, 20, + &soops->custom_view_type, 0, 0, 0, 0, ""); + + xco+= 100; + if(soops->custom_view_type==SO_CUSTOM_CUR_SCENE) + bt= uiDefBut(block, TEX, B_NOP, ":", xco, 0, 100, 20, soops->custom_string, 0.0, 31.0, 0, 0, "Custom Search string (* for all)"); + else if(soops->custom_view_type==SO_CUSTOM_ACTIVE) + bt= uiDefBut(block, TEX, B_NOP, ":", xco, 0, 100, 20, soops->custom_active, 0.0, 31.0, 0, 0, "Custom Search string (* for all)"); + else if(soops->custom_view_type==SO_CUSTOM_SELECTED) + bt= uiDefBut(block, TEX, B_NOP, ":", xco, 0, 100, 20, soops->custom_selected, 0.0, 31.0, 0, 0, "Custom Search string (* for all)"); + else if(soops->custom_view_type==SO_CUSTOM_LIBRARY) + bt= uiDefBut(block, TEX, B_NOP, ":", xco, 0, 100, 20, soops->custom_library, 0.0, 31.0, 0, 0, "Custom Search string (* for all)"); + else + bt= uiDefBut(block, TEX, B_NOP, ":", xco, 0, 100, 20, soops->custom_groups, 0.0, 31.0, 0, 0, "Custom Search string (* for all)"); + uiButSetFunc(bt, oops_custom_cb, soops, NULL); + } } /* always do as last */ Index: source/blender/src/outliner.c =================================================================== --- source/blender/src/outliner.c (revision 12580) +++ source/blender/src/outliner.c (working copy) @@ -411,7 +411,7 @@ /* Prototype, see functions below */ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index); + TreeElement *parent, short type, short index, char *custom_string); static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, SceneRenderLayer *srl) @@ -419,7 +419,7 @@ TreeStoreElem *tselem= TREESTORE(tenla); TreeElement *te; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_COMBINED); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_COMBINED, NULL); te->name= "Combined"; te->directdata= &srl->passflag; @@ -427,55 +427,55 @@ if(tselem->flag & TSE_CLOSED) return; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_Z); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_Z, NULL); te->name= "Z"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_VECTOR); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_VECTOR, NULL); te->name= "Vector"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_NORMAL); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_NORMAL, NULL); te->name= "Normal"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_UV); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_UV, NULL); te->name= "UV"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_INDEXOB); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_INDEXOB, NULL); te->name= "Index Object"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_RGBA); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_RGBA, NULL); te->name= "Color"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_DIFFUSE); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_DIFFUSE, NULL); te->name= "Diffuse"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SPEC); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SPEC, NULL); te->name= "Specular"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SHADOW); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_SHADOW, NULL); te->name= "Shadow"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_AO); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_AO, NULL); te->name= "AO"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFLECT); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFLECT, NULL); te->name= "Reflection"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFRACT); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_REFRACT, NULL); te->name= "Refraction"; te->directdata= &srl->passflag; - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_RADIO); + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_RADIO, NULL); te->name= "Radiosity"; te->directdata= &srl->passflag; @@ -486,7 +486,7 @@ static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a) { - TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); + TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a, NULL); (*a)++; te->name= curBone->name; @@ -500,38 +500,38 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te) { SceneRenderLayer *srl; - TreeElement *tenla= outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0); + TreeElement *tenla= outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0, NULL); int a; tenla->name= "RenderLayers"; for(a=0, srl= sce->r.layers.first; srl; srl= srl->next, a++) { - TreeElement *tenlay= outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); + TreeElement *tenlay= outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a, NULL); tenlay->name= srl->name; tenlay->directdata= &srl->passflag; if(srl->light_override) - outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0); + outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0, NULL); if(srl->mat_override) - outliner_add_element(soops, &tenlay->subtree, srl->mat_override, tenlay, TSE_LINKED_MAT, 0); + outliner_add_element(soops, &tenlay->subtree, srl->mat_override, tenlay, TSE_LINKED_MAT, 0, NULL); outliner_add_passes(soops, tenlay, &sce->id, srl); } - outliner_add_element(soops, lb, sce->world, te, 0, 0); + outliner_add_element(soops, lb, sce->world, te, 0, 0, NULL); if(sce->scriptlink.scripts) { int a= 0; - tenla= outliner_add_element(soops, lb, sce, te, TSE_SCRIPT_BASE, 0); + tenla= outliner_add_element(soops, lb, sce, te, TSE_SCRIPT_BASE, 0, NULL); tenla->name= "Scripts"; for (a=0; ascriptlink.totscript; a++) { - outliner_add_element(soops, &tenla->subtree, sce->scriptlink.scripts[a], tenla, 0, 0); + outliner_add_element(soops, &tenla->subtree, sce->scriptlink.scripts[a], tenla, 0, 0, NULL); } } } static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index) + TreeElement *parent, short type, short index, char *custom_string) { TreeElement *te; TreeStoreElem *tselem; @@ -570,22 +570,28 @@ Object *ob= (Object *)id; if(ob->proxy && ob->id.lib==NULL) - outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0); + outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0, NULL); + + if(G.obedit) + outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0, custom_string); + else + outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0, NULL); - outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0); - if(ob->pose) { bPoseChannel *pchan; TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0); + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0, NULL); tenla->name= "Pose"; if(ob!=G.obedit && (ob->flag & OB_POSEMODE)) { // channels undefined in editmode, but we want the 'tenla' pose icon itself int a= 0, const_index= 1000; /* ensure unique id for bone constraints */ - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if((custom_string) && (!BLI_strcheck(pchan->name, custom_string))) + continue; + + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a, NULL); ten->name= pchan->name; ten->directdata= pchan; pchan->prev= (bPoseChannel *)ten; @@ -594,12 +600,12 @@ //Object *target; bConstraint *con; TreeElement *ten1; - TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); + TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0, NULL); //char *str; tenla1->name= "Constraints"; for(con= pchan->constraints.first; con; con= con->next, const_index++) { - ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index); + ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index, NULL); #if 0 /* disabled as it needs to be reworked for recoded constraints system */ target= get_constraint_target(con, &str); if(str && str[0]) ten1->name= str; @@ -611,22 +617,25 @@ /* possible add all other types links? */ } } + a++; } - /* make hierarchy */ - ten= tenla->subtree.first; - while(ten) { - TreeElement *nten= ten->next, *par; - tselem= TREESTORE(ten); - if(tselem->type==TSE_POSE_CHANNEL) { - pchan= (bPoseChannel *)ten->directdata; - if(pchan->parent) { - BLI_remlink(&tenla->subtree, ten); - par= (TreeElement *)pchan->parent->prev; - BLI_addtail(&par->subtree, ten); - ten->parent= par; + if(!custom_string) { + /* make hierarchy */ + ten= tenla->subtree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + tselem= TREESTORE(ten); + if(tselem->type==TSE_POSE_CHANNEL) { + pchan= (bPoseChannel *)ten->directdata; + if(pchan->parent) { + BLI_remlink(&tenla->subtree, ten); + par= (TreeElement *)pchan->parent->prev; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } } + ten= nten; } - ten= nten; } /* restore prev pointers */ pchan= ob->pose->chanbase.first; @@ -637,23 +646,23 @@ } } - outliner_add_element(soops, &te->subtree, ob->ipo, te, 0, 0); - outliner_add_element(soops, &te->subtree, ob->action, te, 0, 0); + outliner_add_element(soops, &te->subtree, ob->ipo, te, 0, 0, NULL); + outliner_add_element(soops, &te->subtree, ob->action, te, 0, 0, NULL); for(a=0; atotcol; a++) - outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a); + outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a, NULL); if(ob->constraints.first) { //Object *target; bConstraint *con; TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0, NULL); int a= 0; //char *str; tenla->name= "Constraints"; for(con= ob->constraints.first; con; con= con->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a, NULL); #if 0 /* disabled due to constraints system targets recode... code here needs review */ target= get_constraint_target(con, &str); if(str && str[0]) ten->name= str; @@ -668,60 +677,65 @@ if(ob->modifiers.first) { ModifierData *md; - TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); + TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0, NULL); int index; temod->name = "Modifiers"; - for (index=0,md=ob->modifiers.first; md; index++,md=md->next) { - TreeElement *te = outliner_add_element(soops, &temod->subtree, ob, temod, TSE_MODIFIER, index); + for (index=0,md=ob->modifiers.first; md; md=md->next) { + if((custom_string) && (!BLI_strcheck(md->name, custom_string))) + continue; + TreeElement *te = outliner_add_element(soops, &temod->subtree, ob, temod, TSE_MODIFIER, index, NULL); te->name= md->name; if (md->type==eModifierType_Lattice) { - outliner_add_element(soops, &te->subtree, ((LatticeModifierData*) md)->object, te, TSE_LINKED_OB, 0); + outliner_add_element(soops, &te->subtree, ((LatticeModifierData*) md)->object, te, TSE_LINKED_OB, 0, NULL); } else if (md->type==eModifierType_Curve) { - outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_LINKED_OB, 0); + outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_LINKED_OB, 0, NULL); } else if (md->type==eModifierType_Armature) { - outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_LINKED_OB, 0); + outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_LINKED_OB, 0, NULL); } else if (md->type==eModifierType_Hook) { - outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_LINKED_OB, 0); + outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_LINKED_OB, 0, NULL); } + index++; } } if(ob->defbase.first) { bDeformGroup *defgroup; TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0); + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0, NULL); int a= 0; tenla->name= "Vertex Groups"; for (defgroup=ob->defbase.first; defgroup; defgroup=defgroup->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a); + if((custom_string) && (!BLI_strcheck(defgroup->name, custom_string))) + continue; + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a, NULL); ten->name= defgroup->name; ten->directdata= defgroup; } } if(ob->scriptlink.scripts) { - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_SCRIPT_BASE, 0); + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_SCRIPT_BASE, 0, NULL); int a= 0; tenla->name= "Scripts"; for (a=0; ascriptlink.totscript; a++) { /* ** */ - outliner_add_element(soops, &tenla->subtree, ob->scriptlink.scripts[a], te, 0, 0); + outliner_add_element(soops, &tenla->subtree, ob->scriptlink.scripts[a], te, 0, 0, NULL); } } if(ob->dup_group) - outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0); + outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0, NULL); if(ob->nlastrips.first) { bActionStrip *strip; TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_NLA, 0); + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_NLA, 0, NULL); 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); + ten= outliner_add_element(soops, &tenla->subtree, strip->act, tenla, TSE_NLA_ACTION, a, NULL); if(ten) ten->directdata= strip; } } @@ -731,10 +745,10 @@ 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->key, te, 0, 0); + outliner_add_element(soops, &te->subtree, me->ipo, te, 0, 0, NULL); + outliner_add_element(soops, &te->subtree, me->key, te, 0, 0, NULL); for(a=0; atotcol; a++) - outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a); + outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a, NULL); /* could do tfaces with image links, but the images are not grouped nicely. would require going over all tfaces, sort images in use. etc... */ } @@ -743,23 +757,23 @@ { Curve *cu= (Curve *)id; for(a=0; atotcol; a++) - outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a); + outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a, NULL); } break; case ID_MB: { MetaBall *mb= (MetaBall *)id; for(a=0; atotcol; a++) - outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a); + outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a, NULL); } break; case ID_MA: { Material *ma= (Material *)id; - outliner_add_element(soops, &te->subtree, ma->ipo, te, 0, 0); + outliner_add_element(soops, &te->subtree, ma->ipo, te, 0, 0, NULL); for(a=0; amtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); + if(ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a, NULL); } } break; @@ -767,38 +781,38 @@ { Tex *tex= (Tex *)id; - outliner_add_element(soops, &te->subtree, tex->ipo, te, 0, 0); - outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0); + outliner_add_element(soops, &te->subtree, tex->ipo, te, 0, 0, NULL); + outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0, NULL); } 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->ipo, te, 0, 0, NULL); } 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->ipo, te, 0, 0, NULL); for(a=0; amtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); + if(la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a, NULL); } } break; 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->ipo, te, 0, 0, NULL); for(a=0; amtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); + if(wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a, NULL); } } break; case ID_KE: { Key *key= (Key *)id; - outliner_add_element(soops, &te->subtree, key->ipo, te, 0, 0); + outliner_add_element(soops, &te->subtree, key->ipo, te, 0, 0, NULL); } break; case ID_IP: @@ -810,7 +824,7 @@ 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); + outliner_add_element(soops, &te->subtree, icu->driver->ob, te, TSE_LINKED_OB, 0, NULL); lastadded= icu->driver->ob; } } @@ -824,7 +838,7 @@ tselem= TREESTORE(parent); for (chan=act->chanbase.first; chan; chan=chan->next, a++) { - outliner_add_element(soops, &te->subtree, chan->ipo, te, 0, a); + outliner_add_element(soops, &te->subtree, chan->ipo, te, 0, a, NULL); } } break; @@ -837,24 +851,29 @@ EditBone *ebone; TreeElement *ten; - for (ebone = G.edbo.first; ebone; ebone=ebone->next, a++) { - ten= outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a); + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if((custom_string) && (!BLI_strcheck(ebone->name, custom_string))) + continue; + ten= outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a, NULL); ten->directdata= ebone; ten->name= ebone->name; ebone->temp= ten; + a++; } - /* make hierarchy */ - ten= te->subtree.first; - while(ten) { - TreeElement *nten= ten->next, *par; - ebone= (EditBone *)ten->directdata; - if(ebone->parent) { - BLI_remlink(&te->subtree, ten); - par= ebone->parent->temp; - BLI_addtail(&par->subtree, ten); - ten->parent= par; + if(!custom_string) { + /* make hierarchy */ + ten= te->subtree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + ebone= (EditBone *)ten->directdata; + if(ebone->parent) { + BLI_remlink(&te->subtree, ten); + par= ebone->parent->temp; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } + ten= nten; } - ten= nten; } } else { @@ -902,7 +921,7 @@ while(vlink) { child_node = vlink->target; if(child_node && child_node->type==V_NT_GEOMETRY) { - ten = outliner_add_element(soops, &te->subtree, child_node, te, ID_VN, 0); + ten = outliner_add_element(soops, &te->subtree, child_node, te, ID_VN, 0, NULL); ten->directdata = child_node; } vlink = vlink->next; @@ -938,11 +957,14 @@ } } +/* prototype see the function below. */ +static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id); + static void outliner_build_tree(SpaceOops *soops) { Base *base; Object *ob; - TreeElement *te, *ten; + TreeElement *te = NULL, *ten; TreeStoreElem *tselem; int show_opened= soops->treestore==NULL; /* on first view, we open scenes */ #ifdef WITH_VERSE @@ -963,7 +985,7 @@ Library *lib; for(lib= G.main->library.first; lib; lib= lib->id.next) { - ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); + ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0, NULL); lib->id.newid= (ID *)ten; } /* make hierarchy */ @@ -988,13 +1010,13 @@ else if(soops->outlinevis == SO_ALL_SCENES) { Scene *sce; for(sce= G.main->scene.first; sce; sce= sce->id.next) { - te= outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0); + te= outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0, NULL); tselem= TREESTORE(te); if(sce==G.scene && show_opened) tselem->flag &= ~TSE_CLOSED; for(base= sce->base.first; base; base= base->next) { - ten= outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); + ten= outliner_add_element(soops, &te->subtree, base->object, te, 0, 0, NULL); ten->directdata= base; } outliner_make_hierarchy(soops, &te->subtree); @@ -1007,7 +1029,7 @@ outliner_add_scene_contents(soops, &soops->tree, G.scene, NULL); for(base= G.scene->base.first; base; base= base->next) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, NULL); ten->directdata= base; } outliner_make_hierarchy(soops, &soops->tree); @@ -1015,7 +1037,7 @@ else if(soops->outlinevis == SO_VISIBLE) { for(base= G.scene->base.first; base; base= base->next) { if(base->lay & G.scene->lay) - outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, NULL); } outliner_make_hierarchy(soops, &soops->tree); } @@ -1025,11 +1047,11 @@ for(group= G.main->group.first; group; group= group->id.next) { if(group->id.us) { - te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0); + te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0, NULL); tselem= TREESTORE(te); for(go= group->gobject.first; go; go= go->next) { - ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); + ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0, NULL); ten->directdata= NULL; /* eh, why? */ } outliner_make_hierarchy(soops, &te->subtree); @@ -1043,7 +1065,7 @@ if(ob) { for(base= G.scene->base.first; base; base= base->next) { if(base->object->type==ob->type) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, NULL); ten->directdata= base; } } @@ -1054,7 +1076,7 @@ for(base= G.scene->base.first; base; base= base->next) { if(base->lay & G.scene->lay) { if(base==BASACT || (base->flag & SELECT)) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, NULL); ten->directdata= base; } } @@ -1067,15 +1089,15 @@ for(session=session_list.first; session; session = session->next) { struct VNode *vnode; if(session->flag & VERSE_CONNECTED) { - te= outliner_add_element(soops, &soops->tree, session, NULL, ID_VS, 0); + te= outliner_add_element(soops, &soops->tree, session, NULL, ID_VS, 0, NULL); /* add all object nodes as childreen of session */ for(vnode=session->nodes.lb.first; vnode; vnode=vnode->next) { if(vnode->type==V_NT_OBJECT) { - ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0); + ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0, NULL); ten->directdata= vnode; } else if(vnode->type==V_NT_BITMAP) { - ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0); + ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0, NULL); ten->directdata= vnode; } } @@ -1083,19 +1105,109 @@ } } else if(soops->outlinevis == SO_VERSE_MS) { - te= outliner_add_element(soops, &soops->tree, "MS", NULL, ID_MS, 0); + te= outliner_add_element(soops, &soops->tree, "MS", NULL, ID_MS, 0, NULL); if(server_list.first!=NULL) { struct VerseServer *server; /* add one main entry to root of hierarchy */ for(server=server_list.first; server; server=server->next) { - ten= outliner_add_element(soops, &te->subtree, server, te, ID_SS, 0); + ten= outliner_add_element(soops, &te->subtree, server, te, ID_SS, 0, NULL); ten->directdata= server; } } } #endif + else if(soops->outlinevis==SO_CUSTOM_SEARCH) { + if(soops->custom_view_type==SO_CUSTOM_CUR_SCENE) { + for(base= G.scene->base.first; base; base= base->next) { + if(BLI_strcheck(base->object->id.name+2, soops->custom_string)) { + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, NULL); + ten->directdata= base; + } + } + outliner_make_hierarchy(soops, &soops->tree); + } + else if(soops->custom_view_type==SO_CUSTOM_ACTIVE) { + ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0, soops->custom_active); + if(ten) + ten->directdata= BASACT; + } + else if(soops->custom_view_type==SO_CUSTOM_SELECTED) { + for(base= G.scene->base.first; base; base= base->next) { + if(base == BASACT || (base->flag & SELECT)) { + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0, soops->custom_selected); + ten->directdata= base; + } + } + outliner_make_hierarchy(soops, &soops->tree); + } + else if(soops->custom_view_type==SO_CUSTOM_LIBRARY) { + Library *lib, *plib; + + for(lib= G.main->library.first; lib; lib= lib->id.next) { + if(BLI_strcheck(lib->name, soops->custom_library)) { + /* need add all parent library for hierarchy. */ + plib= lib->parent; + while(plib) { + if(!outliner_find_id(soops, &soops->tree, (ID*)plib)) { + ten= outliner_add_element(soops, &soops->tree, plib, NULL, 0, 0, NULL); + plib->id.newid= (ID *)ten; + } + plib= plib->parent; + } + ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0, NULL); + lib->id.newid= (ID *) ten; + } + } + + /* make hierarchy */ + ten= soops->tree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + tselem= TREESTORE(ten); + lib= (Library *)tselem->id; + if(lib->parent) { + BLI_remlink(&soops->tree, ten); + par= (TreeElement *) lib->parent->id.newid; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } + ten= nten; + } + + /* restore newid pointers. */ + for(lib= G.main->library.first; lib; lib= lib->id.next) + lib->id.newid= NULL; + } + else { + Group *group; + GroupObject *go; + int found; + + for(group= G.main->group.first; group; group= group->id.next) { + found= 0; + if(group->id.us) { + for(go= group->gobject.first; go; go= go->next) { + if(BLI_strcheck(go->ob->id.name+2, soops->custom_groups)) { + if(!found) { + te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0, NULL); + tselem= TREESTORE(te); + found= 1; + } + ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0, NULL); + ten->directdata= NULL; + } + } + if(te) + outliner_make_hierarchy(soops, &te->subtree); + /* clear id.newid */ + for(go= group->gobject.first; go; go= go->next) + go->ob->id.newid= NULL; + } + } + } + } else { - ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); + ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0, NULL); if(ten) ten->directdata= BASACT; } Index: source/blender/blenlib/BLI_blenlib.h =================================================================== --- source/blender/blenlib/BLI_blenlib.h (revision 12580) +++ source/blender/blenlib/BLI_blenlib.h (working copy) @@ -368,6 +368,7 @@ char *BLI_strcasestr(const char *s, const char *find); int BLI_strcasecmp(const char *s1, const char *s2); int BLI_strncasecmp(const char *s1, const char *s2, int n); +int BLI_strcheck(char *str, char *pattern); void BLI_timestr(double time, char *str); /** Index: source/blender/blenlib/intern/util.c =================================================================== --- source/blender/blenlib/intern/util.c (revision 12580) +++ source/blender/blenlib/intern/util.c (working copy) @@ -1594,7 +1594,75 @@ return 0; } +int BLI_strcheck ( char *str, char *pattern ) +{ + char *p, *p1; + int ns, np, i; + if ((!str) || (!pattern)) + return (0); + + ns = strlen (str); + np = strlen (pattern); + + /* 1 case: pattern == *, always return 1 */ + if ((np == 1) && (*pattern == '*')) + return (1); + + /* 2 case: pattern == *TEXT* */ + if ((*pattern == '*') && (pattern[np-1] == '*')) { + pattern[np-1] = '\0'; + p = strstr (str, pattern+1); + pattern[np-1] = '*'; + if (p) + return (1); + return (0); + } + + /* 3 case: pattern == *TEXT */ + if (*pattern == '*') { + /* the end of the string. */ + p1 = str+ns; + + /* "go back" the number of character of the pattern */ + p1 -= np; + p1++; + + if (!strcmp (p1, pattern+1)) + return (1); + return (0); + } + + /* 4 case: pattern == TEXT* */ + if (pattern[np] == '*') { + if (!strncmp (str, pattern, np-1)) + return (1); + return (0); + } + + /* 5 case: patter == TEXT*TEXT */ + p = strchr (pattern, '*'); + if (p) { + p++; /* this is the second pattern */ + + /* check the first pattern. */ + for (i = 0; i < np; i++) { + if (pattern[i] == '*') + break; + if (str[i] != pattern[i]) + return (0); + } + + /* the end of the string. */ + p1 = str+ns; + /* "go back" the number of character of the second pattern */ + p1 -= strlen (p); + if (!strcmp (p1, p)) + return (1); + } + return (0); +} + #ifdef WITH_ICONV #include "iconv.h" #include "localcharset.h"