diff options
author | Ton Roosendaal <ton@blender.org> | 2006-12-01 13:12:41 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-12-01 13:12:41 +0300 |
commit | f1a217c5f9f05045f1c38fb39ee12260ca4010b9 (patch) | |
tree | 451039312ff55214c5be9596a5d9c9d697f0921b /source/blender | |
parent | 610026765bbd121fe55a30b19117a28f13769503 (diff) |
Library manegement features:
- Outliner now shows hierarchy for Libraries, indicating which Library
files invoked loading another.
- SHIFT+F1 "Append" browser has a Library menu, allowing to directly browse
into all open library files. This will prevent accidents like re-opening
a same .blend via another path.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 116 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 8 | ||||
-rw-r--r-- | source/blender/src/filesel.c | 152 | ||||
-rw-r--r-- | source/blender/src/header_filesel.c | 1 | ||||
-rw-r--r-- | source/blender/src/outliner.c | 31 |
5 files changed, 107 insertions, 201 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 35613713855..fc0a7563084 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -403,8 +403,10 @@ static void add_main_to_main(Main *mainvar, Main *from) void blo_join_main(ListBase *mainlist) { - Main *tojoin, *mainl= mainlist->first; - + Main *tojoin, *mainl; + + + mainl= mainlist->first; while ((tojoin= mainl->next)) { add_main_to_main(mainl, tojoin); BLI_remlink(mainlist, tojoin); @@ -3731,99 +3733,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } } -/* ********** READ LIBRARY: facility to build a tree to see dependencies *************** */ - -typedef struct LibLink { - struct LibLink *prev, *next; - Main *lib; - ListBase tree; -} LibLink; - -static int library_add_dependency(LibLink *llink, Main *from, Main *to) -{ - LibLink *lc; - - if(llink->lib==from) { - for(lc= llink->tree.first; lc; lc= lc->next) - if(lc->lib==to) - break; - if(lc) - return; - - lc= MEM_callocN(sizeof(LibLink), "lib link"); - BLI_addtail(&llink->tree, lc); - lc->lib= to; - - if(from && from->curlib) printf("Added from %s to %s \n", from->curlib->name, to->curlib->name); - else printf("Added to %s\n", to->curlib->name); - - return 1; - } - else { - for(lc= llink->tree.first; lc; lc= lc->next) - if(library_add_dependency(lc, from, to)) - return 1; - } - if(from) printf("not added from %s to %s \n", from->curlib->name, to->curlib->name); - else printf("not added to %s\n", to->curlib->name); - return 0; -} - -static void library_print_dependency(LibLink *llink, int level) -{ - LibLink *lc; - - for(lc= llink->tree.first; lc; lc= lc->next) { - int a; - for(a=0; a<level; a++) - printf(" "); - printf("%s\n", lc->lib->curlib->name); - library_print_dependency(lc, level+1); - } -} - -static void library_free_dependency(LibLink *llink, int level) -{ - LibLink *lc, *next; - - for(lc= llink->tree.first; lc; lc= next) { - next= lc->next; - library_free_dependency(lc, 1); - } - if(level) - MEM_freeN(llink); -} - - -static void library_do_dependency(char mode, Main *from, Main *to) -{ - static int doit= 0; - static LibLink llink; - - return; // temporary disabled - - if(mode=='s') { /* start */ - memset(&llink, 0, sizeof(LibLink)); - llink.lib= from; - doit= 1; - return; - } - - if(doit==0) return; - - if(mode=='e') { /* end */ - library_print_dependency(&llink, 1); - library_free_dependency(&llink, 0); - doit= 0; - return; - } - if(mode=='a') { - library_add_dependency(&llink, from, to); - } -} - - - /* ********** READ LIBRARY *************** */ @@ -3858,8 +3767,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) newmain= MEM_callocN(sizeof(Main), "directlink"); BLI_addtail(&fd->mainlist, newmain); newmain->curlib= lib; - - library_do_dependency('a', main, newmain); + + lib->parent= NULL; } static void lib_link_library(FileData *fd, Main *main) @@ -6322,9 +6231,6 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) BLI_addtail(&fd->mainlist, bfd->main); bfd->main->versionfile= fd->fileversion; - - /* facility to print depsgraph */ - library_do_dependency('s', bfd->main, NULL); while(bhead) { switch(bhead->code) { @@ -6366,6 +6272,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) do_versions(fd, NULL, bfd->main); read_libraries(fd, &fd->mainlist); + blo_join_main(&fd->mainlist); lib_link_all(fd, bfd->main); @@ -6375,9 +6282,6 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) /* removed here: check for existance of curscreen/scene, moved to kernel setup_app */ MEM_freeN(fg); - - /* facility to print depsgraph */ - library_do_dependency('e', NULL, NULL); return bfd; } @@ -6439,7 +6343,9 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) if(bheadlib) { // BHEAD+DATA dependancy Library *lib= (Library *)(bheadlib+1); - /* we read the lib->name directly from the bhead, potential danger (64 bits?) */ + /* ***************************** */ + /* we read the lib->name directly from the bhead, no DNA, potential danger (64 bits?) */ + /* ***************************** */ Main *main= blo_find_main(&fd->mainlist, lib->name, fd->filename); id= is_yet_read(main, bhead); @@ -6449,7 +6355,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) if(G.f & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name); /* for outliner dependency only */ - library_do_dependency('a', mainvar, main); + main->curlib->parent= mainvar->curlib; } else { //oldnewmap_insert(fd->libmap, bhead->old, id, 1); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 638a225bd21..080d2861a19 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -117,14 +117,16 @@ typedef struct ID { /** * For each library file used, a Library struct is added to Main + * WARNING: readfile.c, expand_doit() reads this struct without DNA check! */ typedef struct Library { ID id; ID *idblock; struct FileData *filedata; - char name[240]; /* reveiled in the UI, can store relative path */ - char filename[240]; /* expanded name, not relative, used while reading */ - int tot, pad; /* tot, idblock and filedata are only fo read and write */ + char name[240]; /* reveiled in the UI, can store relative path */ + char filename[240]; /* expanded name, not relative, used while reading */ + int tot, pad; /* tot, idblock and filedata are only fo read and write */ + struct Library *parent; /* for outliner, showing dependency */ } Library; /** diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 00de9de21b3..815c9f8ebbd 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -139,6 +139,16 @@ int fnmatch(const char *pattern, const char *string, int flags) #define STARTSWITH(x, y) (strncmp(x, y, sizeof(x) - 1) == 0) +/* button events */ +#define B_FS_FILENAME 1 +#define B_FS_DIRNAME 2 +#define B_FS_DIR_MENU 3 +#define B_FS_PARDIR 4 +#define B_FS_LOAD 5 +#define B_FS_CANCEL 6 +#define B_FS_LIBNAME 7 + + static int is_a_library(SpaceFile *sfile, char *dir, char *group); static void do_library_append(SpaceFile *sfile); static void library_to_filelist(SpaceFile *sfile); @@ -148,7 +158,7 @@ static int groupname_to_code(char *group); extern void countall(void); -/* local globals */ +/* very bad local globals */ static rcti scrollrct, textrct, bar; static int filebuty1, filebuty2, page_ofs, collumwidth, selecting=0; @@ -1118,6 +1128,21 @@ static void draw_filetext(SpaceFile *sfile) uiEmboss(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax, 1); } +static char *library_string(void) +{ + Library *lib; + char *str; + int nr=0, tot= BLI_countlist(&G.main->library); + + if(tot==0) return NULL; + str= MEM_callocN(tot*(FILE_MAXDIR+FILE_MAXFILE), "filesel lib menu"); + + for(tot=0, lib= G.main->library.first; lib; lib= lib->id.next, nr++) { + tot+= sprintf(str+tot, "%s %%x%d|", lib->name+2, nr); + } + return str; +} + void drawfilespace(ScrArea *sa, void *spacedata) { SpaceFile *sfile; @@ -1126,7 +1151,7 @@ void drawfilespace(ScrArea *sa, void *spacedata) int act, loadbutton; short mval[2]; char name[20]; - char *menu; + char *menu, *strp= NULL; myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); @@ -1148,6 +1173,10 @@ void drawfilespace(ScrArea *sa, void *spacedata) } else calc_file_rcts(sfile); + /* check if we load library, extra button */ + if(sfile->type==FILE_LOADLIB) + strp= library_string(); + /* HEADER */ sprintf(name, "win %d", sa->win); block= uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win); @@ -1162,28 +1191,33 @@ void drawfilespace(ScrArea *sa, void *spacedata) else loadbutton= 0; uiBlockBeginAlign(block); - uiDefBut(block, TEX,2,"", textrct.xmin, filebuty2, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "Directory, enter a directory and press enter to create it"); /* Directory input */ + uiDefBut(block, TEX, B_FS_DIRNAME,"", textrct.xmin + (strp?20:0), filebuty2, textrct.xmax-textrct.xmin-loadbutton - (strp?20:0), 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "Directory, enter a directory and press enter to create it"); /* Directory input */ if(loadbutton) { uiSetCurFont(block, UI_HELV); - uiDefBut(block, BUT, 5, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, BUT, B_FS_LOAD, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); } uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefBut(block, TEX,1,"", textrct.xmin, filebuty1, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "File, increment version number with (+/-)"); /* File input */ + uiDefBut(block, TEX, B_FS_FILENAME,"", textrct.xmin, filebuty1, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "File, increment version number with (+/-)"); /* File input */ if(loadbutton) { uiSetCurFont(block, UI_HELV); - uiDefBut(block, BUT, 6, "Cancel", textrct.xmax-loadbutton, filebuty1, loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, BUT, B_FS_CANCEL, "Cancel", textrct.xmax-loadbutton, filebuty1, loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); } uiBlockEndAlign(block); menu= fsmenu_build_menu(); - if(menu[0]) // happens when no .Bfs is there, and first time browse - uiDefButS(block, MENU, 3, menu, scrollrct.xmin, filebuty1, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, ""); + if(menu[0]) /* happens when no .Bfs is there, and first time browse */ + uiDefButS(block, MENU, B_FS_DIR_MENU, menu, scrollrct.xmin, filebuty1, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, ""); MEM_freeN(menu); - uiDefBut(block, BUT, 4, "P", scrollrct.xmin, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)"); - + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_FS_PARDIR, "P", scrollrct.xmin, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)"); + if(strp) { + uiDefIconTextButS(block, MENU, B_FS_LIBNAME, ICON_LIBRARY_DEHLT, strp, scrollrct.xmin+20, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, ""); + MEM_freeN(strp); + } + uiDrawBlock(block); draw_filescroll(sfile); @@ -1587,7 +1621,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) { char butname[FILE_MAXDIR+FILE_MAXFILE]; - if (event == 1) { + if (event == B_FS_FILENAME) { if (strchr(sfile->file, '*') || strchr(sfile->file, '?') || strchr(sfile->file, '[')) { int i, match = FALSE; @@ -1602,7 +1636,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) scrarea_queue_winredraw(curarea); } } - else if(event== 2) { + else if(event== B_FS_DIRNAME) { /* reuse the butname variable */ BLI_cleanup_dir(G.sce, sfile->dir); @@ -1625,7 +1659,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) sfile->ofs= 0; scrarea_queue_winredraw(curarea); } - else if(event== 3) { + else if(event== B_FS_DIR_MENU) { char *selected= fsmenu_get_entry(sfile->menu-1); /* which string */ @@ -1641,11 +1675,26 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) sfile->act= -1; } - else if(event== 4) parent(sfile); - else if(event== 5) { - if(sfile->type) filesel_execute(sfile); + else if(event== B_FS_PARDIR) + parent(sfile); + else if(event== B_FS_LOAD) { + if(sfile->type) + filesel_execute(sfile); + } + else if(event== B_FS_CANCEL) + filesel_prevspace(); + else if(event== B_FS_LIBNAME) { + Library *lib= BLI_findlink(&G.main->library, sfile->menu); + if(lib) { + BLI_strncpy(sfile->dir, lib->filename, sizeof(sfile->dir)); + BLI_make_exist(sfile->dir); + BLI_cleanup_dir(G.sce, sfile->dir); + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); + sfile->act= -1; + } } - else if(event== 6) filesel_prevspace(); } @@ -2244,73 +2293,6 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group) return 1; } -/* orange hack... :) */ -static void do_sync_pose(Library *lib) -{ - Object *ob, *obt; - Base *base; - bArmature *arm; - - /* find the armature and the pose from library */ - for(ob= G.main->object.first; ob; ob= ob->id.next) - if(ob->type==OB_ARMATURE && ob->id.lib==lib) - break; - - if(ob==NULL || ob->pose==NULL) { - error("No pose appended"); - return; - } - - arm= ob->data; - - /* for all visible objects in this scene */ - for(base= G.scene->base.first; base; base= base->next) { - if((base->flag & SELECT)) { - obt= base->object; - if(obt->type==OB_ARMATURE && obt->pose && ob!=obt) { - char str[128]; - - sprintf(str, "Replace Object %s", obt->id.name); - if(okee(str)) { - bPoseChannel *chan; - bArmature *oldarm= obt->data; - - /* link armature */ - oldarm->id.us--; - obt->data= arm; - arm->id.us++; - - /* link pose */ - free_pose_channels(obt->pose); - MEM_freeN(obt->pose); - copy_pose(&obt->pose, ob->pose, 1); - - /* relink */ - ob->id.newid= &obt->id; - for (chan = obt->pose->chanbase.first; chan; chan=chan->next){ - relink_constraints(&chan->constraints); - } - - obt->pose->flag |= POSE_RECALC; - obt->recalc |= OB_RECALC_DATA; - } - } - } - } - - /* prevent saving in file, unlink from scene */ - for(base= G.scene->base.first; base; base= base->next) { - if(base->object==ob) - break; - } - - if(base) { - free_and_unlink_base(base); - } - - DAG_scene_sort(G.scene); // for accidentally appended other objects -} - static void do_library_append(SpaceFile *sfile) { Library *lib; @@ -2347,8 +2329,6 @@ static void do_library_append(SpaceFile *sfile) } if(lib) { - if(sfile->flag & FILE_SYNCPOSE) - do_sync_pose(lib); if((sfile->flag & FILE_LINK)==0) all_local(lib); } diff --git a/source/blender/src/header_filesel.c b/source/blender/src/header_filesel.c index 74886c8495c..4e7c94e7181 100644 --- a/source/blender/src/header_filesel.c +++ b/source/blender/src/header_filesel.c @@ -145,7 +145,6 @@ void file_buttons(void) uiDefButBitS(block, TOG, FILE_AUTOSELECT, B_REDR, "Autosel", xco+=125,0,65,YIC, &sfile->flag, 0, 0, 0, 0, "Autoselect imported objects"); uiDefButBitS(block, TOG, FILE_ACTIVELAY, B_REDR, "Active Layer", xco+=65,0,80,YIC, &sfile->flag, 0, 0, 0, 0, "Append object(s) in active layer"); uiDefButBitS(block, TOG, FILE_ATCURSOR, B_REDR, "At Cursor", xco+=80,0,65,YIC, &sfile->flag, 0, 0, 0, 0, "Append object(s) at cursor, use centroid if more than one object is selected"); - uiDefButBitS(block, TOG, FILE_SYNCPOSE, B_REDR, "Sync Pose", xco+=80,0,65,YIC, &sfile->flag, 0, 0, 0, 0, "If Object with Pose appended, link the Pose and Armature to all selected Objects"); uiBlockEndAlign(block); xco+= 100; // scroll diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 18ef168b7e6..565a4998c0e 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -842,9 +842,29 @@ static void outliner_build_tree(SpaceOops *soops) /* options */ if(soops->outlinevis == SO_LIBRARIES) { Library *lib; + for(lib= G.main->library.first; lib; lib= lib->id.next) { - outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); - } + ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); + 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 if(soops->outlinevis == SO_ALL_SCENES) { Scene *sce; @@ -1637,9 +1657,9 @@ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStore return 0; } +#ifdef WITH_VERSE static void verse_operation_menu(TreeElement *te) { -#ifdef WITH_VERSE short event=0; if(te->idcode==ID_VS) { struct VerseSession *session = (VerseSession*)te->directdata; @@ -1713,9 +1733,8 @@ static void verse_operation_menu(TreeElement *te) break; } } -#endif - } +#endif static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short event, float *mval) @@ -2711,7 +2730,7 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen case ID_GR: BIF_icon_draw(x, y, ICON_CIRCLE_DEHLT); break; case ID_LI: - BIF_icon_draw(x, y, ICON_PARLIB); break; + BIF_icon_draw(x, y, ICON_LIBRARY_DEHLT); break; } } } |