2.5 filebrowser
authorAndrea Weikert <elubie@gmx.net>
Sun, 26 Jul 2009 12:40:44 +0000 (12:40 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sun, 26 Jul 2009 12:40:44 +0000 (12:40 +0000)
Bugfixes:
* crash when loading file that has filebrowser open
* file size over 2GB/4GB? shows negative number
Other:
* tried to improve drawing speed a bit by only drawing the files actually shown and improving refresh behaviour a bit.

Note: Solution I found so far is to use the non-standard _stat64, as far as I could see, WIN64 should work without that patch (Genscher, please check and if needed you can enable this too by removing the !defined(WIN64) )
This probably needs to be fixed in at least one other place (BLI_filesize), will look into this once this fix proves stable enough)

source/blender/blenlib/BLI_storage_types.h
source/blender/blenlib/intern/storage.c
source/blender/editors/include/ED_fileselect.h
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/space_file.c
source/blender/windowmanager/WM_types.h

index 385aa39e6cbfce383e3329fd9858b39d62442194..9430ac8c5ff8d2e03bbd1b5a7c544199a0f5205e 100644 (file)
@@ -55,7 +55,11 @@ struct direntry{
        char    *string;
        mode_t  type;
        char    *relname;
+#if defined(WIN32) && !defined(WIN64) && (_MSC_VER>=1500)
+       struct _stat64 s;
+#else
        struct  stat s;
+#endif
        unsigned int    flags;
        char    size[16];
        char    mode1[4];
index 7af383e235610768e2d4f621c7e2fb40ac4bdb3e..997d9b9c3f156b2986c420cc7b7b8db172c8aa46 100644 (file)
@@ -265,7 +265,13 @@ void BLI_builddir(char *dirname, char *relname)
                                while(dlink){
                                        memset(&files[actnum], 0 , sizeof(struct direntry));
                                        files[actnum].relname = dlink->name;
+// use 64 bit file size, only needed for WIN32, WIN64 should work fine with stat. 
+// Excluding other than current MSVC compiler until able to test.
+#if defined(WIN32) && !defined(WIN64) && (_MSC_VER>=1500)
+                                       _stat64(dlink->name,&files[actnum].s);
+#else
                                        stat(dlink->name,&files[actnum].s);
+#endif
                                        files[actnum].type=files[actnum].s.st_mode;
                                        files[actnum].flags = 0;
                                        totnum++;
@@ -361,7 +367,7 @@ void BLI_adddirstrings()
                 * will buy us some time until files get bigger than 4GB or until
                 * everyone starts using __USE_FILE_OFFSET64 or equivalent.
                 */
-               st_size= (off_t)files[num].s.st_size;
+               st_size= files[num].s.st_size;
 
                if (st_size > 1024*1024*1024) {
                        sprintf(files[num].size, "%.2f GB", ((double)st_size)/(1024*1024*1024));        
index 1b8524eea3362379442c190cf7924ab65fd7018d..5cd789d4875610ad44a9e375c188951aa421e67e 100644 (file)
@@ -64,6 +64,7 @@ typedef struct FileLayout
        short width;
        short height;
        short flag;
+       short dirty;
        float column_widths[MAX_FILE_COLUMN];
 } FileLayout;
 
@@ -80,6 +81,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar);
 
 FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar);
 
+int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar);
 int ED_fileselect_layout_offset(FileLayout* layout, int x, int y);
 
 void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y);
index 339ebe27fcd58490b8496db50b5e7bface2f21d9..780b99c3cae0453d7ee4160100b23ca5f1ef49fa 100644 (file)
@@ -505,6 +505,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
        struct FileList* files = sfile->files;
        struct direntry *file;
        int numfiles;
+       int numfiles_layout;
        int colorid = 0;
        short sx, sy;
        int offset;
@@ -543,8 +544,10 @@ void file_draw_list(const bContext *C, ARegion *ar)
 
        sx = ar->v2d.cur.xmin + layout->tile_border_x;
        sy = ar->v2d.cur.ymax - layout->tile_border_y;
+       
+       numfiles_layout = ED_fileselect_layout_numfiles(layout, ar);
 
-       for (i=offset; (i < numfiles); ++i)
+       for (i=offset; (i < numfiles) && (i<offset+numfiles_layout); ++i)
        {
                ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
                sx += v2d->tot.xmin+2;
index 72f97898891e61ec085138205358518680b022d5..bd271c6fb4bec9c72f4562f32afe9ffe16a34ffa 100644 (file)
@@ -141,6 +141,21 @@ void ED_fileselect_reset_params(SpaceFile *sfile)
        sfile->params->title[0] = '\0';
 }
 
+int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar)
+{
+       int numfiles;
+       short width, height;
+
+       if (layout->flag & FILE_LAYOUT_HOR) {
+               short width = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x;
+               numfiles = width/layout->tile_w + 1;
+       } else {
+               short height = ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y;
+               numfiles = height/layout->tile_h + 1;
+       }
+
+       return layout->columns*layout->rows;
+}
 
 int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
 {
@@ -227,68 +242,78 @@ static void column_widths(struct FileList* files, struct FileLayout* layout)
 
 void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar)
 {
-       FileSelectParams* params = ED_fileselect_get_params(sfile);
+       FileSelectParams *params = ED_fileselect_get_params(sfile);
+       FileLayout *layout=0;
        View2D *v2d= &ar->v2d;
        int maxlen = 0;
-       int numfiles = filelist_numfiles(sfile->files);
-       int textheight = file_font_pointsize();
+       int numfiles;
+       int textheight;
        if (sfile->layout == 0) {
                sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout");
-       }
+               sfile->layout->dirty = 1;
+       } 
+
+       if (!sfile->layout->dirty) return;
+
+       numfiles = filelist_numfiles(sfile->files);
+       textheight = file_font_pointsize();
+       layout = sfile->layout;
+
        if (params->display == FILE_IMGDISPLAY) {
-               sfile->layout->prv_w = 96;
-               sfile->layout->prv_h = 96;
-               sfile->layout->tile_border_x = 6;
-               sfile->layout->tile_border_y = 6;
-               sfile->layout->prv_border_x = 6;
-               sfile->layout->prv_border_y = 6;
-               sfile->layout->tile_w = sfile->layout->prv_w + 2*sfile->layout->prv_border_x;
-               sfile->layout->tile_h = sfile->layout->prv_h + 2*sfile->layout->prv_border_y + textheight;
-               sfile->layout->width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->layout->tile_border_x);
-               sfile->layout->columns= sfile->layout->width / (sfile->layout->tile_w + 2*sfile->layout->tile_border_x);
-               if(sfile->layout->columns > 0)
-                       sfile->layout->rows= numfiles/sfile->layout->columns + 1; // XXX dirty, modulo is zero
+               layout->prv_w = 96;
+               layout->prv_h = 96;
+               layout->tile_border_x = 6;
+               layout->tile_border_y = 6;
+               layout->prv_border_x = 6;
+               layout->prv_border_y = 6;
+               layout->tile_w = layout->prv_w + 2*layout->prv_border_x;
+               layout->tile_h = layout->prv_h + 2*layout->prv_border_y + textheight;
+               layout->width= (v2d->cur.xmax - v2d->cur.xmin - 2*layout->tile_border_x);
+               layout->columns= layout->width / (layout->tile_w + 2*layout->tile_border_x);
+               if(layout->columns > 0)
+                       layout->rows= numfiles/layout->columns + 1; // XXX dirty, modulo is zero
                else {
-                       sfile->layout->columns = 1;
-                       sfile->layout->rows= numfiles + 1; // XXX dirty, modulo is zero
+                       layout->columns = 1;
+                       layout->rows= numfiles + 1; // XXX dirty, modulo is zero
                }
-               sfile->layout->height= sfile->layout->rows*(sfile->layout->tile_h+2*sfile->layout->tile_border_y) + sfile->layout->tile_border_y*2;
-               sfile->layout->flag = FILE_LAYOUT_VER;
+               layout->height= sfile->layout->rows*(layout->tile_h+2*layout->tile_border_y) + layout->tile_border_y*2;
+               layout->flag = FILE_LAYOUT_VER;
        } else {
-               sfile->layout->prv_w = 0;
-               sfile->layout->prv_h = 0;
-               sfile->layout->tile_border_x = 8;
-               sfile->layout->tile_border_y = 2;
-               sfile->layout->prv_border_x = 0;
-               sfile->layout->prv_border_y = 0;
-               sfile->layout->tile_h = textheight*3/2;
-               sfile->layout->height= v2d->cur.ymax - v2d->cur.ymin;
-               sfile->layout->rows = sfile->layout->height / (sfile->layout->tile_h + 2*sfile->layout->tile_border_y);;
+               layout->prv_w = 0;
+               layout->prv_h = 0;
+               layout->tile_border_x = 8;
+               layout->tile_border_y = 2;
+               layout->prv_border_x = 0;
+               layout->prv_border_y = 0;
+               layout->tile_h = textheight*3/2;
+               layout->height= v2d->cur.ymax - v2d->cur.ymin - 2*layout->tile_border_y;
+               layout->rows = layout->height / (layout->tile_h + 2*layout->tile_border_y);
         
-               column_widths(sfile->files, sfile->layout);
+               column_widths(sfile->files, layout);
 
                if (params->display == FILE_SHORTDISPLAY) {
-                       maxlen = sfile->layout->column_widths[COLUMN_NAME] +
-                                        sfile->layout->column_widths[COLUMN_SIZE];
+                       maxlen = layout->column_widths[COLUMN_NAME] +
+                                        layout->column_widths[COLUMN_SIZE];
                        maxlen += 20+2*10; // for icon and space between columns
                } else {
-                       maxlen = sfile->layout->column_widths[COLUMN_NAME] +
-                                        sfile->layout->column_widths[COLUMN_DATE] +
-                                        sfile->layout->column_widths[COLUMN_TIME] +
-                                        sfile->layout->column_widths[COLUMN_SIZE];
+                       maxlen = layout->column_widths[COLUMN_NAME] +
+                                        layout->column_widths[COLUMN_DATE] +
+                                        layout->column_widths[COLUMN_TIME] +
+                                        layout->column_widths[COLUMN_SIZE];
                                        /* XXX add mode1, mode2, mode3, owner columns for non-windows platforms */
                        maxlen += 20+4*10; // for icon and space between columns
                }
-               sfile->layout->tile_w = maxlen + 40;
-               if(sfile->layout->rows > 0)
-                       sfile->layout->columns = numfiles/sfile->layout->rows + 1; // XXX dirty, modulo is zero
+               layout->tile_w = maxlen + 40;
+               if(layout->rows > 0)
+                       layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero
                else {
-                       sfile->layout->rows = 1;
-                       sfile->layout->columns = numfiles + 1; // XXX dirty, modulo is zero
+                       layout->rows = 1;
+                       layout->columns = numfiles + 1; // XXX dirty, modulo is zero
                }
-               sfile->layout->width = sfile->layout->columns * (sfile->layout->tile_w + 2*sfile->layout->tile_border_x) + sfile->layout->tile_border_x*2;
-               sfile->layout->flag = FILE_LAYOUT_HOR;
-       } 
+               layout->width = sfile->layout->columns * (layout->tile_w + 2*layout->tile_border_x) + layout->tile_border_x*2;
+               layout->flag = FILE_LAYOUT_HOR;
+       }
+       layout->dirty= 0;
 }
 
 FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar)
index 5af79eb28004e9c31a533b7a22a11f1932129e84..077ad65830cf4d697771661bc6a53b25497d9351 100644 (file)
@@ -153,6 +153,7 @@ static void file_free(SpaceLink *sl)
 /* spacetype; init callback, area size changes, screen set, etc */
 static void file_init(struct wmWindowManager *wm, ScrArea *sa)
 {
+       printf("file_init\n");
 }
 
 
@@ -200,6 +201,9 @@ static void file_refresh(const bContext *C, ScrArea *sa)
        }
        filelist_setfilter(sfile->files, params->flag & FILE_FILTER ? params->filter : 0);      
        if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort);             
+
+       if (sfile->layout) sfile->layout->dirty= 1;
+
 }
 
 static void file_listener(ScrArea *sa, wmNotifier *wmn)
@@ -213,11 +217,9 @@ static void file_listener(ScrArea *sa, wmNotifier *wmn)
                                case ND_FILELIST:
                                        if (sfile->files) filelist_free(sfile->files);
                                        ED_area_tag_refresh(sa);
-                                       ED_area_tag_redraw(sa);
                                        break;
                                case ND_PARAMS:
                                        ED_area_tag_refresh(sa);
-                                       ED_area_tag_redraw(sa);
                                        break;
                        }
                        break;
@@ -241,6 +243,23 @@ static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
 
 }
 
+static void file_main_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+       /* context changes */
+       switch(wmn->category) {
+               case NC_FILE:
+                       switch (wmn->data) {
+                               case ND_FILELIST:
+                                       ED_region_tag_redraw(ar);
+                                       break;
+                               case ND_PARAMS:
+                                       ED_region_tag_redraw(ar);
+                                       break;
+                       }
+                       break;
+       }
+}
+
 static void file_main_area_draw(const bContext *C, ARegion *ar)
 {
        /* draw entirely, view changes should be handled here */
@@ -252,6 +271,10 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
        View2DScrollers *scrollers;
        float col[3];
 
+       /* Needed, because filelist is not initialized on loading */
+       if (!sfile->files)
+               file_refresh(C, NULL);
+
        layout = ED_fileselect_get_layout(sfile, ar);
 
        /* clear and setup matrix */
@@ -471,7 +494,7 @@ void ED_spacetype_file(void)
        art->regionid = RGN_TYPE_WINDOW;
        art->init= file_main_area_init;
        art->draw= file_main_area_draw;
-       // art->listener= file_main_area_listener;
+       art->listener= file_main_area_listener;
        art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
        BLI_addhead(&st->regiontypes, art);
        
index 3a646c5e799cb7936bab9ec2b894569aa64b6fbe..cadb9502adb4ad6d9ba24c8a82569c91475afa39 100644 (file)
@@ -190,6 +190,7 @@ typedef struct wmNotifier {
        /* NC_FILE Filebrowser */
 #define ND_PARAMS                      (60<<16)
 #define ND_FILELIST                    (61<<16)
+#define ND_FILEDISPLAY         (62<<16)
 
        /* NC_ANIMATION Animato */
 #define ND_KEYFRAME_SELECT     (70<<16)