2.5 filebrowser
authorAndrea Weikert <elubie@gmx.net>
Sat, 12 Sep 2009 19:54:39 +0000 (19:54 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sat, 12 Sep 2009 19:54:39 +0000 (19:54 +0000)
Appending and Linking
* Linking Operator, invokes filebrowser for Append/Link
* Separated the append/link function into three parts:
** BLO_library_append_begin finds main for appending
** BLO_library_append_named_part appends one Object,Group, Material, ...
** BLO_library_append_end actually reads and expands the libraries

NOTE 1:
I also changed the returned properties for the filebrowser operators to the following convention:
"path" - the full path to a file or directory, means what is in directory + filename buttons in filebrowser
"directory" - the content of the directory button in filebrowser
"filename" - the content of the filename button in filebrowser
Usually only path should be required, but in some cases it might be more convenient to retrieve the parts separately.

Ton, Brecht: If you have time to take a look, let me know if anything needs to be fixed.

30 files changed:
projectfiles_vc9/blender/loader/BLO_loader.vcproj
release/io/export_ply.py
release/ui/space_info.py
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/library.c
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readfile.c
source/blender/editors/curve/editfont.c
source/blender/editors/screen/screendump.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/file_panels.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/space_file.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_info/info_ops.c
source/blender/editors/space_script/script_edit.c
source/blender/editors/space_script/script_ops.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_text/text_ops.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_define.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c

index a8cec5ecf76002ba50f1ef82e7edb1b392469f71..e8b155875d00afba713d9b99e399482138d9fe67 100644 (file)
        <References>\r
        </References>\r
        <Files>\r
-               <Filter\r
-                       Name="Source Files"\r
-                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
-                       >\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"\r
-                               >\r
-                       </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"\r
-                               >\r
-                               <FileConfiguration\r
-                                       Name="Blender Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="3D Plugin Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="3D Plugin Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="Blender Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="BlenderPlayer Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="BlenderPlayer Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                       </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"\r
-                               >\r
-                       </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"\r
-                               >\r
-                               <FileConfiguration\r
-                                       Name="Blender Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="3D Plugin Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="3D Plugin Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="Blender Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="BlenderPlayer Debug|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                               <FileConfiguration\r
-                                       Name="BlenderPlayer Release|Win32"\r
-                                       >\r
-                                       <Tool\r
-                                               Name="VCCLCompilerTool"\r
-                                               AdditionalIncludeDirectories=""\r
-                                       />\r
-                               </FileConfiguration>\r
-                       </File>\r
-               </Filter>\r
                <Filter\r
                        Name="Header Files"\r
                        Filter="h;hpp;hxx;hm;inl"\r
                                RelativePath="..\..\..\source\blender\blenloader\BLO_undofile.h"\r
                                >\r
                        </File>\r
+                       <Filter\r
+                               Name="Source Files"\r
+                               Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Blender Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="3D Plugin Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="3D Plugin Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Blender Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="BlenderPlayer Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="BlenderPlayer Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Blender Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="3D Plugin Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="3D Plugin Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Blender Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="BlenderPlayer Debug|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="BlenderPlayer Release|Win32"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       AdditionalIncludeDirectories=""\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                       </Filter>\r
                </Filter>\r
        </Files>\r
        <Globals>\r
index c293119d3c8b84cb591b0b02b61d433bc4e86ead..7a3253b2d1699d87d9a4fbaf9065934e1c3546f9 100644 (file)
@@ -242,7 +242,7 @@ class EXPORT_OT_ply(bpy.types.Operator):
        # to the class instance from the operator settings before calling.
        
        __props__ = [
-               bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
+               bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
                bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
                bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
                bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
index 97243f857a63000daec5c0c6b142fab1f3785294..6b2a457e89deebf8d8bec2eb30a9b1b76cdb884a 100644 (file)
@@ -59,6 +59,9 @@ class INFO_MT_file(bpy.types.Menu):
                layout.itemO("wm.save_as_mainfile", text="Save As...")
                layout.itemO("screen.userpref_show", text="User Preferences...")
 
+               layout.itemS()
+               layout.operator_context = "INVOKE_AREA"
+               layout.itemO("wm.link_append", text="Append or Link")
                layout.itemS()
 
                layout.itemM("INFO_MT_file_import")
index 54722dac910c237f5ffecb3be13454e77a1fd053..0e978128cf6bc65b9bbbca49432b17c65489d2fb 100644 (file)
@@ -77,6 +77,7 @@ void IPOnames_to_pupstring(char **str, char *title, char *extraops, struct ListB
 
 void flag_listbase_ids(ListBase *lb, short flag, short value);
 void flag_all_listbases_ids(short flag, short value);
+void recalc_all_library_objects(struct Main *main);
 
 void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
 
index 02d92a62b59b11dda9a75be6400439bbc69de3be..da7692d0cdb438a75915f30f2fba9670dcf078b8 100644 (file)
@@ -455,6 +455,17 @@ void flag_all_listbases_ids(short flag, short value)
        while(a--)      flag_listbase_ids(lbarray[a], flag, value);
 }
 
+void recalc_all_library_objects(struct Main *main)
+{
+       /* DISPLISTS? */
+       Object *ob= main->object.first;
+       while(ob) {
+               if(ob->id.lib) {
+                       ob->recalc |= OB_RECALC;
+               }
+               ob= ob->id.next;
+       }
+}
 
 /* note: MAX_LIBARRAY define should match this code */
 int set_listbasepointers(Main *main, ListBase **lb)
index 4fafac29a6f246e16467f85a0ace1e382715c726..6e2772efea41db6d385fd90546f85ac5666ba5fe 100644 (file)
@@ -36,7 +36,6 @@ extern "C" {
 
 struct bScreen;
 struct direntry;
-struct FileList;
 struct LinkNode;
 struct Main;
 struct MemFile;
@@ -45,6 +44,7 @@ struct Scene;
 struct SpaceFile;
 struct SpaceImaSel;
 struct UserDef;
+struct bContext;
 
 typedef struct BlendHandle     BlendHandle;
 
@@ -197,12 +197,23 @@ BLO_blendhandle_close(
        
        /***/
 
-char *BLO_gethome(void);
+#define GROUP_MAX 32
+
 int BLO_has_bfile_extension(char *str);
 
-void BLO_library_append(BlendHandle **libfiledata, struct direntry* filelist, int totfile, 
-                                                char *dir, char* file, short flag, int idcode, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
+/* return ok when a blenderfile, in dir is the filename,
+ * in group the type of libdata
+ */
+int BLO_is_a_library(char *path, char *dir, char *group);
+
+struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir);
+void BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, char *name, int idcode, short flag);
+void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
+
+/* deprecated */
+#if 0
 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
+#endif
 
 BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, struct ReportList *reports);
 
index 99285fefb4daf31b67af995deb562b203ad4edac..83abd5c2b4d670e704d51314dcaa3ec2883094dc 100644 (file)
 #include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_deform.h"
@@ -1065,6 +1066,46 @@ int BLO_has_bfile_extension(char *str)
        return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz"));
 }
 
+int BLO_is_a_library(char *path, char *dir, char *group)
+{
+       /* return ok when a blenderfile, in dir is the filename,
+        * in group the type of libdata
+        */
+       int len;
+       char *fd;
+       
+       strcpy(dir, path);
+       len= strlen(dir);
+       if(len<7) return 0;
+       if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
+       
+       group[0]= 0;
+       dir[len-1]= 0;
+
+       /* Find the last slash */
+       fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+
+       if(fd==0) return 0;
+       *fd= 0;
+       if(BLO_has_bfile_extension(fd+1)) {
+               /* the last part of the dir is a .blend file, no group follows */
+               *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */
+       }
+       else {          
+               char *gp = fd+1; // in case we have a .blend file, gp points to the group
+
+               /* Find the last slash */
+               fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+               if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
+
+               /* now we know that we are in a blend file and it is safe to 
+                  assume that gp actually points to a group */
+               if (BLI_streq("Screen", gp)==0)
+                       BLI_strncpy(group, gp, GROUP_MAX);
+       }
+       return 1;
+}
+
 /* ************** OLD POINTERS ******************* */
 
 static void *newdataadr(FileData *fd, void *adr)               /* only direct databocks */
@@ -10729,8 +10770,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
 }
 
 
-static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag)
+static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag)
 {
+       Scene *scene= CTX_data_scene(C);
        Object *ob;
        Base *base;
        BHead *bhead;
@@ -10746,9 +10788,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                
                        if(strcmp(idname+2, name)==0) {
 
-                               id= is_yet_read(fd, mainvar, bhead);
+                               id= is_yet_read(fd, mainl, bhead);
                                if(id==NULL) {
-                                       read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
+                                       read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
                                }
                                else {
                                        printf("append: already linked\n");
@@ -10763,13 +10805,18 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        base= MEM_callocN( sizeof(Base), "app_nam_part");
                                        BLI_addtail(&scene->base, base);
 
-                                       if(id==NULL) ob= mainvar->object.last;
+                                       if(id==NULL) ob= mainl->object.last;
                                        else ob= (Object *)id;
                                        
-                                       /* XXX use context to find view3d->lay */
-                                       //if((flag & FILE_ACTIVELAY)) {
-                                       //      scene->lay;
-                                       //}
+                                       /* link at active layer (view3d->lay if in context, else scene->lay */
+                                       if((flag & FILE_ACTIVELAY)) {
+                                               View3D *v3d = CTX_wm_view3d(C);
+                                               if (v3d) {
+                                                       ob->lay = v3d->layact;
+                                               } else {
+                                                       ob->lay = scene->lay;
+                                               }
+                                       }
                                        base->lay= ob->lay;
                                        base->object= ob;
                                        ob->id.us++;
@@ -10788,6 +10835,12 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
        }
 }
 
+void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, char *name, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       append_named_part(C, mainl, fd, name, idcode, flag);
+}
+
 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 {
        BHead *bhead;
@@ -10810,11 +10863,10 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
 /* common routine to append/link something from a library */
 
-static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode,
-               int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
+static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
 {
+       Main *mainvar= CTX_data_main(C);
        Main *mainl;
-       Library *curlib;
 
        /* make mains */
        blo_split_main(&(*fd)->mainlist, mainvar);
@@ -10824,19 +10876,69 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        
        mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
        
-       curlib= mainl->curlib;
+       return mainl;
+}
+
+Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir)
+{
+       FileData *fd= (FileData*)(*bh);
+       return library_append_begin(C, &fd, dir);
+}
+
+static void append_do_cursor(Scene *scene, Library *curlib, short flag)
+{
+       Base *centerbase;
+       Object *ob;
+       float *curs, centerloc[3], vec[3], min[3], max[3];
+       int count= 0;
+
+       /* when not linking (appending)... */
+       if(flag & FILE_LINK) 
+               return;
+
+       /* we're not appending at cursor */
+       if((flag & FILE_ATCURSOR) == 0) 
+               return;
        
-       if(totsel==0) {
-               append_named_part(*fd, mainl, scene, file, idcode, flag);
+       /* find the center of everything appended */
+       INIT_MINMAX(min, max);
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       VECCOPY(vec, centerbase->object->loc);
+                       DO_MINMAX(vec, min, max);
+                       count++;
+               }
+               centerbase= centerbase->next;
        }
-       else {
-               int a;
-               for(a=0; a<totfile; a++) {
-                       if(filelist[a].flags & ACTIVE) {
-                               append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
-                       }
+       /* we haven't found any objects to move to cursor */
+       if(!count) 
+               return;
+       
+       /* move from the center of the appended objects to cursor */
+       centerloc[0]= (min[0]+max[0])/2;
+       centerloc[1]= (min[1]+max[1])/2;
+       centerloc[2]= (min[2]+max[2])/2;
+       curs = scene->cursor;
+       VECSUB(centerloc,curs,centerloc);
+       
+       /* now translate the center of the objects */
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       ob= centerbase->object;
+                       ob->loc[0] += centerloc[0];
+                       ob->loc[1] += centerloc[1];
+                       ob->loc[2] += centerloc[2];
                }
+               centerbase= centerbase->next;
        }
+}
+
+static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
+{
+       Main *mainvar= CTX_data_main(C);
+       Scene *scene= CTX_data_scene(C);
 
        /* make main consistant */
        expand_main(*fd, mainl);
@@ -10844,6 +10946,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        /* do this when expand found other libs */
        read_libraries(*fd, &(*fd)->mainlist);
 
+       /* make the lib path relative if required */
        if(flag & FILE_STRINGCODE) {
 
                /* use the full path, this could have been read by other library even */
@@ -10866,7 +10969,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
                        if (flag & FILE_LINK) {
                                give_base_to_objects(mainvar, scene, NULL, 0);
                        } else {
-                               give_base_to_objects(mainvar, scene, curlib, 1);
+                               give_base_to_objects(mainvar, scene, mainl->curlib, 1);
                        }       
                } else {
                        give_base_to_objects(mainvar, scene, NULL, 0);
@@ -10882,14 +10985,23 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
                *fd = NULL;
        }       
 
-       return curlib;
+       append_do_cursor(scene, mainl->curlib, flag);
+}
+
+void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       library_append_end(C, mainl, &fd, idcode, flag);
+       *bh= (BlendHandle*)fd;
 }
 
 /* this is a version of BLO_library_append needed by the BPython API, so
  * scripts can load data from .blend files -- see Blender.Library module.*/
 /* append to scene */
 /* this should probably be moved into the Python code anyway */
-
+/* tentatively removed, Python should be able to use the split functions too: */
+/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */
+#if 0 
 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, 
                int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
 {
@@ -10906,88 +11018,7 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
 
        *bh= (BlendHandle*)fd;
 }
-
-/* append to scene */
-void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile, 
-                                                char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports)
-{
-       FileData *fd= (FileData*)(*bh);
-       Library *curlib;
-       Base *centerbase;
-       Object *ob;
-       int a, totsel=0;
-       
-       /* are there files selected? */
-       for(a=0; a<totfile; a++) {
-               if(filelist[a].flags & ACTIVE) {
-                       totsel++;
-               }
-       }
-
-       if(totsel==0) {
-               /* is the indicated file in the filelist? */
-               if(file[0]) {
-                       for(a=0; a<totfile; a++) {
-                               if( strcmp(filelist[a].relname, file)==0) break;
-                       }
-                       if(a==totfile) {
-                               BKE_report(reports, RPT_ERROR, "Wrong indicated name");
-                               return;
-                       }
-               }
-               else {
-                       BKE_report(reports, RPT_ERROR, "Nothing indicated");
-                       return;
-               }
-       }
-       /* now we have or selected, or an indicated file */
-       
-       if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
-
-       fd->reports= reports;
-       curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
-       if(fd) fd->reports= NULL;
-
-       *bh= (BlendHandle*)fd;
-
-       /* when not linking (appending)... */
-       if((flag & FILE_LINK)==0) {
-               if(flag & FILE_ATCURSOR) {
-                       float *curs, centerloc[3], vec[3], min[3], max[3];
-                       int count= 0;
-                       
-                       INIT_MINMAX(min, max);
-                       
-                       centerbase= (scene->base.first);
-                       while(centerbase) {
-                               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                       VECCOPY(vec, centerbase->object->loc);
-                                       DO_MINMAX(vec, min, max);
-                                       count++;
-                               }
-                               centerbase= centerbase->next;
-                       }
-                       if(count) {
-                               centerloc[0]= (min[0]+max[0])/2;
-                               centerloc[1]= (min[1]+max[1])/2;
-                               centerloc[2]= (min[2]+max[2])/2;
-                               curs = scene->cursor;
-                               VECSUB(centerloc,curs,centerloc);
-                       
-                               centerbase= (scene->base.first);
-                               while(centerbase) {
-                                       if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                               ob= centerbase->object;
-                                               ob->loc[0] += centerloc[0];
-                                               ob->loc[1] += centerloc[1];
-                                               ob->loc[2] += centerloc[2];
-                                       }
-                                       centerbase= centerbase->next;
-                               }
-                       }
-               }
-       }
-}
+#endif
 
 /* ************* READ LIBRARY ************** */
 
index a9736f3f88dea3b33f4f0c2c24b241c33b36bc0d..868c5902670943d94c2362a15ee3ca1b33d10b5e 100644 (file)
@@ -417,7 +417,7 @@ void FONT_OT_file_paste(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL);
 }
 
 /******************* paste buffer operator ********************/
index 5ae1bdf84aa4f4408b720c92a6f9e921507c6f1c..fb3da4a53539a39d5ff57103cbc681f377d7ba53 100644 (file)
@@ -73,24 +73,24 @@ static int screenshot_exec(bContext *C, wmOperator *op)
        if(scd && scd->dumprect) {
                Scene *scene= CTX_data_scene(C);
                ImBuf *ibuf;
-               char filename[FILE_MAX];
+               char path[FILE_MAX];
        
-               RNA_string_get(op->ptr, "filename", filename);
+               RNA_string_get(op->ptr, "path", path);
        
-               strcpy(G.ima, filename);
-               BLI_convertstringcode(filename, G.sce);
+               strcpy(G.ima, path);
+               BLI_convertstringcode(path, G.sce);
                
                /* BKE_add_image_extension() checks for if extension was already set */
                if(scene->r.scemode & R_EXTENSION) 
-                       if(strlen(filename)<FILE_MAXDIR+FILE_MAXFILE-5)
-                               BKE_add_image_extension(scene, filename, scene->r.imtype);
+                       if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
+                               BKE_add_image_extension(scene, path, scene->r.imtype);
                
                ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0, 0);
                ibuf->rect= scd->dumprect;
                
                if(scene->r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
                
-               BKE_write_ibuf(scene, ibuf, filename, scene->r.imtype, scene->r.subimtype, scene->r.quality);
+               BKE_write_ibuf(scene, ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality);
 
                IMB_freeImBuf(ibuf);
 
@@ -149,10 +149,10 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *event)
                scd->dumprect= dumprect;
                op->customdata= scd;
                
-               if(RNA_property_is_set(op->ptr, "filename"))
+               if(RNA_property_is_set(op->ptr, "path"))
                        return screenshot_exec(C, op);
                
-               RNA_string_set(op->ptr, "filename", G.ima);
+               RNA_string_set(op->ptr, "path", G.ima);
                
                WM_event_add_fileselect(C, op);
        
@@ -173,7 +173,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
        
        ot->flag= 0;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL);
        RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "");
 }
 
@@ -327,7 +327,7 @@ void SCREEN_OT_screencast(wmOperatorType *ot)
        
        ot->flag= 0;
        
-       RNA_def_property(ot->srna, "filename", PROP_STRING, PROP_FILEPATH);
+       RNA_def_property(ot->srna, "path", PROP_STRING, PROP_FILEPATH);
        RNA_def_boolean(ot->srna, "full", 1, "Full Screen", "");
 }
 
index 303ca0eaefd396d293f7ad3e89ea48d47c0de478..1121a3bcbcdf03d42632023a4d768d9ae307840c 100644 (file)
 
 static int open_exec(bContext *C, wmOperator *op)
 {
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
        bSound *sound;
        AUD_SoundInfo info;
 
-       RNA_string_get(op->ptr, "filename", filename);
+       RNA_string_get(op->ptr, "path", path);
 
-       sound = sound_new_file(CTX_data_main(C), filename);
+       sound = sound_new_file(CTX_data_main(C), path);
 
        if (sound==NULL || sound->handle == NULL) {
                BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
@@ -114,7 +114,7 @@ void SOUND_OT_open(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL);
        RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
 }
 
index 481c2d6cfc339f3083946fa8a87670c2503b0e73..9b335b86163d78b2ed7fc36f7adc8ff7c60aa216 100644 (file)
@@ -1069,10 +1069,10 @@ static int file_browse_exec(bContext *C, wmOperator *op)
        FileBrowseOp *fbo= op->customdata;
        char *str;
        
-       if (RNA_property_is_set(op->ptr, "filename")==0 || fbo==NULL)
+       if (RNA_property_is_set(op->ptr, "path")==0 || fbo==NULL)
                return OPERATOR_CANCELLED;
        
-       str= RNA_string_get_alloc(op->ptr, "filename", 0, 0);
+       str= RNA_string_get_alloc(op->ptr, "path", 0, 0);
        RNA_property_string_set(&fbo->ptr, fbo->prop, str);
        RNA_property_update(C, &fbo->ptr, fbo->prop);
        MEM_freeN(str);
@@ -1128,6 +1128,6 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
        ot->cancel= file_browse_cancel;
 
        /* properties */
-       WM_operator_properties_filesel(ot, 0);
+       WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
 }
 
index e1a6e346ce248b9530d31e6ac6c7e973573aa25c..5d3c2c766a3815e7b2e46c1b10e79a902a7c1140 100644 (file)
@@ -520,9 +520,11 @@ int file_exec(bContext *C, wmOperator *unused)
                wmOperator *op= sfile->op;
                
                sfile->op = NULL;
+               RNA_string_set(op->ptr, "filename", sfile->params->file);
                BLI_strncpy(name, sfile->params->dir, sizeof(name));
+               RNA_string_set(op->ptr, "directory", name);
                strcat(name, sfile->params->file);
-               RNA_string_set(op->ptr, "filename", name);
+               RNA_string_set(op->ptr, "path", name);
                
                /* some ops have multiple files to select */
                {
@@ -872,11 +874,13 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
 int file_filenum_exec(bContext *C, wmOperator *op)
 {
        SpaceFile *sfile= CTX_wm_space_file(C);
+       ScrArea *sa= CTX_wm_area(C);
        
        int inc = RNA_int_get(op->ptr, "increment");
        if(sfile->params && (inc != 0)) {
                BLI_newname(sfile->params->file, inc);
-               WM_event_add_notifier(C, NC_WINDOW, NULL);
+               ED_area_tag_redraw(sa);
+               // WM_event_add_notifier(C, NC_WINDOW, NULL);
        }
        
        return OPERATOR_FINISHED;
@@ -916,6 +920,24 @@ int file_rename_exec(bContext *C, wmOperator *op)
 
 }
 
+int file_rename_poll(bContext *C)
+{
+       int poll = ED_operator_file_active(C);
+       SpaceFile *sfile= CTX_wm_space_file(C);
+
+       if (sfile && sfile->params) {
+               if (sfile->params->active_file < 0) { 
+                       poll= 0;
+               } else {
+                       char dir[FILE_MAX], group[FILE_MAX];    
+                       if (filelist_islibrary(sfile->files, dir, group)) poll= 0;
+               }
+       }
+       else
+               poll= 0;
+       return poll;
+}
+
 void FILE_OT_rename(struct wmOperatorType *ot)
 {
        /* identifiers */
@@ -924,7 +946,7 @@ void FILE_OT_rename(struct wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec= file_rename_exec;
-       ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+       ot->poll= file_rename_poll; 
 
 }
 
@@ -938,6 +960,8 @@ int file_delete_poll(bContext *C)
                if (sfile->params->active_file < 0) { 
                        poll= 0;
                } else {
+                       char dir[FILE_MAX], group[FILE_MAX];    
+                       if (filelist_islibrary(sfile->files, dir, group)) poll= 0;
                        file = filelist_file(sfile->files, sfile->params->active_file);
                        if (file && S_ISDIR(file->type)) poll= 0;
                }
index 24c3f9b4ca1ba6252eca270975891f04ecd2df1a..2d351016893a7f293a82ac59c9f05ba5742aa768 100644 (file)
@@ -181,6 +181,12 @@ static void file_panel_operator(const bContext *C, Panel *pa)
                RNA_STRUCT_BEGIN(op->ptr, prop) {
                        if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
                                continue;
+                       if(strcmp(RNA_property_identifier(prop), "type") == 0)
+                               continue;
+                       if(strcmp(RNA_property_identifier(prop), "path") == 0)
+                               continue;
+                       if(strcmp(RNA_property_identifier(prop), "directory") == 0)
+                               continue;
                        if(strcmp(RNA_property_identifier(prop), "filename") == 0)
                                continue;
                        if(strcmp(RNA_property_identifier(prop), "display") == 0)
index 538c1e4fce79f95a30bfc991eb257c18dea29cae..23f24f26dc0ff859d5025f9910e508a225a108e8 100644 (file)
@@ -60,6 +60,7 @@
 #include "BKE_library.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
+#include "BKE_report.h"
 #include "BLO_readfile.h"
 
 #include "DNA_space_types.h"
@@ -109,7 +110,6 @@ typedef struct FileList
 {
        struct direntry *filelist;
        int *fidx;
-
        int numfiles;
        int numfiltered;
        char dir[FILE_MAX];
@@ -118,6 +118,12 @@ typedef struct FileList
        short hide_dot;
        unsigned int filter;
        short changed;
+
+       struct BlendHandle *libfiledata;
+       short hide_parent;
+
+       void (*read)(struct FileList *);
+
        ListBase loadimages;
        ListBase threads;
 } FileList;
@@ -277,12 +283,20 @@ static int compare_extension(const void *a1, const void *a2) {
 
 void filelist_filter(FileList* filelist)
 {
+       /* char dir[FILE_MAX], group[GROUP_MAX]; XXXXX */
        int num_filtered = 0;
        int i, j;
        
        if (!filelist->filelist)
                return;
        
+       /* XXXXX TODO: check if the filter can be handled outside the filelist 
+       if ( ( (filelist->type == FILE_LOADLIB) &&  BIF_filelist_islibrary(filelist, dir, group)) 
+               || (filelist->type == FILE_MAIN) ) {
+               filelist->filter = 0;
+       }
+       */
+
        if (!filelist->filter) {
                if (filelist->fidx) {
                        MEM_freeN(filelist->fidx);
@@ -438,23 +452,29 @@ void folderlist_free(ListBase* folderlist)
        folderlist= NULL;
 }
 
+static void filelist_read_main(struct FileList* filelist);
+static void filelist_read_library(struct FileList* filelist);
+static void filelist_read_dir(struct FileList* filelist);
+
 //------------------FILELIST------------------------//
-struct FileList*       filelist_new()
+struct FileList*       filelist_new(short type)
 {
        FileList* p = MEM_callocN( sizeof(FileList), "filelist" );
-       return p;
-}
-
-struct FileList*       filelist_copy(struct FileList* filelist)
-{
-       FileList* p = filelist_new();
-       BLI_strncpy(p->dir, filelist->dir, FILE_MAX);
-       p->filelist = NULL;
-       p->fidx = NULL;
+       switch(type) {
+               case FILE_MAIN:
+                       p->read = filelist_read_main;
+                       break;
+               case FILE_LOADLIB:
+                       p->read = filelist_read_library;
+                       break;
+               default:
+                       p->read = filelist_read_dir;
 
+       }
        return p;
 }
 
+
 void filelist_free(struct FileList* filelist)
 {
        int i;
@@ -493,6 +513,18 @@ void filelist_free(struct FileList* filelist)
        filelist->hide_dot =0;
 }
 
+void filelist_freelib(struct FileList* filelist)
+{
+       if(filelist->libfiledata)       
+               BLO_blendhandle_close(filelist->libfiledata);
+       filelist->libfiledata= 0;
+}
+
+struct BlendHandle *filelist_lib(struct FileList* filelist)
+{
+       return filelist->libfiledata;
+}
+
 int    filelist_numfiles(struct FileList* filelist)
 {
        return filelist->numfiltered;
@@ -733,16 +765,16 @@ void filelist_setfilter(struct FileList* filelist, unsigned int filter)
        filelist->filter = filter;
 }
 
-void filelist_readdir(struct FileList* filelist)
+static void filelist_read_dir(struct FileList* filelist)
 {
        char wdir[FILE_MAX];
-
        if (!filelist) return;
+
        filelist->fidx = 0;
        filelist->filelist = 0;
 
        BLI_getwdN(wdir);        
-       
+
        BLI_cleanup_dir(G.sce, filelist->dir);
        BLI_hide_dot_files(filelist->hide_dot);
        filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
@@ -750,12 +782,50 @@ void filelist_readdir(struct FileList* filelist)
        chdir(wdir);
        filelist_setfiletypes(filelist, G.have_quicktime);
        filelist_filter(filelist);
-       
+
        if (!filelist->threads.first) {
                BLI_init_threads(&filelist->threads, exec_loadimages, 2);
        }
 }
 
+static void filelist_read_main(struct FileList* filelist)
+{
+       if (!filelist) return;
+       filelist_from_main(filelist);
+}
+
+static void filelist_read_library(struct FileList* filelist)
+{
+       if (!filelist) return;
+       BLI_cleanup_dir(G.sce, filelist->dir);
+       filelist_from_library(filelist);
+       if(!filelist->libfiledata) {
+               int num;
+               struct direntry *file;
+               filelist_read_dir(filelist);
+               file = filelist->filelist;
+               for(num=0; num<filelist->numfiles; num++, file++) {
+                       if(BLO_has_bfile_extension(file->relname)) {
+                               char name[FILE_MAXDIR+FILE_MAXFILE];
+                       
+                               BLI_strncpy(name, filelist->dir, sizeof(name));
+                               strcat(name, file->relname);
+                               
+                               /* prevent current file being used as acceptable dir */
+                               if (BLI_streq(G.main->name, name)==0) {
+                                       file->type &= ~S_IFMT;
+                                       file->type |= S_IFDIR;
+                               }
+                       }
+               }
+       }
+}
+
+void filelist_readdir(struct FileList* filelist)
+{
+       filelist->read(filelist);
+}
+
 int filelist_empty(struct FileList* filelist)
 {      
        return filelist->filelist == 0;
@@ -937,3 +1007,272 @@ void filelist_sort(struct FileList* filelist, short sort)
 
        filelist_filter(filelist);
 }
+
+
+int filelist_islibrary(struct FileList* filelist, char* dir, char* group)
+{
+       return BLO_is_a_library(filelist->dir, dir, group);
+}
+
+static int groupname_to_code(char *group)
+{
+       char buf[32];
+       char *lslash;
+       
+       BLI_strncpy(buf, group, 31);
+       lslash= BLI_last_slash(buf);
+       if (lslash)
+               lslash[0]= '\0';
+
+       return BLO_idcode_from_name(buf);
+}
+
+void filelist_from_library(struct FileList* filelist)
+{
+       LinkNode *l, *names, *previews;
+       struct ImBuf* ima;
+       int ok, i, nnames, idcode;
+       char filename[FILE_MAXDIR+FILE_MAXFILE];
+       char dir[FILE_MAX], group[GROUP_MAX];   
+       
+       /* name test */
+       ok= filelist_islibrary(filelist, dir, group);
+       if (!ok) {
+               /* free */
+               if(filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata);
+               filelist->libfiledata= 0;
+               return;
+       }
+       
+       BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI
+
+       /* there we go */
+       /* for the time being only read filedata when libfiledata==0 */
+       if (filelist->libfiledata==0) {
+               filelist->libfiledata= BLO_blendhandle_from_file(dir);
+               if(filelist->libfiledata==0) return;
+       }
+       
+       idcode= groupname_to_code(group);
+
+               // memory for strings is passed into filelist[i].relname
+               // and free'd in freefilelist
+       previews = NULL;
+       if (idcode) {
+               previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode);
+               names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode);
+               /* ugh, no rewind, need to reopen */
+               BLO_blendhandle_close(filelist->libfiledata);
+               filelist->libfiledata= BLO_blendhandle_from_file(dir);
+               
+       } else {
+               names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata);
+       }
+       
+       nnames= BLI_linklist_length(names);
+
+       filelist->numfiles= nnames + 1;
+       filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist));
+       memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist));
+
+       filelist->filelist[0].relname= BLI_strdup("..");
+       filelist->filelist[0].type |= S_IFDIR;
+               
+       for (i=0, l= names; i<nnames; i++, l= l->next) {
+               char *blockname= l->link;
+
+               filelist->filelist[i + 1].relname= BLI_strdup(blockname);
+               if (!idcode)
+                       filelist->filelist[i + 1].type |= S_IFDIR;
+       }
+       
+       if(previews) {
+               for (i=0, l= previews; i<nnames; i++, l= l->next) {
+                       PreviewImage *img= l->link;
+                       
+                       if (img) {
+                               unsigned int w = img->w[PREVIEW_MIPMAP_LARGE];
+                               unsigned int h = img->h[PREVIEW_MIPMAP_LARGE];
+                               unsigned int *rect = img->rect[PREVIEW_MIPMAP_LARGE];
+
+                               /* first allocate imbuf for copying preview into it */
+                               if (w > 0 && h > 0 && rect) {
+                                       ima = IMB_allocImBuf(w, h, 32, IB_rect, 0);
+                                       memcpy(ima->rect, rect, w*h*sizeof(unsigned int));
+                                       filelist->filelist[i + 1].image = ima;
+                                       filelist->filelist[i + 1].flags = IMAGEFILE;
+                               }
+                       }
+               }
+       }
+
+       BLI_linklist_free(names, free);
+       if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN);
+
+       filelist_sort(filelist, FILE_SORT_ALPHA);
+
+       BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change
+
+       filelist->filter = 0;
+       filelist_filter(filelist);
+}
+
+void filelist_hideparent(struct FileList* filelist, short hide)
+{
+       filelist->hide_parent = hide;
+}
+
+void filelist_from_main(struct FileList *filelist)
+{
+       ID *id;
+       struct direntry *files, *firstlib = NULL;
+       ListBase *lb;
+       int a, fake, idcode, ok, totlib, totbl;
+       
+       // filelist->type = FILE_MAIN; // XXXXX TODO: add modes to filebrowser
+
+       if(filelist->dir[0]=='/') filelist->dir[0]= 0;
+       
+       if(filelist->dir[0]) {
+               idcode= groupname_to_code(filelist->dir);
+               if(idcode==0) filelist->dir[0]= 0;
+       }
+       
+       if( filelist->dir[0]==0) {
+               
+               /* make directories */
+               filelist->numfiles= 23;
+               filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
+               
+               for(a=0; a<filelist->numfiles; a++) {
+                       memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry));
+                       filelist->filelist[a].type |= S_IFDIR;
+               }
+               
+               filelist->filelist[0].relname= BLI_strdup("..");
+               filelist->filelist[2].relname= BLI_strdup("Scene");
+               filelist->filelist[3].relname= BLI_strdup("Object");
+               filelist->filelist[4].relname= BLI_strdup("Mesh");
+               filelist->filelist[5].relname= BLI_strdup("Curve");
+               filelist->filelist[6].relname= BLI_strdup("Metaball");
+               filelist->filelist[7].relname= BLI_strdup("Material");
+               filelist->filelist[8].relname= BLI_strdup("Texture");
+               filelist->filelist[9].relname= BLI_strdup("Image");
+               filelist->filelist[10].relname= BLI_strdup("Ika");
+               filelist->filelist[11].relname= BLI_strdup("Wave");
+               filelist->filelist[12].relname= BLI_strdup("Lattice");
+               filelist->filelist[13].relname= BLI_strdup("Lamp");
+               filelist->filelist[14].relname= BLI_strdup("Camera");
+               filelist->filelist[15].relname= BLI_strdup("Ipo");
+               filelist->filelist[16].relname= BLI_strdup("World");
+               filelist->filelist[17].relname= BLI_strdup("Screen");
+               filelist->filelist[18].relname= BLI_strdup("VFont");
+               filelist->filelist[19].relname= BLI_strdup("Text");
+               filelist->filelist[20].relname= BLI_strdup("Armature");
+               filelist->filelist[21].relname= BLI_strdup("Action");
+               filelist->filelist[22].relname= BLI_strdup("NodeTree");
+               filelist_sort(filelist, FILE_SORT_ALPHA);
+       }
+       else {
+
+               /* make files */
+               idcode= groupname_to_code(filelist->dir);
+               
+               lb= wich_libbase(G.main, idcode );
+               if(lb==0) return;
+               
+               id= lb->first;
+               filelist->numfiles= 0;
+               while(id) {
+                       /* XXXXX TODO: the selection of the ipo blocktype might go somewhere else? 
+                       if(filelist->has_func && idcode==ID_IP) {
+                               if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++;
+                       }
+                       else */
+                       if (!filelist->hide_dot || id->name[2] != '.') {
+                               filelist->numfiles++;
+                       }
+                       
+                       id= id->next;
+               }
+               
+               /* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */
+               if (!filelist->hide_parent) filelist->numfiles+= 1;
+               filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
+               
+               files = filelist->filelist;
+               
+               if (!filelist->hide_parent) {
+                       memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry));
+                       filelist->filelist[0].relname= BLI_strdup("..");
+                       filelist->filelist[0].type |= S_IFDIR;
+               
+                       files++;
+               }
+               
+               id= lb->first;
+               totlib= totbl= 0;
+               
+               while(id) {
+#if 0 
+                       // XXXXX TODO: this is deprecated, checks for correct IPO block? 
+                       ok= 0;
+                       if(filelist->has_func && idcode==ID_IP) {
+                               if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1;
+                       }
+                       else ok= 1;
+#endif                 
+                       ok = 1;
+                       if(ok) {
+                               if (!filelist->hide_dot || id->name[2] != '.') {
+                                       memset( files, 0 , sizeof(struct direntry));
+                                       if(id->lib==NULL)
+                                               files->relname= BLI_strdup(id->name+2);
+                                       else {
+                                               files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib");
+                                               sprintf(files->relname, "%s | %s", id->lib->name, id->name+2);
+                                       }
+                                       /* files->type |= S_IFDIR; */
+#if 0                          // XXXXX TODO show the selection status of the objects
+                                       if(!filelist->has_func) { /* F4 DATA BROWSE */
+                                               if(idcode==ID_OB) {
+                                                       if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE;
+                                               }
+                                               else if(idcode==ID_SCE) {
+                                                       if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE;
+                                               }                                       
+                                       }
+#endif
+                                       files->nr= totbl+1;
+                                       files->poin= id;
+                                       fake= id->flag & LIB_FAKEUSER;
+                                       if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
+                                               files->flags |= IMAGEFILE;
+                                       }
+                                       if(id->lib && fake) sprintf(files->extra, "LF %d", id->us);
+                                       else if(id->lib) sprintf(files->extra, "L    %d", id->us);
+                                       else if(fake) sprintf(files->extra, "F    %d", id->us);
+                                       else sprintf(files->extra, "      %d", id->us);
+                                       
+                                       if(id->lib) {
+                                               if(totlib==0) firstlib= files;
+                                               totlib++;
+                                       }
+                                       
+                                       files++;
+                               }
+                               totbl++;
+                       }
+                       
+                       id= id->next;
+               }
+               
+               /* only qsort of library blocks */
+               if(totlib>1) {
+                       qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
+               }
+       }
+       filelist->filter = 0;
+       filelist_filter(filelist);
+}
+
index dd3c2c766c181b4cbb424cb2716e180fb22af1c0..a8d909f899ec36e23b754d8faf5efc798c27e3e8 100644 (file)
@@ -42,12 +42,13 @@ struct FolderList;
 struct direntry;
 struct BlendHandle;
 struct Scene;
+struct Main;
 struct rcti;
+struct ReportList;
 
-struct FileList *      filelist_new();
+struct FileList *      filelist_new(short type);
 void                           filelist_init_icons();
 void                           filelist_free_icons();
-struct FileList *      filelist_copy(struct FileList* filelist);
 int                                    filelist_find(struct FileList* filelist, char *file);
 void                           filelist_free(struct FileList* filelist);
 void                           filelist_sort(struct FileList* filelist, short sort);
@@ -71,6 +72,13 @@ int                                  filelist_empty(struct FileList* filelist);
 void                           filelist_parent(struct FileList* filelist);
 void                           filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
 
+
+int                                    filelist_islibrary (struct FileList* filelist, char* dir, char* group);
+void                           filelist_from_main(struct FileList* filelist);
+void                           filelist_from_library(struct FileList* filelist);
+void                           filelist_freelib(struct FileList* filelist);
+void                           filelist_hideparent(struct FileList* filelist, short hide);
+
 struct ListBase *      folderlist_new();
 void                           folderlist_free(struct ListBase* folderlist);
 void                           folderlist_popdir(struct ListBase* folderlist, char *dir);
index f300505933f27141e0f3e1f75aae24a9a3143f23..b0bd3a9a5e7b78a8718f4b007fb9c7f250b269fb 100644 (file)
@@ -123,6 +123,22 @@ short ED_fileselect_set_params(SpaceFile *sfile)
        /* set the parameters from the operator, if it exists */
        if (op) {
                BLI_strncpy(params->title, op->type->name, sizeof(params->title));
+
+               params->type = RNA_int_get(op->ptr, "type");
+
+               if (RNA_property_is_set(op->ptr, "path")) {
+                       RNA_string_get(op->ptr, "path", name);
+                       if (params->type == FILE_LOADLIB) {
+                               BLI_strncpy(params->dir, name, sizeof(params->dir));
+                               BLI_cleanup_dir(G.sce, params->dir);    
+                       } else { 
+                               /* if operator has path set, use it, otherwise keep the last */
+                               BLI_convertstringcode(name, G.sce);
+                               BLI_split_dirfile(name, dir, file);
+                               BLI_strncpy(params->file, file, sizeof(params->file));
+                               BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */
+                       }
+               }
                params->filter = 0;
                params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0;
                params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0;
@@ -136,21 +152,18 @@ short ED_fileselect_set_params(SpaceFile *sfile)
                if (params->filter != 0)
                        params->flag |= FILE_FILTER;
 
-               params->flag |= FILE_HIDE_DOT;
-               
+               if (params->type == FILE_LOADLIB) {
+                       params->flag |= FILE_HIDE_DOT;
+                       params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0;
+                       params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0;
+                       params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0;
+               }
+
                if(params->filter & (IMAGEFILE|MOVIEFILE))
                        params->display= FILE_IMGDISPLAY;
                else
                        params->display= FILE_SHORTDISPLAY;
                
-               /* if operator has path set, use it, otherwise keep the last */
-               if (RNA_property_is_set(op->ptr, "filename")) {
-                       RNA_string_get(op->ptr, "filename", name);
-                       BLI_convertstringcode(name, G.sce);
-                       BLI_split_dirfile(name, dir, file);
-                       BLI_strncpy(params->file, file, sizeof(params->file));
-                       BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */                
-               }
        } else {
                /* default values, if no operator */
                params->flag |= FILE_HIDE_DOT;
@@ -357,19 +370,15 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar
 void file_change_dir(struct SpaceFile *sfile)
 {
        if (sfile->params) { 
-               if (BLI_exists(sfile->params->dir)) {
-                       filelist_setdir(sfile->files, sfile->params->dir);
+               filelist_setdir(sfile->files, sfile->params->dir);
 
-                       if(folderlist_clear_next(sfile))
-                               folderlist_free(sfile->folders_next);
+               if(folderlist_clear_next(sfile))
+                       folderlist_free(sfile->folders_next);
 
-                       folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+               folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
 
-                       filelist_free(sfile->files);
-                       sfile->params->active_file = -1;
-               } else {
-                       BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX);
-               }
+               filelist_free(sfile->files);
+               sfile->params->active_file = -1;
        }
 }
 
index 722fa47572712cd1d072fa6582a4262b426bba6d..f71defe3949e4845b98d25058b8adfd64426cc0f 100644 (file)
@@ -119,6 +119,7 @@ static void file_free(SpaceLink *sl)
        SpaceFile *sfile= (SpaceFile *) sl;
        
        if(sfile->files) {
+               filelist_freelib(sfile->files);
                filelist_free(sfile->files);
                MEM_freeN(sfile->files);
                sfile->files= NULL;
@@ -165,7 +166,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
        /* clear or remove stuff from old */
        sfilen->op = NULL; /* file window doesn't own operators */
 
-       sfilen->files = filelist_new();
+       sfilen->files = filelist_new(sfileo->params->type);
        if(sfileo->folders_prev)
                sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev);
 
@@ -190,7 +191,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
        if (!sfile->folders_prev)
                sfile->folders_prev = folderlist_new();
        if (!sfile->files) {
-               sfile->files = filelist_new();
+               sfile->files = filelist_new(params->type);
                file_change_dir(sfile);
                params->active_file = -1; // added this so it opens nicer (ton)
        }
index bee06e6892f1432cba182ab3610cdb51b122912e..806d0d7ce52781fb2328855171972f5903251b1b 100644 (file)
@@ -609,7 +609,7 @@ static const EnumPropertyItem image_file_type_items[] = {
 
 static void image_filesel(bContext *C, wmOperator *op, const char *path)
 {
-       RNA_string_set(op->ptr, "filename", path);
+       RNA_string_set(op->ptr, "path", path);
        WM_event_add_fileselect(C, op); 
 }
 
@@ -623,7 +623,7 @@ static int open_exec(bContext *C, wmOperator *op)
        Image *ima= NULL;
        char str[FILE_MAX];
 
-       RNA_string_get(op->ptr, "filename", str);
+       RNA_string_get(op->ptr, "path", str);
        ima= BKE_add_image_file(str, scene->r.cfra);
 
        if(!ima)
@@ -640,7 +640,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
        SpaceImage *sima= CTX_wm_space_image(C);
        char *path= (sima->image)? sima->image->name: U.textudir;
 
-       if(RNA_property_is_set(op->ptr, "filename"))
+       if(RNA_property_is_set(op->ptr, "path"))
                return open_exec(C, op);
        
        image_filesel(C, op, path);
@@ -663,7 +663,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
 }
 
 /******************** replace image operator ********************/
@@ -676,7 +676,7 @@ static int replace_exec(bContext *C, wmOperator *op)
        if(!sima->image)
                return OPERATOR_CANCELLED;
        
-       RNA_string_get(op->ptr, "filename", str);
+       RNA_string_get(op->ptr, "path", str);
        BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
 
        BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
@@ -693,7 +693,7 @@ static int replace_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(!sima->image)
                return OPERATOR_CANCELLED;
 
-       if(RNA_property_is_set(op->ptr, "filename"))
+       if(RNA_property_is_set(op->ptr, "path"))
                return replace_exec(C, op);
 
        image_filesel(C, op, path);
@@ -716,7 +716,7 @@ void IMAGE_OT_replace(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
 }
 
 /******************** save image as operator ********************/
@@ -801,7 +801,7 @@ static int save_as_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
 
        sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
-       RNA_string_get(op->ptr, "filename", str);
+       RNA_string_get(op->ptr, "path", str);
 
        save_image_doit(C, sima, scene, op, str);
 
@@ -815,7 +815,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
        ImBuf *ibuf= ED_space_image_buffer(sima);
        Scene *scene= CTX_data_scene(C);
 
-       if(RNA_property_is_set(op->ptr, "filename"))
+       if(RNA_property_is_set(op->ptr, "path"))
                return save_as_exec(C, op);
        
        if(!ima)
@@ -861,7 +861,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
        /* properties */
        RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL);
 }
 
 /******************** save image operator ********************/
index 640c968742cd45fafe54a53dd2e49916c1fcea4a..f4d8682b8ea64dcfa156c56228bd38c29b177907 100644 (file)
@@ -300,11 +300,11 @@ void FILE_OT_report_missing_files(wmOperatorType *ot)
 
 static int find_missing_files_exec(bContext *C, wmOperator *op)
 {
-       char *filename;
+       char *path;
        
-       filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0);
-       findMissingFiles(filename);
-       MEM_freeN(filename);
+       path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
+       findMissingFiles(path);
+       MEM_freeN(path);
 
        return OPERATOR_FINISHED;
 }
@@ -330,7 +330,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, 0);
+       WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
 }
 
 #if 0
index 88b8dccc6c9f096e36efbf97ee82f2916a3a2ab2..c17793b28f8ada3a825c924c6aad27d7ae22f2e9 100644 (file)
@@ -64,10 +64,10 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
        ARegion *ar= CTX_wm_region(C);
        
 
-       char filename[512];
-       RNA_string_get(op->ptr, "filename", filename);
+       char path[512];
+       RNA_string_get(op->ptr, "path", path);
 #ifndef DISABLE_PYTHON
-       if(BPY_run_python_script(C, filename, NULL, op->reports)) {
+       if(BPY_run_python_script(C, path, NULL, op->reports)) {
                ED_region_tag_redraw(ar);
                return OPERATOR_FINISHED;
        }
@@ -85,7 +85,7 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot)
        ot->exec= run_pyfile_exec;
        ot->poll= ED_operator_areaactive;
 
-       RNA_def_string_file_path(ot->srna, "filename", "", 512, "Filename", "");
+       RNA_def_string_file_path(ot->srna, "path", "", 512, "Path", "");
 }
 
 static int run_ui_scripts_exec(bContext *C, wmOperator *op)
index aa35ba54b7f047e8ec888752216a769230cd870a..270cc1ffd8fa0bcce85c2a1049446cd033c03879 100644 (file)
@@ -68,7 +68,7 @@ void script_keymap(wmWindowManager *wm)
        ListBase *keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0);
 
        /* TODO - this is just while we have no way to load a text datablock */
-       RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "filename", "test.py");
+       RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "path", "test.py");
        WM_keymap_add_item(keymap, "SCRIPT_OT_python_run_ui_scripts", PKEY, KM_PRESS, KM_SHIFT, 0);
 }
 
index 8a1b3bf3465ad7c465b90fdeb8fb4d6b446a1f74..bd5259ddb524b697d6c079bef8fd3303743b6b85 100644 (file)
@@ -289,7 +289,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
        Editing *ed= seq_give_editing(scene, TRUE);
 
        struct anim *an;
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
 
        Sequence *seq, *soundseq=NULL;  /* generic strip vars */
        Strip *strip;
@@ -301,12 +301,12 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
        channel= RNA_int_get(op->ptr, "channel");
        sound = RNA_boolean_get(op->ptr, "sound");
 
-       RNA_string_get(op->ptr, "filename", filename);
+       RNA_string_get(op->ptr, "path", path);
        
-       an = openanim(filename, IB_rect);
+       an = openanim(path, IB_rect);
 
        if (an==NULL) {
-               BKE_reportf(op->reports, RPT_ERROR, "Filename \"%s\" could not be loaded as a movie", filename);
+               BKE_reportf(op->reports, RPT_ERROR, "File \"%s\" could not be loaded as a movie", path);
                return OPERATOR_CANCELLED;
        }
        
@@ -323,7 +323,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
        
        strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
        
-       BLI_split_dirfile_basic(filename, strip->dir, se->name);
+       BLI_split_dirfile_basic(path, strip->dir, se->name);
 
        RNA_string_get(op->ptr, "name", seq->name);
        
@@ -332,7 +332,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
 
        if(sound)
        {
-               soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, filename);
+               soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, path);
                if(soundseq != NULL)
                        RNA_string_get(op->ptr, "name", soundseq->name);
        }
@@ -376,7 +376,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL);
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
 }
@@ -384,7 +384,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
 /* add sound operator */
 static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
 {
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
        Scene *scene= CTX_data_scene(C);
        Sequence *seq;  /* generic strip vars */
        int start_frame, channel; /* operator props */
@@ -392,9 +392,9 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
        start_frame= RNA_int_get(op->ptr, "start_frame");
        channel= RNA_int_get(op->ptr, "channel");
        
-       RNA_string_get(op->ptr, "filename", filename);
+       RNA_string_get(op->ptr, "path", path);
 
-       seq = sequencer_add_sound_strip(C, op, start_frame, channel, filename);
+       seq = sequencer_add_sound_strip(C, op, start_frame, channel, path);
 
        if(seq == NULL)
                return OPERATOR_CANCELLED;
@@ -442,7 +442,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL);
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
 }
@@ -455,7 +455,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
 
        int tot_images;
 
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
 
        Sequence *seq;  /* generic strip vars */
        Strip *strip;
@@ -466,14 +466,14 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
        start_frame= RNA_int_get(op->ptr, "start_frame");
        channel= RNA_int_get(op->ptr, "channel");
        
-       RNA_string_get(op->ptr, "filename", filename);
+       RNA_string_get(op->ptr, "path", path);
 
        seq = alloc_sequence(ed->seqbasep, start_frame, channel);       
        seq->type= SEQ_IMAGE;
        
        /* basic defaults */
        seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
-       BLI_split_dirfile_basic(filename, strip->dir, NULL);
+       BLI_split_dirfile_basic(path, strip->dir, NULL);
        
        tot_images= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
        
@@ -490,7 +490,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
                RNA_END;
        }
        else {
-               BLI_split_dirfile_basic(filename, NULL, se->name);
+               BLI_split_dirfile_basic(path, NULL, se->name);
        }
 
        RNA_string_get(op->ptr, "name", seq->name);
@@ -538,7 +538,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL);
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        
        RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
@@ -606,15 +606,15 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
                strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
 
        if (seq->type==SEQ_PLUGIN) {
-               char filename[FILE_MAX];
-               RNA_string_get(op->ptr, "filename", filename);
+               char path[FILE_MAX];
+               RNA_string_get(op->ptr, "path", path);
 
-               sh.init_plugin(seq, filename);
+               sh.init_plugin(seq, path);
 
                if(seq->plugin==NULL) {
                        BLI_remlink(ed->seqbasep, seq);
                        seq_free_sequence(scene, seq);
-                       BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", filename);
+                       BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", path);
                        return OPERATOR_CANCELLED;
                }
        }
@@ -673,7 +673,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, 0);
+       WM_operator_properties_filesel(ot, 0, FILE_SPECIAL);
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME);
        RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type");
        RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f);
index 3411d9114df4f4d6ba869c541036d2353ccd1629..3568f50dfe10d34ccd8679e42b7d13255bf2200b 100644 (file)
@@ -192,7 +192,7 @@ static int open_exec(bContext *C, wmOperator *op)
        Text *text;
        char str[FILE_MAX];
 
-       RNA_string_get(op->ptr, "filename", str);
+       RNA_string_get(op->ptr, "path", str);
 
        text= add_text(str, G.sce);
 
@@ -211,10 +211,10 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
        Text *text= CTX_data_edit_text(C);
        char *path= (text && text->name)? text->name: G.sce;
 
-       if(RNA_property_is_set(op->ptr, "filename"))
+       if(RNA_property_is_set(op->ptr, "path"))
                return open_exec(C, op);
        
-       RNA_string_set(op->ptr, "filename", path);
+       RNA_string_set(op->ptr, "path", path);
        WM_event_add_fileselect(C, op); 
 
        return OPERATOR_RUNNING_MODAL;
@@ -233,7 +233,7 @@ void TEXT_OT_open(wmOperatorType *ot)
        ot->poll= text_new_poll;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL);
 }
 
 /******************* reload operator *********************/
@@ -420,7 +420,7 @@ static int save_as_exec(bContext *C, wmOperator *op)
        if(!text)
                return OPERATOR_CANCELLED;
 
-       RNA_string_get(op->ptr, "filename", str);
+       RNA_string_get(op->ptr, "path", str);
 
        if(text->name) MEM_freeN(text->name);
        text->name= BLI_strdup(str);
@@ -438,7 +438,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
        Text *text= CTX_data_edit_text(C);
        char *str;
 
-       if(RNA_property_is_set(op->ptr, "filename"))
+       if(RNA_property_is_set(op->ptr, "path"))
                return save_as_exec(C, op);
 
        if(text->name)
@@ -448,7 +448,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
        else
                str= G.sce;
        
-       RNA_string_set(op->ptr, "filename", str);
+       RNA_string_set(op->ptr, "path", str);
        WM_event_add_fileselect(C, op); 
 
        return OPERATOR_RUNNING_MODAL;
@@ -467,7 +467,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
        ot->poll= text_edit_poll;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL);
 }
 
 /******************* run script operator *********************/
index 6fdc3a7787b89c666325e4af1b33696d353ccddd..5c1b363aa394e8e05bed09f9773f6543a34d0c29 100644 (file)
@@ -154,24 +154,23 @@ typedef struct FileSelectParams {
        char dir[240]; /* directory */
        char file[80]; /* file */
 
-       short flag; /* settings for filter, hiding files and display mode */
+       short type; /* XXXXX for now store type here, should be moved to the operator */
+       short flag; /* settings for filter, hiding dots files,...  */
        short sort; /* sort order */
        short display; /* display mode flag */
        short filter; /* filter when (flags & FILE_FILTER) is true */
 
        /* XXX - temporary, better move to filelist */
        short active_bookmark;
-       short pad;
        int     active_file;
        int selstate;
 
+       /* short 
        /* XXX --- still unused -- */
        short f_fp; /* show font preview */
        short menu; /* currently selected option in pupmenu */
        char fp_str[8]; /* string to use for font preview */
-       
        char *pupmenu; /* allows menu for save options - result stored in menup */
-       
        /* XXX --- end unused -- */
 } FileSelectParams;
 
index 42c5343dbff63d8d1fc203a7480565d891564fe0..595562503aa4c92bcb930ecf058974f3d716a42b 100644 (file)
@@ -83,6 +83,7 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont, const char *identifier
 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
+PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 
 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc);
index c6fed5cd8e651f0561b5e95087f737a9caa889f7..e7fe86afd0328d11258537cf0207456b1f26a8ea 100644 (file)
@@ -89,6 +89,7 @@ typedef enum PropertySubType {
        /* strings */
        PROP_FILEPATH = 1,
        PROP_DIRPATH = 2,
+       PROP_FILENAME = 3,
 
        /* numbers */
        PROP_UNSIGNED = 13,
index 8d05cbde74c23eca83a5867fc5434d1d1b1fc9da..6bca237e02fb7b5409d5f2f4718c8813b153a9d1 100644 (file)
@@ -2113,6 +2113,20 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide
        return prop;
 }
 
+PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
+       const char *ui_name, const char *ui_description)
+{
+       ContainerRNA *cont= cont_;
+       PropertyRNA *prop;
+       
+       prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
+       if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
+       if(default_value) RNA_def_property_string_default(prop, default_value);
+       RNA_def_property_ui_text(prop, ui_name, ui_description);
+
+       return prop;
+}
+
 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
        const char *ui_name, const char *ui_description)
 {
index 544804b26d6a3c74ede68fec39e504b0f2819e2b..6610c5d8931a37870b718c2b2a23034b166a1b8d 100644 (file)
@@ -139,7 +139,7 @@ void                WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, i
 int                    WM_menu_invoke                  (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
                        /* invoke callback, confirm menu + exec */
 int                    WM_operator_confirm             (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-               /* invoke callback, file selector "filename" unset + exec */
+               /* invoke callback, file selector "path" unset + exec */
 int                    WM_operator_filesel             (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
                        /* poll callback, context checks */
 int                    WM_operator_winactive   (struct bContext *C);
@@ -169,7 +169,7 @@ int                 WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int con
 
 void           WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring);
 void           WM_operator_properties_free(struct PointerRNA *ptr);
-void           WM_operator_properties_filesel(struct wmOperatorType *ot, int filter);
+void           WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type);
 
                /* operator as a python command (resultuing string must be free'd) */
 char           *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args);
index 3c03d24ca938ab1d6ec084a37d25e18c147871c5..79441f3361061b5953b92899b7deaf0227bdcae9 100644 (file)
@@ -895,9 +895,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
        switch(event->val) {
                case EVT_FILESELECT_OPEN: 
                case EVT_FILESELECT_FULL_OPEN: 
-                       {
-                               char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0);
-                                       
+                       {       
                                if(event->val==EVT_FILESELECT_OPEN)
                                        ED_area_newspace(C, handler->op_area, SPACE_FILE);
                                else
@@ -908,8 +906,6 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                                sfile->op= handler->op;
 
                                ED_fileselect_set_params(sfile);
-                               dir = NULL;
-                               MEM_freeN(path);
                                
                                action= WM_HANDLER_BREAK;
                        }
@@ -920,7 +916,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                        {
                                /* XXX validate area and region? */
                                bScreen *screen= CTX_wm_screen(C);
-                               char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0);
+                               char *path= RNA_string_get_alloc(handler->op->ptr, "path", NULL, 0);
                                
                                if(screen != handler->filescreen)
                                        ED_screen_full_prevspace(C);
@@ -1250,7 +1246,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
        }
 }
 
-/* operator is supposed to have a filled "filename" property */
+/* operator is supposed to have a filled "path" property */
 /* optional property: filetype (XXX enum?) */
 
 /* Idea is to keep a handler alive on window queue, owning the operator.
index 37cd424ac18c6c42a3cbf66f4d3bc93ae27c4506..66724b57ff806169ff02d917edbe240254ff8ae6 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h" /*for WM_operator_pystring */
 
+#include "BLO_readfile.h"
+
 #include "BKE_blender.h"
 #include "BKE_context.h"
+#include "BKE_depsgraph.h"
 #include "BKE_idprop.h"
 #include "BKE_library.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
+#include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_utildefines.h"
 
@@ -496,10 +500,10 @@ int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_CANCELLED;
 }
 
-/* op->invoke, opens fileselect if filename property not set, otherwise executes */
+/* op->invoke, opens fileselect if path property not set, otherwise executes */
 int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event)
 {
-       if (RNA_property_is_set(op->ptr, "filename")) {
+       if (RNA_property_is_set(op->ptr, "path")) {
                return WM_operator_call(C, op);
        } 
        else {
@@ -509,9 +513,11 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event)
 }
 
 /* default properties for fileselect */
-void WM_operator_properties_filesel(wmOperatorType *ot, int filter)
+void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type)
 {
-       RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "Path to file.");
+       RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "FilePath", "Path to file.");
+       RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "FileName", "Name of the file.");
+       RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file.");
 
        RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", "");
        RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", "");
@@ -521,6 +527,10 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter)
        RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", "");
        RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", "");
        RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", "");
+
+       RNA_def_int(ot->srna, "type", type, FILE_LOADLIB, FILE_SPECIAL, 
+               "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.",
+               FILE_LOADLIB, FILE_SPECIAL);
 }
 
 /* op->poll */
@@ -891,7 +901,7 @@ static void load_set_load_ui(wmOperator *op)
 
 static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       RNA_string_set(op->ptr, "filename", G.sce);
+       RNA_string_set(op->ptr, "path", G.sce);
        load_set_load_ui(op);
 
        WM_event_add_fileselect(C, op);
@@ -901,9 +911,9 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
 static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
 {
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
 
-       RNA_string_get(op->ptr, "filename", filename);
+       RNA_string_get(op->ptr, "path", path);
        load_set_load_ui(op);
 
        if(RNA_boolean_get(op->ptr, "load_ui"))
@@ -915,7 +925,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
        // do it before for now, but is this correct with multiple windows?
        WM_event_add_notifier(C, NC_WINDOW, NULL);
 
-       WM_read_file(C, filename, op->reports);
+       WM_read_file(C, path, op->reports);
        
        return 0;
 }
@@ -930,11 +940,168 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
        ot->exec= wm_open_mainfile_exec;
        ot->poll= WM_operator_winactive;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
 
        RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file.");
 }
 
+static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       if (RNA_property_is_set(op->ptr, "path")) {
+               return WM_operator_call(C, op);
+       } 
+       else {
+               /* XXX solve where to get last linked library from */
+               RNA_string_set(op->ptr, "path", G.lib);
+               WM_event_add_fileselect(C, op);
+               return OPERATOR_RUNNING_MODAL;
+       }
+}
+
+static short wm_link_append_flag(wmOperator *op)
+{
+       short flag = 0;
+       if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT;
+       if (RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY;
+       if (RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE;
+       if (RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK;
+       return flag;
+}
+
+#define GROUP_MAX 32
+
+
+static void make_library_local(const char *libname, Main *main)
+{
+       struct Library *lib;
+
+       /* and now find the latest append lib file */
+       lib= main->library.first;
+       while(lib) {
+               if (BLI_streq(libname, lib->filename)) break;
+               lib= lib->id.next;
+       }
+       
+       /* make local */
+       if(lib) {
+               all_local(lib, 1);
+               /* important we unset, otherwise these object wont
+                * link into other scenes from this blend file */
+               flag_all_listbases_ids(LIB_APPEND_TAG, 0);
+       }
+}
+
+static int wm_link_append_exec(bContext *C, wmOperator *op)
+{
+       char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX];
+       int idcode;
+       BlendHandle *bh;
+       struct Main *main= CTX_data_main(C);
+       struct Scene *scene= CTX_data_scene(C);
+       struct Main *mainl= 0;
+       
+       struct ScrArea *sa= CTX_wm_area(C);
+       PropertyRNA *prop;
+       int totfiles=0;
+       short flag;
+
+       name[0] = '\0';
+       RNA_string_get(op->ptr, "filename", name);
+       RNA_string_get(op->ptr, "directory", dir);
+
+       if ( BLO_is_a_library(dir, libname, group)==0 ) {
+               BKE_report(op->reports, RPT_ERROR, "Not a library");
+               return OPERATOR_FINISHED;
+       } else if (group[0]==0) {
+               BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+               return OPERATOR_FINISHED;
+       } else if (BLI_streq(main->name, libname)) {
+               BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
+               return OPERATOR_FINISHED;
+       }
+
+       /* check if something is indicated for append/link */
+       prop = RNA_struct_find_property(op->ptr, "files");
+       if (prop) {
+               totfiles= RNA_property_collection_length(op->ptr, prop);
+               if (totfiles == 0) {
+                       if (name[0] == '\0') {
+                               BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+                               return OPERATOR_FINISHED;
+                       }
+               }
+       } else if (name[0] == '\0') {
+               BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+               return OPERATOR_FINISHED;
+       }
+
+       /* now we have or selected, or an indicated file */
+       if (RNA_boolean_get(op->ptr, "autoselect"))
+               scene_deselect_all(scene);
+
+       bh = BLO_blendhandle_from_file(libname);
+       idcode = BLO_idcode_from_name(group);
+       
+       flag = wm_link_append_flag(op);
+
+       if((flag & FILE_LINK)==0) {
+               /* tag everything, all untagged data can be made local */
+               flag_all_listbases_ids(LIB_APPEND_TAG, 1);
+       }
+
+       /* here appending/linking starts */
+       mainl = BLO_library_append_begin(C, &bh, libname);
+       if (totfiles == 0) {
+               BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+       } else {
+               RNA_BEGIN(op->ptr, itemptr, "files") {
+                       RNA_string_get(&itemptr, "name", name);
+                       BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+               }
+               RNA_END;
+       }
+       BLO_library_append_end(C, mainl, &bh, idcode, flag);
+       
+       /* DISPLISTS? */
+       recalc_all_library_objects(main);
+
+       /* Append, rather than linking */
+       if ((flag & FILE_LINK)==0) {
+               make_library_local(main, libname);
+       }
+
+       /* do we need to do this? */
+       if(scene)
+               DAG_scene_sort(scene);
+
+       BLO_blendhandle_close(bh);
+       BLI_strncpy(G.lib, dir, FILE_MAX);
+
+       WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+static void WM_OT_link_append(wmOperatorType *ot)
+{
+       ot->name= "Link/Append from Library";
+       ot->idname= "WM_OT_link_append";
+       ot->description= "Link or Append from a Library .blend file";
+       
+       ot->invoke= wm_link_append_invoke;
+       ot->exec= wm_link_append_exec;
+       ot->poll= WM_operator_winactive;
+       
+       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB);
+       
+       RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending.");
+       RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects.");
+       RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer.");
+       RNA_def_boolean(ot->srna, "relative_paths", 1, "Relative Paths", "Store the library path as a relative path to current .blend file.");
+
+       RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
+}      
+
 static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
 {
        char scestr[FILE_MAX], filename[FILE_MAX];
@@ -987,7 +1154,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
        
        BLI_strncpy(name, G.sce, FILE_MAX);
        untitled(name);
-       RNA_string_set(op->ptr, "filename", name);
+       RNA_string_set(op->ptr, "path", name);
        
        WM_event_add_fileselect(C, op);
 
@@ -997,20 +1164,20 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
 /* function used for WM_OT_save_mainfile too */
 static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
 {
-       char filename[FILE_MAX];
+       char path[FILE_MAX];
        int compress;
 
        save_set_compress(op);
        compress= RNA_boolean_get(op->ptr, "compress");
        
-       if(RNA_property_is_set(op->ptr, "filename"))
-               RNA_string_get(op->ptr, "filename", filename);
+       if(RNA_property_is_set(op->ptr, "path"))
+               RNA_string_get(op->ptr, "path", path);
        else {
-               BLI_strncpy(filename, G.sce, FILE_MAX);
-               untitled(filename);
+               BLI_strncpy(path, G.sce, FILE_MAX);
+               untitled(path);
        }
 
-       WM_write_file(C, filename, compress, op->reports);
+       WM_write_file(C, path, compress, op->reports);
        
        WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL);
 
@@ -1027,7 +1194,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
        ot->exec= wm_save_as_mainfile_exec;
        ot->poll= WM_operator_winactive;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
        RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
 }
 
@@ -1041,7 +1208,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
        
        BLI_strncpy(name, G.sce, FILE_MAX);
        untitled(name);
-       RNA_string_set(op->ptr, "filename", name);
+       RNA_string_set(op->ptr, "path", name);
        uiPupMenuSaveOver(C, op, name);
 
        return OPERATOR_RUNNING_MODAL;
@@ -1057,7 +1224,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
        ot->exec= wm_save_as_mainfile_exec;
        ot->poll= WM_operator_winactive;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE);
+       WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
        RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
 }
 
@@ -1913,6 +2080,7 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_exit_blender);
        WM_operatortype_append(WM_OT_open_recentfile);
        WM_operatortype_append(WM_OT_open_mainfile);
+       WM_operatortype_append(WM_OT_link_append);
        WM_operatortype_append(WM_OT_recover_last_session);
        WM_operatortype_append(WM_OT_jobs_timer);
        WM_operatortype_append(WM_OT_save_as_mainfile);
@@ -1944,6 +2112,7 @@ void wm_window_keymap(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); 
        WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
        WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
        WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);