Page MenuHome

outliner_search_02.patch

outliner_search_02.patch

Index: blender/blenlib/BLI_blenlib.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenlib/BLI_blenlib.h,v
retrieving revision 1.21
diff -u -r1.21 BLI_blenlib.h
--- blender/blenlib/BLI_blenlib.h 20 Aug 2006 15:22:54 -0000 1.21
+++ blender/blenlib/BLI_blenlib.h 13 Sep 2006 06:12:20 -0000
@@ -209,6 +209,19 @@
*/
int BLI_strcaseeq(char *a, char *b);
+ /**
+ * Search a string for another
+ *
+ * flags:
+ * 1 - case sensitive
+ * 2 - only accept if at start
+ * 4 - only accept if at end
+ * 8 - full matches only
+ *
+ * @retval True if found
+ */
+int BLI_str_search(char *str, char *find, int flags);
+
/**
* Read a file as ASCII lines. An empty list is
* returned if the file cannot be opened or read.
Index: blender/blenlib/intern/util.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenlib/intern/util.c,v
retrieving revision 1.37
diff -u -r1.37 util.c
--- blender/blenlib/intern/util.c 20 Aug 2006 15:22:54 -0000 1.37
+++ blender/blenlib/intern/util.c 13 Sep 2006 06:50:59 -0000
@@ -655,6 +655,77 @@
return (BLI_strcasecmp(a, b)==0);
}
+int BLI_str_search(char *str, char *find, int flags)
+{
+ int srclen= strlen(str);
+ int findlen= strlen(find);
+
+ /* check relation of find to str */
+ if (findlen > srclen) /* false, as str is too short */
+ return 0;
+ else if (findlen == srclen) {
+ /* do basic str comparing */
+ if (flags & 1)
+ return BLI_streq(str, find);
+ else
+ return BLI_strcaseeq(str, find);
+ }
+ else {
+ /* do Aligorith's specially stupid slow search*/
+ int match, i;
+
+ /* determine which type of search to do */
+ if (flags & 2) {
+ /* find only at start */
+ char *search= MEM_mallocN(findlen+1, "strseg");
+ BLI_strncpy(search, str, findlen+1);
+
+ if (flags & 1)
+ match= BLI_streq(search, find);
+ else
+ match= BLI_strcaseeq(search, find);
+
+ MEM_freeN(search);
+ return match;
+ }
+ else if (flags & 4) {
+ /* find only at end */
+ char *search= MEM_mallocN(findlen+1, "strseg");
+ BLI_strncpy(search, str+(srclen-findlen-1), findlen+1); // hmm...
+
+ if (flags & 1)
+ match= BLI_streq(search, find);
+ else
+ match= BLI_strcaseeq(search, find);
+
+ MEM_freeN(search);
+ return match;
+ }
+ else {
+ /* loop until found */
+ for (i=0; i<srclen; i++) {
+ char *search= MEM_mallocN(findlen+1, "strseg");
+
+ /* get segment */
+ BLI_strncpy(search, (str+i), findlen+1);
+
+ /* check if strings equal */
+ if (flags & 1)
+ match= BLI_streq(search, find);
+ else
+ match= BLI_strcaseeq(search, find);
+
+ /* cleanup and break loop (if match) */
+ MEM_freeN(search);
+ if (match) return 1;
+ }
+
+ /* nothing found */
+ return 0;
+ }
+ }
+}
+
/* ******************** string encoding ***************** */
/* This is quite an ugly function... its purpose is to
Index: blender/blenloader/intern/readfile.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenloader/intern/readfile.c,v
retrieving revision 1.288
diff -u -r1.288 readfile.c
--- blender/blenloader/intern/readfile.c 6 Sep 2006 09:51:30 -0000 1.288
+++ blender/blenloader/intern/readfile.c 13 Sep 2006 07:14:05 -0000
@@ -3088,6 +3088,9 @@
tselem->id= newlibadr(fd, NULL, tselem->id);
}
}
+
+ if (so->lastfind)
+ MEM_freeN(so->lastfind);
}
else if(sl->spacetype==SPACE_SOUND) {
SpaceSound *ssound= (SpaceSound *)sl;
@@ -3357,6 +3360,9 @@
soops->treestore->totelem= soops->treestore->usedelem;
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
}
+
+ if (soops->lastfind)
+ MEM_freeN(soops->lastfind);
}
else if(sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl;
Index: blender/blenloader/intern/writefile.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/blenloader/intern/writefile.c,v
retrieving revision 1.71
diff -u -r1.71 writefile.c
--- blender/blenloader/intern/writefile.c 3 Sep 2006 12:16:13 -0000 1.71
+++ blender/blenloader/intern/writefile.c 13 Sep 2006 05:39:42 -0000
@@ -1355,6 +1355,9 @@
}
oops= oopsn;
}
+
+ if (so->lastfind)
+ MEM_freeN(so->lastfind);
/* ater cleanup, because of listbase! */
writestruct(wd, DATA, "SpaceOops", 1, so);
Index: blender/include/BIF_outliner.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BIF_outliner.h,v
retrieving revision 1.13
diff -u -r1.13 BIF_outliner.h
--- blender/include/BIF_outliner.h 20 Aug 2006 15:22:54 -0000 1.13
+++ blender/include/BIF_outliner.h 13 Sep 2006 06:10:42 -0000
@@ -47,6 +47,12 @@
void *directdata; // Armature Bones, Base, ...
} TreeElement;
+/* last found item in outliner */
+typedef struct LastFindItem {
+ char searchString[32]; /* the string that was searched for */
+ ID *elemID; /* id of TreeElement or TreeStoreElem */
+} LastFindItem;
+
/* TreeElement->flag */
#define TE_ACTIVE 1
#define TE_ICONROW 2
@@ -86,6 +92,7 @@
extern void outliner_toggle_selected(struct ScrArea *sa);
extern void outliner_operation_menu(struct ScrArea *sa);
extern void outliner_page_up_down(struct ScrArea *sa, int up);
+extern void outliner_find_panel(struct ScrArea *sa, int flags);
#endif
Index: blender/makesdna/DNA_space_types.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_space_types.h,v
retrieving revision 1.49
diff -u -r1.49 DNA_space_types.h
--- blender/makesdna/DNA_space_types.h 6 Sep 2006 09:51:30 -0000 1.49
+++ blender/makesdna/DNA_space_types.h 13 Sep 2006 04:26:36 -0000
@@ -47,6 +47,7 @@
struct Image;
struct SpaceIpo;
struct BlendHandle;
+struct LastFindItem;
struct TreeStore;
struct RenderInfo;
struct bNodeTree;
@@ -206,6 +207,7 @@
ListBase tree;
struct TreeStore *treestore;
+ struct LastFindItem *lastfind; /* for search. should not be written to file!!! */
short type, outlinevis, storeflag;
short deps_flags;
Index: blender/src/header_oops.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/header_oops.c,v
retrieving revision 1.26
diff -u -r1.26 header_oops.c
--- blender/src/header_oops.c 6 Sep 2006 09:51:30 -0000 1.26
+++ blender/src/header_oops.c 13 Sep 2006 06:51:12 -0000
@@ -348,7 +348,78 @@
return block;
}
+static void do_oops_searchmenu(void *arg, int event)
+{
+ int search_flags = 0;
+
+ switch(event)
+ {
+ case 0: /* plain new find */
+ search_flags = 0;
+ break;
+ case 1: /* find in-string, from start */
+ search_flags |= 2;
+ break;
+ case 2: /* find in-string, from end */
+ search_flags |= 4;
+ break;
+ case 3: /* case sensitive */
+ search_flags |= 1;
+ break;
+ case 4: /* full search */
+ search_flags |= 8;
+ break;
+ case 5: /* full case sensitive */
+ search_flags = 1|8;
+ break;
+ case 6: /* again */
+ search_flags |= 16;
+ break;
+ default: /* nothing valid */
+ return;
+ }
+
+ /* run search */
+ outliner_find_panel(curarea, search_flags);
+}
+
+static uiBlock *oops_searchmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+ block= uiNewBlock(&curarea->uiblocks, "oops_searchmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
+ uiBlockSetButmFunc(block, do_oops_searchmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find In-Name At Start", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find In-Name At End", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find (Case Sensitive)|Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Complete|Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Complete (Case Sensitive)|Ctrl Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Again|Shift F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+
+ if(curarea->headertype==HEADERTOP) {
+ uiBlockSetDirection(block, UI_DOWN);
+ }
+ else {
+ uiBlockSetDirection(block, UI_TOP);
+ uiBlockFlipOrder(block);
+ }
+
+ uiTextBoundsBlock(block, 50);
+
+ return block;
+}
void oops_buttons(void)
{
@@ -404,6 +475,11 @@
uiDefPulldownBut(block, oops_blockmenu, NULL, "Block", xco, -2, xmax-3, 24, "");
xco+= xmax;
+ }
+ else {
+ xmax= GetButStringLength("Search");
+ uiDefPulldownBut(block, oops_searchmenu, NULL, "Search", xco, -2, xmax-3, 24, "");
+ xco+= xmax;
}
}
Index: blender/src/outliner.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/outliner.c,v
retrieving revision 1.69
diff -u -r1.69 outliner.c
--- blender/src/outliner.c 6 Sep 2006 09:51:30 -0000 1.69
+++ blender/src/outliner.c 13 Sep 2006 07:03:29 -0000
@@ -1007,6 +1008,20 @@
}
}
+/* this function opens all the levels that box it in*/
+static void outliner_open_back(SpaceOops *soops, TreeElement *te)
+{
+ TreeStoreElem *tselem;
+ te= te->parent;
+
+ while(te) {
+ tselem= TREESTORE(te);
+ if (tselem->flag & TSE_CLOSED)
+ tselem->flag &= ~TSE_CLOSED;
+ te= te->parent;
+ }
+}
+
void outliner_one_level(struct ScrArea *sa, int add)
{
SpaceOops *soops= sa->spacedata.first;
@@ -1697,6 +1712,7 @@
}
+
static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id)
{
TreeElement *te, *tes;
@@ -1730,6 +1746,161 @@
so->v2d.cur.ymax= ytop;
so->v2d.cur.ymin= ytop-(so->v2d.mask.ymax-so->v2d.mask.ymin);
scrarea_queue_redraw(sa);
+ }
+}
+
+/* find next element that has this name */
+static TreeElement *outliner_find_named(SpaceOops *soops, ListBase *lb, char *name, int flags, TreeElement *prev)
+{
+ TreeElement *te, *tes;
+ char searchName[33];
+
+ BLI_strncpy(searchName, name, 33);
+
+ te= lb->first;
+ while(te) {
+ char teName[33];
+
+ BLI_strncpy(teName, te->name, 33);
+
+ /* determine if match */
+ if (BLI_str_search(teName, searchName, flags)) {
+ /* name is right, but is element the previous one? */
+ if (prev) {
+ if (te != prev) return te;
+ }
+ else
+ return te;
+ }
+
+ tes= outliner_find_named(soops, &te->subtree, name, flags, prev);
+ if(tes) return tes;
+
+ te= te->next;
+ }
+
+ /* check if no more was due to no more matches past prev */
+ if (prev) {
+ /* go through list one more time to try and find the first entry. no more past last */
+ te= lb->first;
+ while(te) {
+ char teName[33];
+
+ BLI_strncpy(teName, te->name, 33);
+
+ /* see if this is a single element */
+ if (BLI_str_search(teName, searchName, flags)) {
+ /* name is right, but is element the previous one? */
+ if (te != prev) return te;
+ }
+
+ /* try to find in subtree if exists */
+ tes= outliner_find_named(soops, &te->subtree, name, flags, prev);
+ if(tes) return tes;
+
+ te= te->next;
+ }
+ }
+
+ /* nothing valid found */
+ return NULL;
+}
+
+/* Called to find an item based on name.
+ * flags:
+ * 1 - case sensitive
+ * 2 - only accept if at start
+ * 4 - only accept if at end
+ * 8 - full matches only
+ * 16 - again
+ */
+void outliner_find_panel(struct ScrArea *sa, int flags)
+{
+ SpaceOops *soops= sa->spacedata.first;
+
+ TreeElement *te;
+ TreeElement *last_find;
+ TreeStoreElem *tselem;
+
+ char name[33];
+ int ytop;
+
+ /* get last found tree-element */
+ if (soops->lastfind)
+ last_find= outliner_find_id(soops, &soops->tree, soops->lastfind->elemID);
+ else
+ last_find= NULL;
+
+ /* determine which type of search to do */
+ if ((flags & 16) && (last_find)) {
+ /* no popup panel - previous + user wanted to search for next after previous */
+ BLI_strncpy(name, soops->lastfind->searchString, 33);
+ te= outliner_find_named(soops, &soops->tree, name, flags, last_find);
+
+ /* deselect last if match */
+ if (te) {
+ TreeStoreElem *tsel;
+ tsel= TREESTORE(last_find);
+ if (tsel->flag & TSE_SELECTED)
+ tsel->flag &= ~TSE_SELECTED;
+ }
+ }
+ else {
+ /* pop up panel - no previous, or user didn't want search after previous */
+ strcpy(name, "");
+ if (sbutton(name, 0, sizeof(name)-1, "Find: ") && name[0]) {
+ te= outliner_find_named(soops, &soops->tree, name, flags, NULL);
+
+ if (te && last_find) {
+ TreeStoreElem *tsel;
+ tsel= TREESTORE(last_find);
+ if (tsel->flag & TSE_SELECTED)
+ tsel->flag &= ~TSE_SELECTED;
+ }
+ }
+ else
+ return;
+ }
+
+ /* do selection */
+ if (te) {
+ tselem= TREESTORE(te);
+ if (tselem) {
+ LastFindItem *find_item;
+
+ /* outliner highlight/select */
+ if ((tselem->flag & TSE_SELECTED)==0)
+ tselem->flag |= TSE_SELECTED;
+
+ /* expand branches so that it will be visible */
+ outliner_open_back(soops, te);
+
+ /* make te->ys center of view */
+ ytop= te->ys + (soops->v2d.mask.ymax-soops->v2d.mask.ymin)/2;
+ if(ytop>0) ytop= 0;
+ soops->v2d.cur.ymax= ytop;
+ soops->v2d.cur.ymin= ytop-(soops->v2d.mask.ymax-soops->v2d.mask.ymin);
+
+ /* store selection */
+ if (soops->lastfind) MEM_freeN(soops->lastfind);
+ find_item = MEM_callocN(sizeof(LastFindItem), "lastfinditem");
+ find_item->elemID= tselem->id;
+ BLI_strncpy(find_item->searchString, name, 33);
+ soops->lastfind= find_item;
+
+ /* redraw and undo stack */
+ BIF_undo_push("Outliner find item");
+ scrarea_queue_redraw(sa);
+ }
+ else {
+ if (soops->lastfind) MEM_freeN(soops->lastfind);
+ soops->lastfind= NULL;
+ }
+ }
+ else {
+ if (name) error("Not found: %s", name);
+ if (soops->lastfind) MEM_freeN(soops->lastfind);
+ soops->lastfind= NULL;
}
}
Index: blender/src/space.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/space.c,v
retrieving revision 1.376
diff -u -r1.376 space.c
--- blender/src/space.c 4 Sep 2006 12:48:25 -0000 1.376
+++ blender/src/space.c 13 Sep 2006 06:19:06 -0000
@@ -4349,6 +4349,19 @@
else
outliner_toggle_visible(sa);
break;
+ case FKEY:
+ {
+ /* search */
+ int search_flags=0;
+
+ /* CTRL=case sensitive, SHIFT=find again, ALT=complete */
+ if (G.qual & LR_CTRLKEY) search_flags |= 1;
+ if (G.qual & LR_SHIFTKEY) search_flags |= 16;
+ if (G.qual & LR_ALTKEY) search_flags |= 8;
+
+ outliner_find_panel(sa, search_flags);
+ }
+ break;
case WKEY:
outliner_operation_menu(sa);
break;
@@ -4893,7 +4906,9 @@
}
}
else if(sl->spacetype==SPACE_OOPS) {
- free_oopspace((SpaceOops *)sl);
+ SpaceOops *so= (SpaceOops *) sl;
+ if (so->lastfind) MEM_freeN(so->lastfind);
+ free_oopspace(so);
}
else if(sl->spacetype==SPACE_IMASEL) {
free_imasel((SpaceImaSel *)sl);

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
23/8e/e604d00872aeb2dcef38771a00f4

Event Timeline