diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/blender/src/filesel.c |
Initial revisionv2.25
Diffstat (limited to 'source/blender/src/filesel.c')
-rw-r--r-- | source/blender/src/filesel.c | 2376 |
1 files changed, 2376 insertions, 0 deletions
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c new file mode 100644 index 00000000000..7a63a7779a0 --- /dev/null +++ b/source/blender/src/filesel.c @@ -0,0 +1,2376 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include <io.h> +#include <direct.h> +#include "BLI_winstuff.h" +#else +#include <unistd.h> +#include <sys/times.h> +#endif + +#include <sys/stat.h> +#include <sys/types.h> +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_linklist.h" +#include "BLI_storage_types.h" +#include "BLI_dynstr.h" + +#include "IMB_imbuf.h" + +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_vfont_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_texture_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_displist.h" +#include "BKE_library.h" +#include "BKE_curve.h" +#include "BKE_font.h" +#include "BKE_material.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_editview.h" +#include "BIF_space.h" +#include "BIF_screen.h" + +#include "BLO_readfile.h" + +#include "BDR_editcurve.h" +#include "BSE_filesel.h" +#include "BSE_view.h" + +#include "mydevice.h" +#include "blendef.h" +#include "render.h" +#include "interface.h" +#include "nla.h" + +#if defined WIN32 || defined __BeOS + int fnmatch(){return 0;} +#else + #include <fnmatch.h> +#endif + +#ifndef WIN32 +#include <sys/param.h> +#endif + +#define FILESELHEAD 60 +#define FILESEL_DY 16 + +#define NOTACTIVE 0 +#define ACTIVATE 1 +#define INACTIVATE 2 + +#define STARTSWITH(x, y) (strncmp(x, y, sizeof(x) - 1) == 0) + +static int is_a_library(SpaceFile *sfile, char *dir, char *group); +static void do_library_append(SpaceFile *sfile); +static void library_to_filelist(SpaceFile *sfile); +static void filesel_select_objects(struct SpaceFile *sfile); +static void active_file_object(struct SpaceFile *sfile); +static int groupname_to_code(char *group); + +/* local globals */ + +static rcti scrollrct, textrct, bar; +static int filebuty1, filebuty2, page_ofs, collumwidth, selecting=0; +static int filetoname= 0; +static float pixels_to_ofs; +static char otherdir[FILE_MAXDIR]; +static ScrArea *otherarea; + +/* FSMENU HANDLING */ + + /* FSMenuEntry's without paths indicate seperators */ +typedef struct _FSMenuEntry FSMenuEntry; +struct _FSMenuEntry { + FSMenuEntry *next; + + char *path; +}; + +static FSMenuEntry *fsmenu= 0, *lseperator= 0; + +int fsmenu_get_nentries(void) +{ + FSMenuEntry *fsme; + int count= 0; + + for (fsme= fsmenu; fsme; fsme= fsme->next) + count++; + + return count; +} +int fsmenu_is_entry_a_seperator(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return (fsme && !fsme->path)?1:0; +} +char *fsmenu_get_entry(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return fsme?fsme->path:NULL; +} +char *fsmenu_build_menu(void) +{ + DynStr *ds= BLI_dynstr_new(); + FSMenuEntry *fsme; + char *menustr; + + for (fsme= fsmenu; fsme; fsme= fsme->next) { + if (!fsme->path) { + /* ignore consecutive or trailing seperators */ + if (fsme->next && fsme->next->path) + BLI_dynstr_append(ds, "%l|"); + } else { + BLI_dynstr_append(ds, fsme->path); + if (fsme->next) BLI_dynstr_append(ds, "|"); + } + } + + menustr= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return menustr; +} +void fsmenu_insert_entry(char *path, int sorted) +{ + FSMenuEntry *fsme, *prev; + + if (lseperator) { + prev= lseperator; + fsme= lseperator->next; + } else { + prev= NULL; + fsme= fsmenu; + } + for (; fsme; prev= fsme, fsme= fsme->next) { + if (fsme->path) { + if (BLI_streq(path, fsme->path)) { + return; + } else if (sorted && strcmp(path, fsme->path)<0) { + break; + } + } + } + + fsme= MEM_mallocN(sizeof(*fsme), "fsme"); + fsme->path= BLI_strdup(path); + + if (prev) { + fsme->next= prev->next; + prev->next= fsme; + } else { + fsme->next= fsmenu; + fsmenu= fsme; + } +} +void fsmenu_append_seperator(void) +{ + if (fsmenu) { + FSMenuEntry *fsme= fsmenu; + + while (fsme->next) fsme= fsme->next; + + lseperator= MEM_mallocN(sizeof(*fsme), "fsme"); + lseperator->next= NULL; + lseperator->path= NULL; + + fsme->next= lseperator; + } +} +void fsmenu_remove_entry(int idx) +{ + FSMenuEntry *prev= NULL, *fsme= fsmenu; + + for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next) + if (fsme->path) + idx--; + + if (fsme) { + if (prev) { + prev->next= fsme->next; + } else { + fsmenu= fsme->next; + } + + MEM_freeN(fsme->path); + MEM_freeN(fsme); + } +} +void fsmenu_free(void) +{ + FSMenuEntry *fsme= fsmenu; + + while (fsme) { + FSMenuEntry *n= fsme->next; + + if (fsme->path) MEM_freeN(fsme->path); + MEM_freeN(fsme); + + fsme= n; + } +} + +/* ******************* SORT ******************* */ + +static int compare_name(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + return (strcasecmp(entry1->relname,entry2->relname)); +} + +static int compare_date(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + +/* + if ( entry1->s.st_ctime < entry2->s.st_ctime) return 1; + if ( entry1->s.st_ctime > entry2->s.st_ctime) return -1; +*/ + if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1; + if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1; + else return strcasecmp(entry1->relname,entry2->relname); +} + +static int compare_size(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + if ( entry1->s.st_size < entry2->s.st_size) return 1; + if ( entry1->s.st_size > entry2->s.st_size) return -1; + else return strcasecmp(entry1->relname,entry2->relname); +} + + +/* **************************************** */ + +void clear_global_filesel_vars() +{ + selecting= 0; +} + + +void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen) +{ + int a, len; + + *totfile= *selfile= 0; + *totlen= *sellen= 0; + + if(sfile->filelist==0) return; + + for(a=0; a<sfile->totfile; a++) { + if( (sfile->filelist[a].type & S_IFDIR)==0 ) { + (*totfile) ++; + + len = sfile->filelist[a].s.st_size; + (*totlen) += (len/1048576.0); + + if(sfile->filelist[a].flags & ACTIVE) { + (*selfile) ++; + (*sellen) += (len/1048576.0); + } + } + } +} + +/* *************** HULPFUNKTIES ******************* */ + +/* This is a really ugly function... its purpose is to + * take the space file name and clean it up, replacing + * excess file entry stuff (like /tmp/../tmp/../) + */ + +void checkdir(char *dir) +{ + short a; + char *start, *eind; + char tmp[FILE_MAXDIR+FILE_MAXFILE]; + + BLI_make_file_string(G.sce, tmp, dir, ""); + strcpy(dir, tmp); + +#ifdef WIN32 + if(dir[0]=='.') { /* komt voor, o.a. bij FILE_MAIN */ + dir[0]= '\\'; + dir[1]= 0; + return; + } + + while (start = strstr(dir, "\\..\\")) { + eind = start + strlen("\\..\\") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '\\') break; + a--; + } + strcpy(dir+a,eind); + } + + while (start = strstr(dir,"\\.\\")){ + eind = start + strlen("\\.\\") - 1; + strcpy(start,eind); + } + + while (start = strstr(dir,"\\\\" )){ + eind = start + strlen("\\\\") - 1; + strcpy(start,eind); + } + + if(a = strlen(dir)){ /* eerst alle '\\' weghalen aan het eind */ + while(a>0 && dir[a-1] == '\\'){ + a--; + dir[a] = 0; + } + } + + strcat(dir, "\\"); +#else + if(dir[0]=='.') { /* komt voor, o.a. bij FILE_MAIN */ + dir[0]= '/'; + dir[1]= 0; + return; + } + + while ( (start = strstr(dir, "/../")) ) { + eind = start + strlen("/../") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '/') break; + a--; + } + strcpy(dir+a,eind); + } + + while ( (start = strstr(dir,"/./")) ){ + eind = start + strlen("/./") - 1; + strcpy(start,eind); + } + + while ( (start = strstr(dir,"//" )) ){ + eind = start + strlen("//") - 1; + strcpy(start,eind); + } + + if( (a = strlen(dir)) ){ /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '/'){ + a--; + dir[a] = 0; + if (a<=0) break; + } + } + + strcat(dir, "/"); +#endif +} + +void test_flags_file(SpaceFile *sfile) +{ + struct direntry *file; + int num; + + file= sfile->filelist; + + for(num=0; num<sfile->totfile; num++, file++) { + file->flags= 0; + file->type= file->s.st_mode; /* restore het geknoei van hieronder */ + + /* Don't check extensions for directories */ + if (file->type&S_IFDIR) + continue; + + if(sfile->type==FILE_BLENDER || sfile->type==FILE_LOADLIB) { + if(BLO_has_bfile_extension(file->relname)) { + file->flags |= BLENDERFILE; + if(sfile->type==FILE_LOADLIB) { + file->type &= ~S_IFMT; + file->type |= S_IFDIR; + } + } + else if(BLI_testextensie(file->relname, ".psx")) { + file->flags |= PSXFILE; + } + } else if (sfile->type==FILE_SPECIAL){ + if(BLI_testextensie(file->relname, ".jpg") || + BLI_testextensie(file->relname, ".tga") || + BLI_testextensie(file->relname, ".rgb") || + BLI_testextensie(file->relname, ".png") || + BLI_testextensie(file->relname, ".sgi")) { + file->flags |= IMAGEFILE; + } + else if(BLI_testextensie(file->relname, ".avi") || + BLI_testextensie(file->relname, ".mv")) { + file->flags |= MOVIEFILE; + } + } + } +} + + +void sort_filelist(SpaceFile *sfile) +{ + struct direntry *file; + int num;/* , act= 0; */ + + switch(sfile->sort) { + case FILE_SORTALPHA: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + break; + case FILE_SORTDATE: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_date); + break; + case FILE_SORTSIZE: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_size); + break; + case FILE_SORTEXTENS: + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + break; + } + + sfile->act= -1; + + file= sfile->filelist; + for(num=0; num<sfile->totfile; num++, file++) { + file->flags &= ~HILITE; + } + +} + +void read_dir(SpaceFile *sfile) +{ + int num, len; + char wdir[FILE_MAXDIR]; + + /* sfile->act wordt gebruikt o.a. bij databrowse: dubbele namen van library objecten */ + sfile->act= -1; + + if(sfile->type==FILE_MAIN) { + main_to_filelist(sfile); + return; + } + else if(sfile->type==FILE_LOADLIB) { + library_to_filelist(sfile); + if(sfile->libfiledata) return; + } + + BLI_hide_dot_files(sfile->flag & FILE_HIDE_DOT); + + BLI_getwdN(wdir); + sfile->totfile= BLI_getdir(sfile->dir, &(sfile->filelist)); + chdir(wdir); + + if(sfile->sort!=FILE_SORTALPHA) sort_filelist(sfile); + + sfile->maxnamelen= 0; + + for (num=0; num<sfile->totfile; num++) { + + len = BMF_GetStringWidth(G.font, sfile->filelist[num].relname); + if (len > sfile->maxnamelen) sfile->maxnamelen = len; + + if(filetoname) { + if(strcmp(sfile->file, sfile->filelist[num].relname)==0) { + + sfile->ofs= num-( sfile->collums*(curarea->winy-FILESELHEAD-20)/(2*FILESEL_DY)); + filetoname= 0; + } + } + } + test_flags_file(sfile); + + filetoname= 0; +} + +void freefilelist(SpaceFile *sfile) +{ + int num; + + num= sfile->totfile-1; + + if (sfile->filelist==0) return; + + for(; num>=0; num--){ + free(sfile->filelist[num].relname); + + if (sfile->filelist[num].string) free(sfile->filelist[num].string); + } + free(sfile->filelist); + sfile->filelist= 0; +} + +static void split_sfile(SpaceFile *sfile, char *s1) +{ + char string[FILE_MAXDIR+FILE_MAXFILE], dir[FILE_MAXDIR], file[FILE_MAXFILE]; + + strcpy(string, s1); + + BLI_split_dirfile(string, dir, file); + + if(sfile->filelist) { + if(strcmp(dir, sfile->dir)!=0) { + freefilelist(sfile); + } + else test_flags_file(sfile); + } + strcpy(sfile->file, file); + BLI_make_file_string(G.sce, sfile->dir, dir, ""); +} + + +void parent(SpaceFile *sfile) +{ + short a; + char *dir; + + /* als databrowse: geen parent */ + if(sfile->type==FILE_MAIN && sfile->returnfunc) return; + + dir= sfile->dir; + +#ifdef WIN32 + if(a = strlen(dir)) { /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '\\') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if(a = strlen(dir)) { /* daarna alles weghalen tot aan '/' */ + while(dir[a-1] != '\\') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if (a = strlen(dir)) { + if (dir[a-1] != '\\') strcat(dir,"\\"); + } + else if(sfile->type!=FILE_MAIN) strcpy(dir,"\\"); +#else + if( (a = strlen(dir)) ) { /* eerst alle '/' weghalen aan het eind */ + while(dir[a-1] == '/') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if( (a = strlen(dir)) ) { /* daarna alles weghalen tot aan '/' */ + while(dir[a-1] != '/') { + a--; + dir[a] = 0; + if (a<=0) break; + } + } + if ( (a = strlen(dir)) ) { + if (dir[a-1] != '/') strcat(dir,"/"); + } + else if(sfile->type!=FILE_MAIN) strcpy(dir,"/"); +#endif + + /* to be sure */ + BLI_make_exist(sfile->dir); + + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); +} + +void swapselect_file(SpaceFile *sfile) +{ + struct direntry *file; + int num, act= 0; + + file= sfile->filelist; + for(num=0; num<sfile->totfile; num++, file++) { + if(file->flags & ACTIVE) { + act= 1; + break; + } + } + file= sfile->filelist+2; + for(num=2; num<sfile->totfile; num++, file++) { + if(act) file->flags &= ~ACTIVE; + else file->flags |= ACTIVE; + } +} + +static int find_active_file(SpaceFile *sfile, short x, short y) +{ + int ofs; + + if(y > textrct.ymax) y= textrct.ymax; + if(y <= textrct.ymin) y= textrct.ymin+1; + + ofs= (x-textrct.xmin)/collumwidth; + if(ofs<0) ofs= 0; + ofs*= (textrct.ymax-textrct.ymin); + + return sfile->ofs+ (ofs+textrct.ymax-y)/FILESEL_DY; + +} + + +/* ********************** DRAW ******************************* */ + +static void calc_file_rcts(SpaceFile *sfile) +{ + int tot, h, len; + float fac, start, totfile; + + scrollrct.xmin= 15; + scrollrct.xmax= 35; + scrollrct.ymin= 10; + scrollrct.ymax= curarea->winy-10-FILESELHEAD; + + textrct.xmin= scrollrct.xmax+10; + textrct.xmax= curarea->winx-10; + textrct.ymin= scrollrct.ymin; + textrct.ymax= scrollrct.ymax; + + if(textrct.xmax-textrct.xmin <60) textrct.xmax= textrct.xmin+60; + + len= (textrct.ymax-textrct.ymin) % FILESEL_DY; + textrct.ymin+= len; + scrollrct.ymin+= len; + + filebuty1= curarea->winy-FILESELHEAD; + filebuty2= filebuty1+FILESELHEAD/2 -6; + + + /* aantal kolommen */ + len= sfile->maxnamelen+25; + + if(sfile->type==FILE_MAIN) len+= 100; + else if(sfile->flag & FILE_SHOWSHORT) len+= 100; + else len+= 380; + + sfile->collums= (textrct.xmax-textrct.xmin)/len; + + if(sfile->collums<1) sfile->collums= 1; + else if(sfile->collums>8) sfile->collums= 8; + + if((U.flag & FSCOLLUM)==0) if(sfile->type!=FILE_MAIN) sfile->collums= 1; + + collumwidth= (textrct.xmax-textrct.xmin)/sfile->collums; + + + totfile= sfile->totfile + 0.5; + + tot= FILESEL_DY*totfile; + if(tot) fac= ((float)sfile->collums*(scrollrct.ymax-scrollrct.ymin))/( (float)tot); + else fac= 1.0; + + if(sfile->ofs<0) sfile->ofs= 0; + + if(tot) start= ( (float)sfile->ofs)/(totfile); + else start= 0.0; + if(fac>1.0) fac= 1.0; + + if(start+fac>1.0) { + sfile->ofs= ceil((1.0-fac)*totfile); + start= ( (float)sfile->ofs)/(totfile); + fac= 1.0-start; + } + + bar.xmin= scrollrct.xmin+2; + bar.xmax= scrollrct.xmax-2; + h= (scrollrct.ymax-scrollrct.ymin)-4; + bar.ymax= scrollrct.ymax-2- start*h; + bar.ymin= bar.ymax- fac*h; + + pixels_to_ofs= (totfile)/(float)(h+3); + page_ofs= fac*totfile; +} + +int filescrollselect= 0; + +static void draw_filescroll(SpaceFile *sfile) +{ + + if(scrollrct.ymin+10 >= scrollrct.ymax) return; + + cpack(0x707070); + glRecti(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax); + + uiEmboss(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax, 1); + + cpack(0x909090); + glRecti(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2); + + uiEmboss(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2, filescrollselect); + +} + +static void regelrect(unsigned int col, int x, int y) +{ + cpack(col); + glRects(x-17, y-3, x+collumwidth-21, y+11); + +} + +static void printregel(SpaceFile *sfile, struct direntry *files, int x, int y) +{ + unsigned int boxcol=0; + char *s; + + switch(files->flags & (HILITE + ACTIVE)) { + case HILITE+ACTIVE: + boxcol= (0xC09090); + break; + case HILITE: + boxcol= (0x909090); + break; + case ACTIVE: + boxcol= (0xB08080); + break; + } + + if(boxcol) { + regelrect(boxcol, x, y); + } + + if(files->flags & BLENDERFILE) { + cpack(0xA0A0); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & PSXFILE) { + cpack(0xA060B0); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & IMAGEFILE) { + cpack(0xF08040); + glRects(x-14, y, x-8, y+7); + } + else if(files->flags & MOVIEFILE) { + cpack(0x70A070); + glRects(x-14, y, x-8, y+7); + } + + if(S_ISDIR(files->type)) cpack(0xFFFFFF); + else cpack(0x0); + + s = files->string; + if(s) { + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->relname); + + x += sfile->maxnamelen + 100; + + glRasterPos2i(x - BMF_GetStringWidth(G.font, files->size), y); + BMF_DrawString(G.font, files->size); + + if(sfile->flag & FILE_SHOWSHORT) return; + +#ifndef WIN32 + /* rwx rwx rwx */ + x += 20; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode1); + + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode2); + + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->mode3); + + /* owner time date */ + x += 30; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->owner); +#endif + + x += 60; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->time); + + x += 50; glRasterPos2i(x, y); + BMF_DrawString(G.font, files->date); + } + else { + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->relname); + + if(files->nr) { /* extra info */ + x+= sfile->maxnamelen+20; + glRasterPos2i(x, y); + BMF_DrawString(G.font, files->extra); + } + } +} + + +static int calc_filesel_regel(SpaceFile *sfile, int nr, int *valx, int *valy) +{ + /* sco van de de regel */ + int val, coll; + + nr-= sfile->ofs; + + /* aantal regels in de hoogte */ + val= (textrct.ymax-textrct.ymin)/FILESEL_DY; + coll= nr/val; + nr -= coll*val; + + *valy= textrct.ymax-FILESEL_DY+3 - nr*FILESEL_DY; + *valx= coll*collumwidth + textrct.xmin+20; + + if(nr<0 || coll > sfile->collums) return 0; + return 1; +} + +static void set_active_file(SpaceFile *sfile, int act) +{ + struct direntry *file; + int num, redraw= 0, newflag; + int old=0, newi=0; + + file= sfile->filelist; + if(file==0) return; + + for(num=0; num<sfile->totfile; num++, file++) { + if(num==act) { + + if(selecting && num>1) { + newflag= HILITE | (file->flags & ~ACTIVE); + if(selecting==ACTIVATE) newflag |= ACTIVE; + + if(file->flags != newflag) redraw|= 1; + file->flags= newflag; + } + else { + if(file->flags & HILITE); + else { + file->flags |= HILITE; + redraw|= 2; + newi= num; + } + } + } + else { + if(file->flags & HILITE) { + file->flags &= ~HILITE; + redraw|= 2; + old= num; + } + } + + } + + if(redraw==2) { + int x, y; + + glDrawBuffer(GL_FRONT); + + glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx-12, curarea->winy); + + if( calc_filesel_regel(sfile, old, &x, &y) ) { + regelrect(0x717171, x, y); + printregel(sfile, sfile->filelist+old, x, y); + } + if( calc_filesel_regel(sfile, newi, &x, &y) ) { + printregel(sfile, sfile->filelist+newi, x, y); + } + + glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy); + + glFinish(); /* for geforce, to show it in the frontbuffer */ + glDrawBuffer(GL_BACK); + } + else if(redraw) { + scrarea_queue_winredraw(curarea); + } +} + + +static void draw_filetext(SpaceFile *sfile) +{ + struct direntry *files; + int a, x, y; + short mval[2]; + + if(textrct.ymin+10 >= textrct.ymax) return; + + + /* kader */ + cpack(0x717171); + glRecti(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax); + + /* kolommen */ + x= textrct.xmin+collumwidth; + for(a=1; a<sfile->collums; a++, x+= collumwidth) { + cpack(0x303030); + sdrawline(x, textrct.ymin, x, textrct.ymax); + cpack(0xB0B0B0); + sdrawline(x+1, textrct.ymin, x+1, textrct.ymax); + } + + if(sfile->filelist==0) return; + + /* test: als muis niet in area staat: de HILITE wissen */ + getmouseco_areawin(mval); + + if(mval[0]<0 || mval[0]>curarea->winx) { + files= sfile->filelist+sfile->ofs; + for(a= sfile->ofs; a<sfile->totfile; a++, files++) files->flags &= ~HILITE; + } + + files= sfile->filelist+sfile->ofs; + for(a= sfile->ofs; a<sfile->totfile; a++, files++) { + + if( calc_filesel_regel(sfile, a, &x, &y)==0 ) break; + + printregel(sfile, files, x, y); + } + + /* wissen tekenfoutjes, tekst teveel aan de rechterkant: */ + uiEmboss(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax, 1); + + glColor3f(.5625, .5625, .5625); + glRecti(textrct.xmax+2, textrct.ymin, textrct.xmax+10, textrct.ymax); +} + +void drawfilespace() +{ + SpaceFile *sfile; + uiBlock *block; + int act, loadbutton; + short mval[2]; + char name[20]; + char *menu; + + myortho2(-0.5, curarea->winrct.xmax-curarea->winrct.xmin-0.5, -0.5, curarea->winrct.ymax-curarea->winrct.ymin-0.5); + + glClearColor(.56, .56, .56, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + sfile= curarea->spacedata.first; + if(sfile->filelist==0) { + read_dir(sfile); + + calc_file_rcts(sfile); + + /* act berekenen */ + getmouseco_areawin(mval); + act= find_active_file(sfile, mval[0], mval[1]); + if(act>=0 && act<sfile->totfile) + sfile->filelist[act].flags |= HILITE; + } + else calc_file_rcts(sfile); + + /* HEADER */ + sprintf(name, "win %d", curarea->win); + block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSSF, UI_HELV, curarea->win); + + uiSetButLock( sfile->type==FILE_MAIN && sfile->returnfunc, NULL); + + /* space available for load/save buttons? */ + loadbutton= MAX2(80, 20+BMF_GetStringWidth(G.font, sfile->title)); + if(textrct.xmax-textrct.xmin > loadbutton+20) { + if(sfile->title[0]==0) loadbutton= 0; + } + else loadbutton= 0; + + uiDefBut(block, TEX, 1,"", textrct.xmin, filebuty1, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, TEX, 2,"", textrct.xmin, filebuty2, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + if(loadbutton) { + uiSetCurFont(block, UI_HELV); + uiDefBut(block, BUT, 5, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + uiDefBut(block, BUT, 6, "Cancel", textrct.xmax-loadbutton, filebuty1, loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, ""); + } + + menu= fsmenu_build_menu(); + uiDefButS(block, MENU, 3, menu, scrollrct.xmin, filebuty1, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, ""); + MEM_freeN(menu); + + uiDefBut(block, BUT, 4, "P", scrollrct.xmin, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)"); + + draw_filescroll(sfile); + draw_filetext(sfile); + + /* andere diskfree etc ? */ + scrarea_queue_headredraw(curarea); + + uiDrawBlock(block); + + curarea->win_swap= WIN_BACK_OK; +} + +static void do_filescroll(SpaceFile *sfile) +{ + short mval[2], oldy, yo; + + calc_file_rcts(sfile); + + filescrollselect= 1; + /* voor mooiigheid */ + + glDrawBuffer(GL_FRONT); + draw_filescroll(sfile); + glDrawBuffer(GL_BACK); + + getmouseco_areawin(mval); + oldy= yo= mval[1]; + + while(get_mbut()&L_MOUSE) { + getmouseco_areawin(mval); + + if(yo!=mval[1]) { + int dy= floor(0.5+((float)(oldy-mval[1]))*pixels_to_ofs); + + if(dy) { + sfile->ofs+= dy; + if(sfile->ofs<0) { + sfile->ofs= 0; + oldy= mval[1]; + } + else oldy= floor(0.5+ (float)oldy - (float)dy/pixels_to_ofs); + + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + } + + yo= mval[1]; + } + else BIF_wait_for_statechange(); + } + filescrollselect= 0; + + /* voor mooiigheid */ + glDrawBuffer(GL_FRONT); + draw_filescroll(sfile); + glDrawBuffer(GL_BACK); + +} + +void activate_fileselect(int type, char *title, char *file, void (*func)(char *)) +{ + SpaceFile *sfile; + char group[24], name[FILE_MAXDIR], temp[FILE_MAXDIR]; + + if(curarea==0) return; + if(curarea->win==0) return; + + newspace(curarea, SPACE_FILE); + scrarea_queue_winredraw(curarea); + + /* is misschien dubbelop, voor geval area al SPACE_FILE is met andere filename */ + addqueue(curarea->headwin, CHANGED, 1); + + + name[2]= 0; + strcpy(name, file); + + sfile= curarea->spacedata.first; + /* sfile wants a (*)(short), but get (*)(char*) */ + sfile->returnfunc= func; + sfile->type= type; + sfile->ofs= 0; + /* sfile->act wordt gebruikt bij databrowse: dubbele namen van library objecten */ + sfile->act= -1; + + if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) sfile->flag |= FILE_STRINGCODE; + else sfile->flag &= ~FILE_STRINGCODE; + + if(type==FILE_MAIN) { + char *groupname; + + strcpy(sfile->file, name+2); + + groupname = BLO_idcode_to_name( GS(name) ); + if (groupname) { + strcpy(sfile->dir, groupname); + strcat(sfile->dir, "/"); + } + + /* alles vrijgeven */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + + freefilelist(sfile); + } + else if(type==FILE_LOADLIB) { + strcpy(sfile->dir, name); + if( is_a_library(sfile, temp, group) ) { + /* dit geval is om een reload van library-filelist te veroorzaken */ + if(sfile->libfiledata==0) { + freefilelist(sfile); + } + } + else { + split_sfile(sfile, name); + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + } + } + else { /* FILE_BLENDER */ + split_sfile(sfile, name); /* test ook de filelist */ + + /* vrijgeven: filelist en libfiledata kloppen niet meer */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + } + BLI_strncpy(sfile->title, title, sizeof(sfile->title)); + filetoname= 1; +} + +void activate_imageselect(int type, char *title, char *file, void (*func)(char *)) +{ + SpaceImaSel *simasel; + char dir[FILE_MAXDIR], name[FILE_MAXFILE]; + + if(curarea==0) return; + if(curarea->win==0) return; + + newspace(curarea, SPACE_IMASEL); + + /* is misschien dubbelop, voor geval area al SPACE_FILE is met andere filename */ + addqueue(curarea->headwin, CHANGED, 1); + addqueue(curarea->win, CHANGED, 1); + + name[2]= 0; + strcpy(name, file); + + simasel= curarea->spacedata.first; + simasel->returnfunc= func; + + if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE; + else simasel->mode &= ~IMS_STRINGCODE; + + BLI_split_dirfile(name, dir, simasel->file); + if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0; + strcpy(simasel->dir, dir); + + BLI_strncpy(simasel->title, title, sizeof(simasel->title)); + + + + /* filetoname= 1; */ +} + + +void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short)) +{ + ListBase *lb; + SpaceFile *sfile; + char str[32]; + + if(id==0) { + lb= wich_libbase(G.main, idcode); + id= lb->first; + } + + if(id) strcpy(str, id->name); + else return; + + activate_fileselect(FILE_MAIN, "SELECT DATABLOCK", str, (void (*) (char*))func); + + sfile= curarea->spacedata.first; + sfile->retval= retval; + sfile->ipotype= fromcode; + sfile->menup= menup; +} + +void filesel_prevspace() +{ + SpaceFile *sfile; + + sfile= curarea->spacedata.first; + if(sfile->next) { + + BLI_remlink(&curarea->spacedata, sfile); + BLI_addtail(&curarea->spacedata, sfile); + + sfile= curarea->spacedata.first; + newspace(curarea, sfile->spacetype); + } + else newspace(curarea, SPACE_INFO); +} + +static int countselect(SpaceFile *sfile) +{ + int a, count=0; + + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + count++; + } + } + return count; +} + +static int getotherdir(void) +{ + ScrArea *sa; + SpaceFile *sfile=0; + + sa= G.curscreen->areabase.first; + while(sa) { + if(sa!=curarea) { + if(sa->spacetype==SPACE_FILE) { + + /* al een gevonden */ + if(sfile) return 0; + + sfile= sa->spacedata.first; + + if(sfile->type & FILE_UNIX) { + otherarea= sa; + BLI_make_file_string(G.sce, otherdir, sfile->dir, ""); + } + else sfile= 0; + } + } + sa= sa->next; + } + if(sfile) return 1; + return 0; +} + +static void reread_other_fs(void) +{ + SpaceFile *sfile; + + /* oppassen: alleen aanroepen als getotherdir goed is afgelopen */ + + sfile= otherarea->spacedata.first; + freefilelist(sfile); + scrarea_queue_winredraw(otherarea); +} + + +void free_filesel_spec(char *dir) +{ + /* alle filesels met 'dir' worden vrijgegeven */ + bScreen *sc; + + sc= G.main->screen.first; + while(sc) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_FILE) { + SpaceFile *sfile= (SpaceFile*) sl; + if (BLI_streq(sfile->dir, dir)) { + freefilelist(sfile); + } + } + sl= sl->next; + } + sa= sa->next; + } + sc= sc->id.next; + } +} + + +static void filesel_execute(SpaceFile *sfile) +{ + struct direntry *files; + char name[FILE_MAXDIR]; + int a; + + filesel_prevspace(); + + if(sfile->type==FILE_LOADLIB) { + do_library_append(sfile); + + allqueue(REDRAWALL, 1); + } + else if(sfile->returnfunc) { + fsmenu_insert_entry(sfile->dir, 1); + + if(sfile->type==FILE_MAIN) { + if (sfile->menup) { + if(sfile->act>=0) { + if(sfile->filelist) { + files= sfile->filelist+sfile->act; + *sfile->menup= files->nr; + } + else *sfile->menup= sfile->act+1; + } + else { + *sfile->menup= -1; + for(a=0; a<sfile->totfile; a++) { + if( strcmp(sfile->filelist[a].relname, sfile->file)==0) { + *sfile->menup= a+1; + break; + } + } + } + } + sfile->returnfunc((char*) sfile->retval); + } + else { + if(strncmp(sfile->title, "SAVE", 4)==0) free_filesel_spec(sfile->dir); + + strcpy(name, sfile->dir); + strcat(name, sfile->file); + + if(sfile->flag & FILE_STRINGCODE) BLI_makestringcode(G.sce, name); + + sfile->returnfunc(name); + } + } +} + +static void do_filesel_buttons(short event, SpaceFile *sfile) +{ + char butname[FILE_MAXDIR]; + + if (event == 1) { + if (strchr(sfile->file, '*') || strchr(sfile->file, '?') || strchr(sfile->file, '[')) { + int i, match = FALSE; + + for (i = 2; i < sfile->totfile; i++) { + if (fnmatch(sfile->file, sfile->filelist[i].relname, 0) == 0) { + sfile->filelist[i].flags |= ACTIVE; + match = TRUE; + } + } + if (match) strcpy(sfile->file, ""); + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + scrarea_queue_winredraw(curarea); + } + } + else if(event== 2) { + /* reuse the butname variable */ + checkdir(sfile->dir); + + BLI_make_file_string(G.sce, butname, sfile->dir, ""); + /* strip the trailing slash if its a real dir */ + if (strlen(butname)!=1) + butname[strlen(butname)-1]=0; + + if(sfile->type & FILE_UNIX) { + if (!BLI_exists(butname)) { + if (okee("Makedir")) { + BLI_recurdir_fileops(butname); + if (!BLI_exists(butname)) parent(sfile); + } else parent(sfile); + } + } + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); + } + else if(event== 3) { + char *selected= fsmenu_get_entry(sfile->menu-1); + + /* welke string */ + if (selected) { + strcpy(sfile->dir, selected); + BLI_make_exist(sfile->dir); + checkdir(sfile->dir); + freefilelist(sfile); + sfile->ofs= 0; + scrarea_queue_winredraw(curarea); + } + + sfile->act= -1; + + } + else if(event== 4) parent(sfile); + else if(event== 5) { + if(sfile->type) filesel_execute(sfile); + } + else if(event== 6) filesel_prevspace(); + +} + +/****/ + +typedef void (*ReplaceFP)(ID *oldblock, ID *newblock); + +static void change_id_link(void *linkpv, void *newlinkv) { + ID **linkp= (ID**) linkpv; + ID *newlink= newlinkv; + + if (*linkp) { + (*linkp)->us--; + } + (*linkp)= newlink; + if (newlink) { + id_us_plus(newlink); + } +} + +static void replace_image(ID *oldblock, ID *newblock) { + Image *oldima= (Image*) oldblock; + Image *newima= (Image*) newblock; + bScreen *sc; + Scene *sce; + Tex *tex; + Mesh *me; + + for (tex= G.main->tex.first; tex; tex= tex->id.next) { + if (tex->env && tex->env->type == ENV_LOAD && tex->env->ima == oldima) + change_id_link(&tex->env->ima, newima); + if (tex->ima == oldima) + change_id_link(&tex->ima, newima); + } + + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->ima == oldima) + change_id_link(&sce->ima, newima); + } + + for (sc= G.main->screen.first; sc; sc= sc->id.next) { + ScrArea *sa; + + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + BGpic *bgp= v3d->bgpic; + + if (bgp && bgp->ima == oldima) + change_id_link(&bgp->ima, newima); + } else if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage*) sl; + + if (sima->image == oldima) + change_id_link(&sima->image, newima); + } + } + } + } + + for (me= G.main->mesh.first; me; me= me->id.next) { + TFace *tfaces= me->tface; + + if (tfaces) { + int i; + + for (i=0; i<me->totface; i++) { + TFace *tf= &tfaces[i]; + + if (tf->tpage == oldima) { + /* not change_id_link, tpage's aren't owners :( + * see hack below. + */ + tf->tpage= newima; + } + } + } + } + + /* Nasty hack, necessary because tpages don't act + * as a user, so there lots of image user count + * munging occurs... this will ensure the image + * really dies. + */ + oldima->id.us= 0; +} + +static void replace_material(ID *oldblock, ID *newblock) +{ + Material *old= (Material*) oldblock; + Material *new= (Material*) newblock; + Material ***matarar; + ID *id; + Object *ob; + int a; + + ob= G.main->object.first; + while(ob) { + if(ob->totcol && ob->id.lib==0) { + matarar= give_matarar(ob); + for(a=1; a<=ob->totcol; a++) { + if(ob->mat[a-1] == old) { + if(old) old->id.us--; + id_us_plus((ID *)new); + ob->mat[a-1]= new; + } + id= ob->data; + if( (*matarar)[a-1] == old && id->lib==0) { + if(old) old->id.us--; + id_us_plus((ID *)new); + (*matarar)[a-1]= new; + } + } + } + ob= ob->id.next; + } +} + +static ReplaceFP get_id_replace_function(int idcode) { + switch (idcode) { + case ID_MA: + return &replace_material; + case ID_IM: + return &replace_image; + default: + return NULL; + } +} + +static void databrowse_replace(SpaceFile *sfile, int idcode) +{ + ReplaceFP replace_func= get_id_replace_function(idcode); + + if (!replace_func) { + error("Replacing %s blocks is unsupported", BLO_idcode_to_name(idcode)); + } else if (sfile->act==-1) { + error("Select target with leftmouse"); + } else { + ID *target= (ID*) sfile->filelist[sfile->act].poin; + + if (target) { + char buf[128]; + + sprintf(buf, "Replace with %s: %s", BLO_idcode_to_name(idcode), target->name+2); + + if (okee(buf)) { + int i; + + for (i = 0; i <sfile->totfile; i++) + if ((sfile->filelist[i].flags&ACTIVE) && sfile->filelist[i].poin!=target) + replace_func(sfile->filelist[i].poin, target); + } + } + } + + freefilelist(sfile); + scrarea_queue_winredraw(curarea); +} + +static void fs_fake_users(SpaceFile *sfile) +{ + ID *id; + int a; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + for(a=0; a<sfile->totfile; a++) { + if(sfile->filelist[a].flags & ACTIVE) { + id= (ID *)sfile->filelist[a].poin; + if(id) { + if( id->flag & LIB_FAKEUSER) { + id->flag -= LIB_FAKEUSER; + id->us--; + } + else { + id->flag |= LIB_FAKEUSER; + id->us++; + } + } + } + } + freefilelist(sfile); + scrarea_queue_winredraw(curarea); +} + +void winqreadfilespace(unsigned short event, short val, char ascii) +{ + static int acto=0; + SpaceFile *sfile; + int act, do_draw= 0, i, test, ret = 0; + short qual, mval[2]; + char str[FILE_MAXDIR+FILE_MAXFILE+12]; + + sfile= curarea->spacedata.first; + if(sfile==0) return; + if(sfile->filelist==0) { + /* wel buttons doen */ + if(val && event==LEFTMOUSE) { + /* FrontbufferButs(TRUE); */ + /* event= DoButtons(); */ + /* FrontbufferButs(FALSE); */ + /* NIET de headerbuttons! */ + /* if(event) do_filesel_buttons(event, sfile); */ + } + return; + } + + if(curarea->win==0) return; + calc_file_rcts(sfile); + getmouseco_areawin(mval); + + /* om hangen te voorkomen */ + if(selecting && !(get_mbut() & R_MOUSE)) selecting= 0; + + if(val) { + + if( event!=RETKEY && event!=PADENTER) + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { + + case UI_BUT_EVENT: + do_filesel_buttons(val, sfile); + break; + + case LEFTMOUSE: + case MIDDLEMOUSE: + if(mval[0]>scrollrct.xmin && mval[0]<scrollrct.xmax && mval[1]>scrollrct.ymin && mval[1]<scrollrct.ymax) { + do_filescroll(sfile); + } + else if(mval[0]>textrct.xmin && mval[0]<textrct.xmax && mval[1]>textrct.ymin && mval[1]<textrct.ymax) { + + /* sfile->act wordt gebruikt bij databrowse: dubbelenamen van library objecten */ + + sfile->act= act= find_active_file(sfile, mval[0], mval[1]); + + if(act>=0 && act<sfile->totfile) { + if(S_ISDIR(sfile->filelist[act].type)) { + strcat(sfile->dir, sfile->filelist[act].relname); + strcat(sfile->dir,"/"); + checkdir(sfile->dir); + freefilelist(sfile); + sfile->ofs= 0; + do_draw= 1; + } + else { + if( strcmp(sfile->file, sfile->filelist[act].relname)) { + do_draw= 1; + strcpy(sfile->file, sfile->filelist[act].relname); + } + if(event==MIDDLEMOUSE && sfile->type) filesel_execute(sfile); + } + } + } + else { + /* FrontbufferButs(TRUE); */ + /* event= DoButtons(); */ + /* FrontbufferButs(FALSE); */ + /* NIET de headerbuttons! */ + /* if(event) do_filesel_buttons(event, sfile); */ + } + break; + case RIGHTMOUSE: + act= find_active_file(sfile, mval[0], mval[1]); + acto= act; + if(act>=0 && act<sfile->totfile) { + + if (sfile->filelist[act].flags & ACTIVE) { + sfile->filelist[act].flags &= ~ACTIVE; + selecting = INACTIVATE; + } + else { + test= sfile->filelist[act].relname[0]; + if (act>=2 || test!='.') sfile->filelist[act].flags |= ACTIVE; + + selecting = ACTIVATE; + } + do_draw= 1; + } + break; + case MOUSEY: + act= find_active_file(sfile, mval[0], mval[1]); + if (act!=acto) { + set_active_file(sfile, act); + } + if(selecting && act!=acto) { + + while(1) { + if (acto >= 2 && acto < sfile->totfile) { + if (selecting == ACTIVATE) sfile->filelist[acto].flags |= ACTIVE; + else if (selecting == INACTIVATE) sfile->filelist[acto].flags &= ~ACTIVE; + } + if (acto < act) acto++; + else if (acto > act) acto--; + else break; + + } + + } + acto= act; + break; + + case PAGEUPKEY: + sfile->ofs-= page_ofs; + do_draw= 1; + break; + case PAGEDOWNKEY: + sfile->ofs+= page_ofs; + do_draw= 1; + break; + case HOMEKEY: + sfile->ofs= 0; + do_draw= 1; + break; + case ENDKEY: + sfile->ofs= sfile->totfile; + do_draw= 1; + break; + + case AKEY: + swapselect_file(sfile); + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + do_draw= 1; + break; + + case BKEY: + case CKEY: + case LKEY: + if(event==LKEY && sfile->type==FILE_MAIN && (G.qual & LR_CTRLKEY)) { + databrowse_replace(sfile, groupname_to_code(sfile->dir)); + break; + } + /* doorgeven */ + case MKEY: + if(sfile->type==FILE_MAIN) break; + + if(!countselect(sfile)) { + error("No files selected"); + break; + } + + if(!getotherdir()) { + error("No second fileselect"); + break; + } + + if (!strcmp(sfile->dir, otherdir)) { + error("Same directories"); + break; + } + + if(event==BKEY) sprintf(str, "Backup to %s", otherdir); + else if(event==CKEY) sprintf(str, "Copy to %s", otherdir); + else if(event==LKEY) sprintf(str, "Linked copy to %s", otherdir); + else if(event==MKEY) sprintf(str, "Move to %s", otherdir); + + if (!okee(str)) break; + + for (i = 0; i<sfile->totfile; i++){ + if (sfile->filelist[i].flags & ACTIVE) { + BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname); + + if(event==BKEY) ret= BLI_backup(sfile->filelist[i].relname, sfile->dir, otherdir); + else if(event==CKEY) ret= BLI_copy_fileops(str, otherdir); + else if(event==LKEY) ret= BLI_link(str, otherdir); + else if(event==MKEY) ret= BLI_move(str, otherdir); + + if (ret) {error("Command failed, see console"); break;} + else sfile->filelist[i].flags &= ~ACTIVE; + } + } + do_draw= 1; + if(event==BKEY || event==MKEY) + freefilelist(sfile); + + reread_other_fs(); + + break; + case RKEY: + if(sfile->type==FILE_MAIN) { + databrowse_replace(sfile, groupname_to_code(sfile->dir)); + break; + } + /* doorgeven aan TKEY! */ + + case TKEY: + if(sfile->type==FILE_MAIN) break; + + if(!countselect(sfile)) { + error("No files selected"); + break; + } + + if(event==TKEY) sprintf(str, "Touch"); + else if(event==RKEY) sprintf(str, "Remove from %s", sfile->dir); + + qual= G.qual; /* want na okee() heb je de shift losgelaten */ + if (!okee(str)) break; + + for (i = 0; i <sfile->totfile; i++) { + if (sfile->filelist[i].flags & ACTIVE) { + BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname); + + if(event==TKEY) ret= BLI_touch(str); + else if(event==RKEY) { + if(qual & LR_SHIFTKEY) ret= BLI_delete(str, 0, 1); + else if(S_ISDIR(sfile->filelist[i].type)) ret= BLI_delete(str, 1, 0); + else ret= BLI_delete(str, 0, 0); + } + + if (ret) {error("Command failed, see console"); break;} + else sfile->filelist[i].flags &= ~ACTIVE; + } + } + do_draw= 1; + freefilelist(sfile); + + break; + + case PKEY: + if(G.qual & LR_SHIFTKEY) { + extern char bprogname[]; /* usiblender.c */ + + sprintf(str, "%s -a \"%s%s\"", bprogname, sfile->dir, sfile->file); + system(str); + } + else + parent(sfile); + + break; + + case IKEY: + if(sfile->type==FILE_MAIN) break; + + sprintf(str, "$IMAGEEDITOR %s%s", sfile->dir, sfile->file); + system(str); + break; + + case EKEY: + if(sfile->type==FILE_MAIN) break; + + sprintf(str, "$WINEDITOR %s%s", sfile->dir, sfile->file); + system(str); + break; + + case FKEY: + if(sfile->type==FILE_MAIN) { + fs_fake_users(sfile); + } + break; + + case PADPLUSKEY: + case EQUALKEY: + if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, +100); + else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, +10); + else BLI_newname(sfile->file, +1); + + do_draw= 1; + break; + + case PADMINUS: + case MINUSKEY: + if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, -100); + else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, -10); + else BLI_newname(sfile->file, -1); + + do_draw= 1; + break; + + case BACKSLASHKEY: + case SLASHKEY: + if(sfile->type==FILE_MAIN) break; + +#ifdef WIN32 + strcpy(sfile->dir, "\\"); +#else + strcpy(sfile->dir, "/"); +#endif + freefilelist(sfile); + sfile->ofs= 0; + do_draw= 1; + break; + case PERIODKEY: + freefilelist(sfile); + do_draw= 1; + break; + case ESCKEY: + filesel_prevspace(); + break; + case PADENTER: + case RETKEY: + if(sfile->type) filesel_execute(sfile); + break; + } + } + else if(event==RIGHTMOUSE) { + selecting = NOTACTIVE; + if(sfile->type==FILE_MAIN) filesel_select_objects(sfile); + } + else if(event==LEFTMOUSE) { + if(sfile->type==FILE_MAIN) active_file_object(sfile); + } + + /* XXX, stupid patch, curarea can become undone + * because of file loading... fixme zr + */ + if(do_draw && curarea) scrarea_queue_winredraw(curarea); +} + + + + +/* ************* LIBRARY FILESEL ******************* */ + +static int groupname_to_code(char *group) +{ + char buf[32]; + char *lslash; + + strcpy(buf, group); + lslash= BLI_last_slash(buf); + if (lslash) + lslash[0]= '\0'; + + return BLO_idcode_from_name(buf); +} + +static int is_a_library(SpaceFile *sfile, char *dir, char *group) +{ + /* return ok als een blenderfile, in dir staat de filename, + * in group het type libdata + */ + int len; + char *fd; + + strcpy(dir, sfile->dir); + 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)) { + *fd= '/'; + } + else { + strcpy(group, fd+1); + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + if (!fd || !BLO_has_bfile_extension(fd+1)) return 0; + } + return 1; +} + +static void do_library_append(SpaceFile *sfile) +{ + char dir[FILE_MAXDIR], group[32]; + + if ( is_a_library(sfile, dir, group)==0 ) { + error("Not a library"); + } else if (!sfile->libfiledata) { + error("Library not loaded"); + } else if (group[0]==0) { + error("Nothing indicated"); + } else if (BLI_streq(G.main->name, dir)) { + error("Cannot use current file as library"); + } else { + Object *ob; + int idcode = groupname_to_code(group); + + BLO_library_append(sfile, dir, idcode); + + /* DISPLISTEN */ + ob= G.main->object.first; + set_displist_onlyzero(1); + while(ob) { + if(ob->id.lib) { + if(ob->type==OB_FONT) { + Curve *cu= ob->data; + if(cu->nurb.first==0) text_to_curve(ob, 0); + } + makeDispList(ob); + } + else if(ob->type==OB_MESH && ob->parent && ob->parent->type==OB_LATTICE ) { + makeDispList(ob); + } + + ob= ob->id.next; + } + set_displist_onlyzero(0); + + /* in sfile->dir staat de HELE libnaam */ + strcpy(G.lib, sfile->dir); + + if((sfile->flag & FILE_LINK)==0) all_local(); + } +} + +static void library_to_filelist(SpaceFile *sfile) +{ + char dir[FILE_MAXDIR], group[24]; + int ok, i, nnames, idcode; + LinkNode *l, *names; + + /* name testen */ + ok= is_a_library(sfile, dir, group); + if (!ok) { + /* vrijgeven */ + if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); + sfile->libfiledata= 0; + return; + } + + /* en daar gaat ie */ + /* voorlopig alleen filedata inlezen als libfiledata==0 */ + if (sfile->libfiledata==0) { + sfile->libfiledata= BLO_blendhandle_from_file(dir); + if(sfile->libfiledata==0) return; + } + + if (idcode= groupname_to_code(group)) { + names= BLO_blendhandle_get_datablock_names(sfile->libfiledata, idcode); + } else { + names= BLO_blendhandle_get_linkable_groups(sfile->libfiledata); + } + + nnames= BLI_linklist_length(names); + + sfile->totfile= nnames + 2; + sfile->filelist= malloc(sfile->totfile * sizeof(*sfile->filelist)); + memset(sfile->filelist, 0, sfile->totfile * sizeof(*sfile->filelist)); + + sfile->filelist[0].relname= strdup("."); + sfile->filelist[0].type |= S_IFDIR; + sfile->filelist[1].relname= strdup(".."); + sfile->filelist[1].type |= S_IFDIR; + + for (i=0, l= names; i<nnames; i++, l= l->next) { + char *blockname= l->link; + + sfile->filelist[i + 2].relname= blockname; + if (!idcode) + sfile->filelist[i + 2].type |= S_IFDIR; + } + + BLI_linklist_free(names, NULL); + + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + + sfile->maxnamelen= 0; + for(i=0; i<sfile->totfile; i++) { + int len = BMF_GetStringWidth(G.font, sfile->filelist[i].relname); + if (len > sfile->maxnamelen) + sfile->maxnamelen = len; + } +} + +/* ******************* DATA SELECT ********************* */ + +static void filesel_select_objects(SpaceFile *sfile) +{ + Object *ob; + Base *base; + Scene *sce; + int a; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + if( strcmp(sfile->dir, "Object/")==0 ) { + for(a=0; a<sfile->totfile; a++) { + + ob= (Object *)sfile->filelist[a].poin; + + if(ob) { + if(sfile->filelist[a].flags & ACTIVE) ob->flag |= SELECT; + else ob->flag &= ~SELECT; + } + + } + base= FIRSTBASE; + while(base) { + base->flag= base->object->flag; + base= base->next; + } + allqueue(REDRAWVIEW3D, 0); + } + else if( strcmp(sfile->dir, "Scene/")==0 ) { + + for(a=0; a<sfile->totfile; a++) { + + sce= (Scene *)sfile->filelist[a].poin; + if(sce) { + if(sfile->filelist[a].flags & ACTIVE) sce->r.scemode |= R_BG_RENDER; + else sce->r.scemode &= ~R_BG_RENDER; + } + + } + allqueue(REDRAWBUTSRENDER, 0); + } +} + +static void active_file_object(SpaceFile *sfile) +{ + Object *ob; + + /* alleen bij F4 DATABROWSE */ + if(sfile->returnfunc) return; + + if( strcmp(sfile->dir, "Object/")==0 ) { + if(sfile->act >= 0) { + + ob= (Object *)sfile->filelist[sfile->act].poin; + + if(ob) { + set_active_object(ob); + if(BASACT && BASACT->object==ob) { + BASACT->flag |= SELECT; + sfile->filelist[sfile->act].flags |= ACTIVE; + allqueue(REDRAWVIEW3D, 0); + scrarea_queue_winredraw(curarea); + } + } + } + } +} + + +void main_to_filelist(SpaceFile *sfile) +{ + ID *id; + struct direntry *files, *firstlib = NULL; + ListBase *lb; + int a, fake, idcode, len, ok, totlib, totbl; + + if(sfile->dir[0]=='/') sfile->dir[0]= 0; + + if(sfile->dir[0]) { + idcode= groupname_to_code(sfile->dir); + if(idcode==0) sfile->dir[0]= 0; + } + + if( sfile->dir[0]==0) { + + /* directories maken */ + sfile->totfile= 22; + sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); + + for(a=0; a<sfile->totfile; a++) { + memset( &(sfile->filelist[a]), 0 , sizeof(struct direntry)); + sfile->filelist[a].type |= S_IFDIR; + } + + sfile->filelist[0].relname= strdup(".."); + sfile->filelist[1].relname= strdup("."); + sfile->filelist[2].relname= strdup("Scene"); + sfile->filelist[3].relname= strdup("Object"); + sfile->filelist[4].relname= strdup("Mesh"); + sfile->filelist[5].relname= strdup("Curve"); + sfile->filelist[6].relname= strdup("Metaball"); + sfile->filelist[7].relname= strdup("Material"); + sfile->filelist[8].relname= strdup("Texture"); + sfile->filelist[9].relname= strdup("Image"); + sfile->filelist[10].relname= strdup("Ika"); + sfile->filelist[11].relname= strdup("Wave"); + sfile->filelist[12].relname= strdup("Lattice"); + sfile->filelist[13].relname= strdup("Lamp"); + sfile->filelist[14].relname= strdup("Camera"); + sfile->filelist[15].relname= strdup("Ipo"); + sfile->filelist[16].relname= strdup("World"); + sfile->filelist[17].relname= strdup("Screen"); + sfile->filelist[18].relname= strdup("VFont"); + sfile->filelist[19].relname= strdup("Text"); + sfile->filelist[20].relname= strdup("Armature"); + sfile->filelist[21].relname= strdup("Action"); + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); + } + else { + + /* files maken */ + idcode= groupname_to_code(sfile->dir); + + lb= wich_libbase(G.main, idcode ); + if(lb==0) return; + + id= lb->first; + sfile->totfile= 0; + while(id) { + + if(sfile->returnfunc && idcode==ID_IP) { + if(sfile->ipotype== ((Ipo *)id)->blocktype) sfile->totfile++; + } + else sfile->totfile++; + + id= id->next; + } + + if(sfile->returnfunc==0) sfile->totfile+= 2; + sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); + + files= sfile->filelist; + + if(sfile->returnfunc==0) { + memset( &(sfile->filelist[0]), 0 , sizeof(struct direntry)); + sfile->filelist[0].relname= strdup("."); + sfile->filelist[0].type |= S_IFDIR; + memset( &(sfile->filelist[1]), 0 , sizeof(struct direntry)); + sfile->filelist[1].relname= strdup(".."); + sfile->filelist[1].type |= S_IFDIR; + + files+= 2; + } + + id= lb->first; + totlib= totbl= 0; + + while(id) { + + ok= 0; + if(sfile->returnfunc && idcode==ID_IP) { + if(sfile->ipotype== ((Ipo *)id)->blocktype) ok= 1; + } + else ok= 1; + + if(ok) { + + memset( files, 0 , sizeof(struct direntry)); + files->relname= strdup(id->name+2); + + if(sfile->returnfunc==0) { /* 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; + } + } + files->nr= totbl+1; + files->poin= id; + fake= id->flag & LIB_FAKEUSER; + + 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; + } + + /* alleen qsort van libraryblokken */ + if(totlib>1) { + qsort(firstlib, totlib, sizeof(struct direntry), compare_name); + } + } + + sfile->maxnamelen= 0; + for(a=0; a<sfile->totfile; a++) { + len = BMF_GetStringWidth(G.font, sfile->filelist[a].relname); + if (len > sfile->maxnamelen) sfile->maxnamelen = len; + + if(filetoname) { + if( strcmp(sfile->file, sfile->filelist[a].relname)==0) { + sfile->ofs= a-( sfile->collums*(curarea->winy-FILESELHEAD-10)/(2*FILESEL_DY)); + filetoname= 0; + if(sfile->returnfunc) sfile->filelist[a].flags |= ACTIVE; + } + } + } +} + + + |