2.5 compile errors.
[blender-staging.git] / source / blender / editors / space_file / filelist.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2007 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30
31 /* global includes */
32
33 #include <stdlib.h>
34 #include <math.h>
35 #include <string.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #ifndef WIN32
42 #include <unistd.h>
43 #else
44 #include <io.h>
45 #include <direct.h>
46 #endif   
47 #include "MEM_guardedalloc.h"
48
49 #include "BLI_blenlib.h"
50 #include "BLI_linklist.h"
51 #include "BLI_storage_types.h"
52 #include "BLI_threads.h"
53
54 #ifdef WIN32
55 #include "BLI_winstuff.h"
56 #endif
57
58 #include "BKE_utildefines.h"
59 #include "BKE_global.h"
60 #include "BKE_library.h"
61 #include "BKE_global.h"
62 #include "BKE_main.h"
63 #include "BLO_readfile.h"
64
65 #include "DNA_space_types.h"
66 #include "DNA_ipo_types.h"
67 #include "DNA_ID.h"
68 #include "DNA_object_types.h"
69 #include "DNA_listBase.h"
70 #include "DNA_lamp_types.h"
71 #include "DNA_material_types.h"
72 #include "DNA_texture_types.h"
73 #include "DNA_world_types.h"
74 #include "DNA_scene_types.h"
75 #include "DNA_userdef_types.h"
76
77 #include "ED_datafiles.h"
78
79 #include "IMB_imbuf.h"
80 #include "IMB_imbuf_types.h"
81 #include "IMB_thumbs.h"
82
83 #include "PIL_time.h"
84
85 #include "UI_interface.h"
86
87 #include "filelist.h"
88
89 /* Elubie: VERY, really very ugly and evil! Remove asap!!! */
90 /* for state of file */
91 #define ACTIVE                          2
92
93 /* max length of library group name within filesel */
94 #define GROUP_MAX 32
95
96 static void *exec_loadimages(void *list_v);
97
98 struct FileList;
99
100 typedef struct FileImage {
101         struct FileImage *next, *prev;
102         int index;
103         short lock;
104         short done;
105         struct FileList* filelist;
106 } FileImage;
107
108 typedef struct FileList
109 {
110         struct direntry *filelist;
111         int *fidx;
112
113         int numfiles;
114         int numfiltered;
115         char dir[FILE_MAX];
116         short type;
117         int has_func;
118         short prv_w;
119         short prv_h;
120         short hide_dot;
121         unsigned int filter;
122         short changed;
123         ListBase loadimages;
124         ListBase threads;
125 } FileList;
126
127 #define SPECIAL_IMG_SIZE 48
128 #define SPECIAL_IMG_ROWS 4
129 #define SPECIAL_IMG_COLS 4
130
131 #define SPECIAL_IMG_FOLDER 0
132 #define SPECIAL_IMG_PARENT 1
133 #define SPECIAL_IMG_REFRESH 2
134 #define SPECIAL_IMG_BLENDFILE 3
135 #define SPECIAL_IMG_SOUNDFILE 4
136 #define SPECIAL_IMG_MOVIEFILE 5
137 #define SPECIAL_IMG_PYTHONFILE 6
138 #define SPECIAL_IMG_TEXTFILE 7
139 #define SPECIAL_IMG_FONTFILE 8
140 #define SPECIAL_IMG_UNKNOWNFILE 9
141 #define SPECIAL_IMG_LOADING 10
142 #define SPECIAL_IMG_MAX SPECIAL_IMG_LOADING + 1
143
144 static ImBuf* gSpecialFileImages[SPECIAL_IMG_MAX];
145
146
147 /* ******************* SORT ******************* */
148
149 static int compare_name(const void *a1, const void *a2)
150 {
151         const struct direntry *entry1=a1, *entry2=a2;
152
153         /* type is is equal to stat.st_mode */
154
155         if (S_ISDIR(entry1->type)){
156                 if (S_ISDIR(entry2->type)==0) return (-1);
157         } else{
158                 if (S_ISDIR(entry2->type)) return (1);
159         }
160         if (S_ISREG(entry1->type)){
161                 if (S_ISREG(entry2->type)==0) return (-1);
162         } else{
163                 if (S_ISREG(entry2->type)) return (1);
164         }
165         if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
166         if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
167         
168         /* make sure "." and ".." are always first */
169         if( strcmp(entry1->relname, ".")==0 ) return (-1);
170         if( strcmp(entry2->relname, ".")==0 ) return (1);
171         if( strcmp(entry1->relname, "..")==0 ) return (-1);
172         if( strcmp(entry2->relname, "..")==0 ) return (1);
173         
174         return (BLI_strcasecmp(entry1->relname,entry2->relname));
175 }
176
177 static int compare_date(const void *a1, const void *a2) 
178 {
179         const struct direntry *entry1=a1, *entry2=a2;
180         
181         /* type is equal to stat.st_mode */
182
183         if (S_ISDIR(entry1->type)){
184                 if (S_ISDIR(entry2->type)==0) return (-1);
185         } else{
186                 if (S_ISDIR(entry2->type)) return (1);
187         }
188         if (S_ISREG(entry1->type)){
189                 if (S_ISREG(entry2->type)==0) return (-1);
190         } else{
191                 if (S_ISREG(entry2->type)) return (1);
192         }
193         if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
194         if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
195
196         /* make sure "." and ".." are always first */
197         if( strcmp(entry1->relname, ".")==0 ) return (-1);
198         if( strcmp(entry2->relname, ".")==0 ) return (1);
199         if( strcmp(entry1->relname, "..")==0 ) return (-1);
200         if( strcmp(entry2->relname, "..")==0 ) return (1);
201         
202         if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1;
203         if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1;
204         
205         else return BLI_strcasecmp(entry1->relname,entry2->relname);
206 }
207
208 static int compare_size(const void *a1, const void *a2) 
209 {
210         const struct direntry *entry1=a1, *entry2=a2;
211
212         /* type is equal to stat.st_mode */
213
214         if (S_ISDIR(entry1->type)){
215                 if (S_ISDIR(entry2->type)==0) return (-1);
216         } else{
217                 if (S_ISDIR(entry2->type)) return (1);
218         }
219         if (S_ISREG(entry1->type)){
220                 if (S_ISREG(entry2->type)==0) return (-1);
221         } else{
222                 if (S_ISREG(entry2->type)) return (1);
223         }
224         if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
225         if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
226
227         /* make sure "." and ".." are always first */
228         if( strcmp(entry1->relname, ".")==0 ) return (-1);
229         if( strcmp(entry2->relname, ".")==0 ) return (1);
230         if( strcmp(entry1->relname, "..")==0 ) return (-1);
231         if( strcmp(entry2->relname, "..")==0 ) return (1);
232         
233         if ( entry1->s.st_size < entry2->s.st_size) return 1;
234         if ( entry1->s.st_size > entry2->s.st_size) return -1;
235         else return BLI_strcasecmp(entry1->relname,entry2->relname);
236 }
237
238 static int compare_extension(const void *a1, const void *a2) {
239         const struct direntry *entry1=a1, *entry2=a2;
240         char *sufix1, *sufix2;
241         char *nil="";
242
243         if (!(sufix1= strstr (entry1->relname, ".blend.gz"))) 
244                 sufix1= strrchr (entry1->relname, '.');
245         if (!(sufix2= strstr (entry2->relname, ".blend.gz")))
246                 sufix2= strrchr (entry2->relname, '.');
247         if (!sufix1) sufix1= nil;
248         if (!sufix2) sufix2= nil;
249
250         /* type is is equal to stat.st_mode */
251
252         if (S_ISDIR(entry1->type)){
253                 if (S_ISDIR(entry2->type)==0) return (-1);
254         } else{
255                 if (S_ISDIR(entry2->type)) return (1);
256         }
257         if (S_ISREG(entry1->type)){
258                 if (S_ISREG(entry2->type)==0) return (-1);
259         } else{
260                 if (S_ISREG(entry2->type)) return (1);
261         }
262         if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
263         if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
264         
265         /* make sure "." and ".." are always first */
266         if( strcmp(entry1->relname, ".")==0 ) return (-1);
267         if( strcmp(entry2->relname, ".")==0 ) return (1);
268         if( strcmp(entry1->relname, "..")==0 ) return (-1);
269         if( strcmp(entry2->relname, "..")==0 ) return (1);
270         
271         return (BLI_strcasecmp(sufix1, sufix2));
272 }
273
274 void filelist_filter(FileList* filelist)
275 {
276         int num_filtered = 0;
277         int i, j;
278         
279         if (!filelist->filelist)
280                 return;
281         
282         if (!filelist->filter) {
283                 if (filelist->fidx) {
284                         MEM_freeN(filelist->fidx);
285                         filelist->fidx = NULL;
286                 }
287                 filelist->fidx = (int *)MEM_callocN(filelist->numfiles*sizeof(int), "filteridx");
288                 for (i = 0; i < filelist->numfiles; ++i) {
289                         filelist->fidx[i] = i;
290                 }
291                 filelist->numfiltered = filelist->numfiles;
292                 return;
293         }
294
295         // How many files are left after filter ?
296         for (i = 0; i < filelist->numfiles; ++i) {
297                 if (filelist->filelist[i].flags & filelist->filter) {
298                         num_filtered++;
299                 } 
300                 else if (filelist->filelist[i].type & S_IFDIR) {
301                         if (filelist->filter & FOLDERFILE) {
302                                 num_filtered++;
303                         }
304                 }               
305         }
306         
307         if (filelist->fidx) {
308                         MEM_freeN(filelist->fidx);
309                         filelist->fidx = NULL;
310         }
311         filelist->fidx = (int *)MEM_callocN(num_filtered*sizeof(int), "filteridx");
312         filelist->numfiltered = num_filtered;
313
314         for (i = 0, j=0; i < filelist->numfiles; ++i) {
315                 if (filelist->filelist[i].flags & filelist->filter) {
316                         filelist->fidx[j++] = i;
317                 }
318                 else if (filelist->filelist[i].type & S_IFDIR) {
319                         if (filelist->filter & FOLDERFILE) {
320                                 filelist->fidx[j++] = i;
321                         }
322                 }  
323         }
324 }
325
326 void filelist_init_icons()
327 {
328         short x, y, k;
329         ImBuf *bbuf;
330         ImBuf *ibuf;
331         bbuf = IMB_ibImageFromMemory((int *)datatoc_prvicons, datatoc_prvicons_size, IB_rect);
332         if (bbuf) {
333                 for (y=0; y<SPECIAL_IMG_ROWS; y++) {
334                         for (x=0; x<SPECIAL_IMG_COLS; x++) {
335                                 int tile = SPECIAL_IMG_COLS*y + x; 
336                                 if (tile < SPECIAL_IMG_MAX) {
337                                         ibuf = IMB_allocImBuf(SPECIAL_IMG_SIZE, SPECIAL_IMG_SIZE, 32, IB_rect, 0);
338                                         for (k=0; k<SPECIAL_IMG_SIZE; k++) {
339                                                 memcpy(&ibuf->rect[k*SPECIAL_IMG_SIZE], &bbuf->rect[(k+y*SPECIAL_IMG_SIZE)*SPECIAL_IMG_SIZE*SPECIAL_IMG_COLS+x*SPECIAL_IMG_SIZE], SPECIAL_IMG_SIZE*sizeof(int));
340                                         }
341                                         gSpecialFileImages[tile] = ibuf;
342                                 }
343                         }
344                 }
345                 IMB_freeImBuf(bbuf);
346         }
347 }
348
349 void filelist_free_icons()
350 {
351         int i;
352         for (i=0; i < SPECIAL_IMG_MAX; ++i) {
353                 IMB_freeImBuf(gSpecialFileImages[i]);
354                 gSpecialFileImages[i] = NULL;
355         }
356 }
357
358 struct FileList*        filelist_new()
359 {
360         FileList* p = MEM_callocN( sizeof(FileList), "filelist" );
361         p->filelist = 0;
362         p->numfiles = 0;
363         p->dir[0] = '\0';
364         p->type = 0;
365         p->has_func = 0;
366         p->filter = 0;
367         return p;
368 }
369
370 struct FileList*        filelist_copy(struct FileList* filelist)
371 {
372         FileList* p = filelist_new();
373         BLI_strncpy(p->dir, filelist->dir, FILE_MAX);
374         p->filelist = NULL;
375         p->fidx = NULL;
376         p->type = filelist->type;
377
378         return p;
379 }
380
381 void filelist_free(struct FileList* filelist)
382 {
383         int i;
384
385         if (!filelist) {
386                 printf("Attemtping to delete empty filelist.\n");
387                 return;
388         }
389
390         BLI_end_threads(&filelist->threads);
391         BLI_freelistN(&filelist->loadimages);
392         
393         if (filelist->fidx) {
394                 MEM_freeN(filelist->fidx);
395                 filelist->fidx = NULL;
396         }
397
398         for (i = 0; i < filelist->numfiles; ++i) {
399                 if (filelist->filelist[i].image) {                      
400                         IMB_freeImBuf(filelist->filelist[i].image);
401                 }
402                 filelist->filelist[i].image = 0;
403                 if (filelist->filelist[i].relname)
404                         MEM_freeN(filelist->filelist[i].relname);
405                 filelist->filelist[i].relname = 0;
406                 if (filelist->filelist[i].string)
407                         MEM_freeN(filelist->filelist[i].string);
408                 filelist->filelist[i].string = 0;
409         }
410         
411         filelist->numfiles = 0;
412         free(filelist->filelist);
413         filelist->filelist = 0; 
414         filelist->filter = 0;
415         filelist->numfiltered =0;
416 }
417
418 int     filelist_numfiles(struct FileList* filelist)
419 {
420         return filelist->numfiltered;
421 }
422
423 const char * filelist_dir(struct FileList* filelist)
424 {
425         return filelist->dir;
426 }
427
428 void filelist_setdir(struct FileList* filelist, const char *dir)
429 {
430         BLI_strncpy(filelist->dir, dir, FILE_MAX);
431 }
432
433 void filelist_imgsize(struct FileList* filelist, short w, short h)
434 {
435         filelist->prv_w = w;
436         filelist->prv_h = h;
437 }
438
439
440 static void *exec_loadimages(void *list_v)
441 {
442         FileImage* img = (FileImage*)list_v;
443         struct FileList *filelist = img->filelist;
444
445         ImBuf *imb = NULL;
446         int fidx = img->index;
447         
448         if ( filelist->filelist[fidx].flags & IMAGEFILE ) {                             
449                 imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_IMAGE);
450         } else if ( filelist->filelist[fidx].flags & MOVIEFILE ) {                              
451                 imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_MOVIE);
452                 if (!imb) {
453                         /* remember that file can't be loaded via IMB_open_anim */
454                         filelist->filelist[fidx].flags &= ~MOVIEFILE;
455                         filelist->filelist[fidx].flags |= MOVIEFILE_ICON;
456                 }
457         }
458         if (imb) {
459                 IMB_freeImBuf(imb);
460         }
461         img->done=1;
462         return 0;
463 }
464
465 short filelist_changed(struct FileList* filelist)
466 {
467         return filelist->changed;
468 }
469
470 void filelist_loadimage_timer(struct FileList* filelist)
471 {
472         FileImage *limg = filelist->loadimages.first;
473         short refresh=0;
474
475         // as long as threads are available and there is work to do
476         while (limg) {
477                 if (BLI_available_threads(&filelist->threads)>0) {
478                         if (!limg->lock) {
479                                 limg->lock=1;
480                                 BLI_insert_thread(&filelist->threads, limg);
481                         }
482                 }
483                 if (limg->done) {
484                         FileImage *oimg = limg;
485                         BLI_remlink(&filelist->loadimages, oimg);
486                         BLI_remove_thread(&filelist->threads, oimg);
487                         limg = oimg->next;
488                         MEM_freeN(oimg);
489                         refresh = 1;
490                 } else {
491                         limg= limg->next;
492                 }
493         }
494         filelist->changed=refresh;
495 }
496
497 void filelist_loadimage(struct FileList* filelist, int index)
498 {
499         ImBuf *imb = NULL;
500         int imgwidth = filelist->prv_w;
501         int imgheight = filelist->prv_h;
502         short ex, ey, dx, dy;
503         float scaledx, scaledy;
504         int fidx = 0;
505         
506         if ( (index < 0) || (index >= filelist->numfiltered) ) {
507                 return;
508         }
509         fidx = filelist->fidx[index];
510
511         if (!filelist->filelist[fidx].image)
512         {
513                 if (filelist->type != FILE_MAIN)
514                 {
515                         if ( (filelist->filelist[fidx].flags & IMAGEFILE) || (filelist->filelist[fidx].flags & MOVIEFILE) ) {                           
516                                 imb = IMB_thumb_read(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL);
517                         } 
518                         if (imb) {
519                                 if (imb->x > imb->y) {
520                                         scaledx = (float)imgwidth;
521                                         scaledy =  ( (float)imb->y/(float)imb->x )*imgwidth;
522                                 }
523                                 else {
524                                         scaledy = (float)imgheight;
525                                         scaledx =  ( (float)imb->x/(float)imb->y )*imgheight;
526                                 }
527                                 ex = (short)scaledx;
528                                 ey = (short)scaledy;
529                                 
530                                 dx = imgwidth - ex;
531                                 dy = imgheight - ey;
532                                 
533                                 // IMB_scaleImBuf(imb, ex, ey);
534                                 filelist->filelist[fidx].image = imb;
535                         } else {
536                                 /* prevent loading image twice */
537                                 FileImage* limg = filelist->loadimages.first;
538                                 short found= 0;
539                                 while(limg) {
540                                         if (limg->index == fidx) {
541                                                 found= 1;
542                                                 break;
543                                         }
544                                         limg= limg->next;
545                                 }
546                                 if (!found) {
547                                         FileImage* limg = MEM_callocN(sizeof(struct FileImage), "loadimage");
548                                         limg->index= fidx;
549                                         limg->lock= 0;
550                                         limg->filelist= filelist;
551                                         BLI_addtail(&filelist->loadimages, limg);
552                                 }
553                         }               
554                 }
555         }
556 }
557
558 struct ImBuf * filelist_getimage(struct FileList* filelist, int index)
559 {
560         ImBuf* ibuf = NULL;
561         int fidx = 0;   
562         if ( (index < 0) || (index >= filelist->numfiltered) ) {
563                 return NULL;
564         }
565         fidx = filelist->fidx[index];
566         ibuf = filelist->filelist[fidx].image;
567
568         return ibuf;
569 }
570
571 struct ImBuf * filelist_geticon(struct FileList* filelist, int index)
572 {
573         ImBuf* ibuf= NULL;
574         struct direntry *file= NULL;
575         int fidx = 0;   
576         if ( (index < 0) || (index >= filelist->numfiltered) ) {
577                 return NULL;
578         }
579         fidx = filelist->fidx[index];
580         file = &filelist->filelist[fidx];
581         if (file->type & S_IFDIR) {
582                         if ( strcmp(filelist->filelist[fidx].relname, "..") == 0) {
583                                 ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
584                         } else if  ( strcmp(filelist->filelist[fidx].relname, ".") == 0) {
585                                 ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
586                         } else {
587                 ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
588                         }
589         } else {
590                 ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
591         }
592
593         if (file->flags & BLENDERFILE) {
594                 ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
595         } else if ( (file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON) ) {
596                 ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
597         } else if (file->flags & SOUNDFILE) {
598                 ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
599         } else if (file->flags & PYSCRIPTFILE) {
600                 ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
601         } else if (file->flags & FTFONTFILE) {
602                 ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
603         } else if (file->flags & TEXTFILE) {
604                 ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
605         } else if (file->flags & IMAGEFILE) {
606                 ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
607         }
608
609         return ibuf;
610 }
611
612 struct direntry * filelist_file(struct FileList* filelist, int index)
613 {
614         int fidx = 0;
615         
616         if ( (index < 0) || (index >= filelist->numfiltered) ) {
617                 return NULL;
618         }
619         fidx = filelist->fidx[index];
620
621         return &filelist->filelist[fidx];
622 }
623
624
625 int filelist_find(struct FileList* filelist, char *file)
626 {
627         int index = -1;
628         int i;
629         int fidx = -1;
630         
631         if (!filelist->fidx) 
632                 return fidx;
633
634         
635         for (i = 0; i < filelist->numfiles; ++i) {
636                 if ( strcmp(filelist->filelist[i].relname, file) == 0) {
637                         index = i;
638                         break;
639                 }
640         }
641
642         for (i = 0; i < filelist->numfiltered; ++i) {
643                 if (filelist->fidx[i] == index) {
644                         fidx = i;
645                         break;
646                 }
647         }
648         return fidx;
649 }
650
651 void filelist_hidedot(struct FileList* filelist, short hide)
652 {
653         filelist->hide_dot = hide;
654 }
655
656 void filelist_setfilter(struct FileList* filelist, unsigned int filter)
657 {
658         filelist->filter = filter;
659 }
660
661 void filelist_readdir(struct FileList* filelist)
662 {
663         char wdir[FILE_MAX];
664
665         if (!filelist) return;
666         filelist->fidx = 0;
667         filelist->filelist = 0;
668
669         BLI_getwdN(wdir);        
670         
671         BLI_cleanup_dir(G.sce, filelist->dir);
672         BLI_hide_dot_files(filelist->hide_dot);
673         filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
674
675         chdir(wdir);
676         filelist_setfiletypes(filelist, G.have_quicktime);
677         filelist_filter(filelist);
678         
679         if (!filelist->threads.first) {
680                 BLI_init_threads(&filelist->threads, exec_loadimages, 2);
681         }
682 }
683
684 int filelist_empty(struct FileList* filelist)
685 {       
686         return filelist->filelist == 0;
687 }
688
689 void filelist_parent(struct FileList* filelist)
690 {
691         BLI_parent_dir(filelist->dir);
692         BLI_make_exist(filelist->dir);
693         filelist_readdir(filelist);
694 }
695
696 void filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
697 {
698         struct direntry *file;
699         int num;
700
701         file= filelist->filelist;
702
703         for(num=0; num<filelist->numfiles; num++, file++) {
704                 file->flags= 0;
705                 file->type= file->s.st_mode;    /* restore the mess below */ 
706
707                         /* Don't check extensions for directories */ 
708                 if (file->type & S_IFDIR)
709                         continue;
710                                 
711                 
712                 
713                 if(BLO_has_bfile_extension(file->relname)) {
714                         file->flags |= BLENDERFILE;
715                 } else if(BLI_testextensie(file->relname, ".py")) {
716                                 file->flags |= PYSCRIPTFILE;
717                 } else if(BLI_testextensie(file->relname, ".txt")) {
718                                 file->flags |= TEXTFILE;
719                 } else if( BLI_testextensie(file->relname, ".ttf")
720                                         || BLI_testextensie(file->relname, ".ttc")
721                                         || BLI_testextensie(file->relname, ".pfb")
722                                         || BLI_testextensie(file->relname, ".otf")
723                                         || BLI_testextensie(file->relname, ".otc")) {
724                                 file->flags |= FTFONTFILE;                      
725                 } else if (has_quicktime){
726                         if(             BLI_testextensie(file->relname, ".int")
727                                 ||  BLI_testextensie(file->relname, ".inta")
728                                 ||  BLI_testextensie(file->relname, ".jpg")
729 #ifdef WITH_OPENJPEG
730                                 ||  BLI_testextensie(file->relname, ".jp2")
731 #endif
732                                 ||      BLI_testextensie(file->relname, ".jpeg")
733                                 ||      BLI_testextensie(file->relname, ".tga")
734                                 ||      BLI_testextensie(file->relname, ".rgb")
735                                 ||      BLI_testextensie(file->relname, ".rgba")
736                                 ||      BLI_testextensie(file->relname, ".bmp")
737                                 ||      BLI_testextensie(file->relname, ".png")
738                                 ||      BLI_testextensie(file->relname, ".iff")
739                                 ||      BLI_testextensie(file->relname, ".lbm")
740                                 ||      BLI_testextensie(file->relname, ".gif")
741                                 ||      BLI_testextensie(file->relname, ".psd")
742                                 ||      BLI_testextensie(file->relname, ".tif")
743                                 ||      BLI_testextensie(file->relname, ".tiff")
744                                 ||      BLI_testextensie(file->relname, ".pct")
745                                 ||      BLI_testextensie(file->relname, ".pict")
746                                 ||      BLI_testextensie(file->relname, ".pntg") //macpaint
747                                 ||      BLI_testextensie(file->relname, ".qtif")
748                                 ||      BLI_testextensie(file->relname, ".sgi")
749                                 ||      BLI_testextensie(file->relname, ".hdr")
750 #ifdef WITH_DDS
751                                 ||      BLI_testextensie(file->relname, ".dds")
752 #endif
753 #ifdef WITH_OPENEXR
754                                 ||      BLI_testextensie(file->relname, ".exr")
755 #endif
756                             ) {
757                                 file->flags |= IMAGEFILE;                       
758                         }
759                         else if(BLI_testextensie(file->relname, ".avi")
760                                 ||      BLI_testextensie(file->relname, ".flc")
761                                 ||      BLI_testextensie(file->relname, ".mov")
762                                 ||      BLI_testextensie(file->relname, ".movie")
763                                 ||      BLI_testextensie(file->relname, ".mp4")
764                                 ||      BLI_testextensie(file->relname, ".m4v")
765                                 ||      BLI_testextensie(file->relname, ".mv")) {
766                                 file->flags |= MOVIEFILE;                       
767                         }
768                         else if(BLI_testextensie(file->relname, ".wav")) {
769                                 file->flags |= SOUNDFILE;
770                         }
771                 } else { // no quicktime
772                         if(BLI_testextensie(file->relname, ".int")
773                                 ||      BLI_testextensie(file->relname, ".inta")
774                                 ||      BLI_testextensie(file->relname, ".jpg")
775                                 ||  BLI_testextensie(file->relname, ".jpeg")
776 #ifdef WITH_OPENJPEG
777                                 ||  BLI_testextensie(file->relname, ".jp2")
778 #endif
779                                 ||      BLI_testextensie(file->relname, ".tga")
780                                 ||      BLI_testextensie(file->relname, ".rgb")
781                                 ||      BLI_testextensie(file->relname, ".rgba")
782                                 ||      BLI_testextensie(file->relname, ".bmp")
783                                 ||      BLI_testextensie(file->relname, ".png")
784                                 ||      BLI_testextensie(file->relname, ".iff")
785                                 ||      BLI_testextensie(file->relname, ".tif")
786                                 ||      BLI_testextensie(file->relname, ".tiff")
787                                 ||      BLI_testextensie(file->relname, ".hdr")
788 #ifdef WITH_DDS
789                                 ||      BLI_testextensie(file->relname, ".dds")
790 #endif
791 #ifdef WITH_OPENEXR
792                                 ||      BLI_testextensie(file->relname, ".exr")
793 #endif
794                                 ||      BLI_testextensie(file->relname, ".lbm")
795                                 ||      BLI_testextensie(file->relname, ".sgi")) {
796                                 file->flags |= IMAGEFILE;                       
797                         }
798                         else if(BLI_testextensie(file->relname, ".avi")
799                                 ||      BLI_testextensie(file->relname, ".mp4")
800                                 ||      BLI_testextensie(file->relname, ".mv")) {
801                                 file->flags |= MOVIEFILE;                       
802                         }
803                         else if(BLI_testextensie(file->relname, ".wav")) {
804                                 file->flags |= SOUNDFILE;
805                         }
806                 }
807         }
808 }
809
810 void filelist_swapselect(struct FileList* filelist)
811 {
812         struct direntry *file;
813         int num, act= 0;
814         
815         file= filelist->filelist;
816         for(num=0; num<filelist->numfiles; num++, file++) {
817                 if(file->flags & ACTIVE) {
818                         act= 1;
819                         break;
820                 }
821         }
822         file= filelist->filelist+2;
823         for(num=2; num<filelist->numfiles; num++, file++) {
824                 if(act) file->flags &= ~ACTIVE;
825                 else file->flags |= ACTIVE;
826         }
827 }
828
829 void filelist_settype(struct FileList* filelist, int type)
830 {
831         filelist->type = type;
832 }
833
834 short filelist_gettype(struct FileList* filelist)
835 {
836         return filelist->type;
837 }
838
839 void filelist_sort(struct FileList* filelist, short sort)
840 {
841         struct direntry *file;
842         int num;/*  , act= 0; */
843
844         switch(sort) {
845         case FILE_SORTALPHA:
846                 qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);   
847                 break;
848         case FILE_SORTDATE:
849                 qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);   
850                 break;
851         case FILE_SORTSIZE:
852                 qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);   
853                 break;
854         case FILE_SORTEXTENS:
855                 qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);      
856         }
857
858         file= filelist->filelist;
859         for(num=0; num<filelist->numfiles; num++, file++) {
860                 file->flags &= ~HILITE;
861         }
862         filelist_filter(filelist);
863 }