New feature: imporant missing option for use of Libraries: access to to the
authorTon Roosendaal <ton@blender.org>
Wed, 6 Sep 2006 09:51:30 +0000 (09:51 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 6 Sep 2006 09:51:30 +0000 (09:51 +0000)
file path where library is read from.

In Outliner, choose new view mode "Libraries". A ctrl+click on the library
name then allows to change the file name or path. Note that when you change
the file name, nothing is being re-read or re-linked. Only after saving the
.blend file and reading it back the new library is used.

This feature allows to cleanup library usage. You can make files relative,
or reorganize a project. Just keep in mind that you cannot use this feature
to fix .blend files that link to non-existing other files. That because the
lost data is actually not read at all, so cannot be saved either.

Currently, library errors are only printed in the console... quite
important to keep track of when using Libraries.

Implementation note: this Outliner view mode can become expanded to a full
"Database view", showing something similar as SHIFT+F4 databrowse does now.

source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/library.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_space_types.h
source/blender/src/header_oops.c
source/blender/src/outliner.c

index ac438ec95bd2f6b410bf5652bd212ad453d33706..c51ebe252268662e4e9087f28b797bc12b0fb16f 100644 (file)
@@ -50,6 +50,8 @@ void id_us_plus(struct ID *id);
 int new_id(struct ListBase *lb, struct ID *id, const char *name);
 
 struct ListBase *wich_libbase(struct Main *mainlib, short type);
+
+#define MAX_LIBARRAY   40
 int set_listbasepointers(struct Main *main, struct ListBase **lb);
 
 void free_libblock(struct ListBase *lb, void *idv);
index 5628e4bc491f3265f839d54d72823fe3c02588ea..2917853b72daa4645f9a72f1439a50b5cb36d5b1 100644 (file)
 #include "BPI_script.h"
 
 #define MAX_IDPUP              60      /* was 24 */
-#define MAX_LIBARRAY   100 /* was 30, warning: used it readfile.c too */
 
 /* ************* general ************************ */
 
@@ -201,6 +200,7 @@ ListBase *wich_libbase(Main *mainlib, short type)
        return 0;
 }
 
+/* note: MAX_LIBARRAY define should match this code */
 int set_listbasepointers(Main *main, ListBase **lb)
 {
        /* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
index 09b040be7315bab52df11064299272a30a4ff47d..6ece27c2e462dc3912282bfa5aa1b2675b8a4dce 100644 (file)
@@ -384,7 +384,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist);
 
 static void add_main_to_main(Main *mainvar, Main *from)
 {
-       ListBase *lbarray[100], *fromarray[100];        // define in library.c too
+       ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
        int a;
 
        a= set_listbasepointers(mainvar, lbarray);
@@ -434,7 +434,7 @@ static void split_libdata(ListBase *lb, Main *first)
 void blo_split_main(ListBase *mainlist)
 {
        Main *mainl= mainlist->first;
-       ListBase *lbarray[30];
+       ListBase *lbarray[MAX_LIBARRAY];
        Library *lib;
        int i;
 
@@ -6260,7 +6260,7 @@ static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
 
 static void expand_main(FileData *fd, Main *mainvar)
 {
-       ListBase *lbarray[30];
+       ListBase *lbarray[MAX_LIBARRAY];
        ID *id;
        int a, doit= 1;
 
@@ -6643,7 +6643,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
 
 static int mainvar_count_libread_blocks(Main *mainvar)
 {
-       ListBase *lbarray[30];
+       ListBase *lbarray[MAX_LIBARRAY];
        int a, tot= 0;
 
        a= set_listbasepointers(mainvar, lbarray);
@@ -6661,7 +6661,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 {
        Main *mainl= mainlist->first;
        Main *mainptr;
-       ListBase *lbarray[30];
+       ListBase *lbarray[MAX_LIBARRAY];
        int a, doit= 1;
 
        while(doit) {
index c885c709c0e772cd5cbc5119b11973a7242a8f18..6f21eb86f56d25c87ca61f620c88e54524db8e0c 100644 (file)
@@ -526,6 +526,7 @@ typedef struct SpaceImaSel {
 #define SO_ACTIVE              4
 #define SO_SAME_TYPE   5
 #define SO_GROUPS              6
+#define SO_LIBRARIES   7
 
 /* SpaceOops->storeflag */
 #define SO_TREESTORE_CLEANUP   1
index f84cee782d7ac1bb70f589f5a9e8b3525a9b56b7..98dbced9dbd64ced1654c2ae6437928a1b49df99 100644 (file)
@@ -477,7 +477,10 @@ void oops_buttons(void)
        } 
 #endif
        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, "");
+               if(G.main->library.first)
+                       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, "");
+               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, "");
        }
        
        /* always do as last */
index 187106e79d6088100b84a185cae98de59a4d1d33..e5c4797209a0f3f83b1292f7073eef819daf6663 100644 (file)
@@ -399,7 +399,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        
        te->parent= parent;
        te->index= index;       // for data arays
-       te->name= id->name+2; // default, can be overridden by non-ID data
+       te->name= id->name+2; // default, can be overridden by Library or non-ID data
        te->idcode= GS(id->name);
        
        if(type==0) {
@@ -409,6 +409,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                
                /* expand specific data always */
                switch(GS(id->name)) {
+               case ID_LI:
+                       te->name= ((Library *)id)->name;
+                       break;
                case ID_SCE:
                        {
                                Scene *sce= (Scene *)id;
@@ -788,7 +791,6 @@ static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb)
 
 static void outliner_build_tree(SpaceOops *soops)
 {
-       Scene *sce;
        Base *base;
        Object *ob;
        TreeElement *te, *ten;
@@ -804,8 +806,15 @@ static void outliner_build_tree(SpaceOops *soops)
        /* clear ob id.new flags */
        for(ob= G.main->object.first; ob; ob= ob->id.next) ob->id.newid= NULL;
        
-       /* option 1: all scenes */
-       if(soops->outlinevis == SO_ALL_SCENES) {
+       /* 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);
+               }
+       }
+       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);
                        tselem= TREESTORE(te);
@@ -848,7 +857,7 @@ static void outliner_build_tree(SpaceOops *soops)
                                
                                for(go= group->gobject.first; go; go= go->next) {
                                        ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
-                                       ten->directdata= NULL;
+                                       ten->directdata= NULL; /* eh, why? */
                                }
                                outliner_make_hierarchy(soops, &te->subtree);
                                /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
@@ -2134,7 +2143,7 @@ void outliner_operation_menu(ScrArea *sa)
 {
        SpaceOops *soops= sa->spacedata.first;
        
-       // globals
+       // bad globals
        scenelevel= objectlevel= idlevel= datalevel=0;
        
        set_operation_types(soops, &soops->tree);
@@ -2360,6 +2369,8 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
                                BIF_icon_draw(x, y, ICON_SCRIPT); break;
                        case ID_GR:
                                BIF_icon_draw(x, y, ICON_CIRCLE_DEHLT); break;
+                       case ID_LI:
+                               BIF_icon_draw(x, y, ICON_PARLIB); break;
                }
        }
 }
@@ -2739,6 +2750,7 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
                        
                        if(tselem->type==TSE_EBONE) len = sizeof(((EditBone*) 0)->name);
                        else if (tselem->type==TSE_MODIFIER) len = sizeof(((ModifierData*) 0)->name);
+                       else if(tselem->id && GS(tselem->id->name)==ID_LI) len = sizeof(((Library*) 0)->name);
                        else len= sizeof(((ID*) 0)->name)-2;
                        
                        dx= BIF_GetStringWidth(G.font, te->name, 0);