#ifdef HAVE_CONFIG_H #include <config.h> #endif Just need to finish cpp files now :) Kent -- mein@cs.umn.edu
2381 lines
53 KiB
C
2381 lines
53 KiB
C
/**
|
|
* $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 HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|