Fixes for:

[ #4337 ] Cant refresh the C:\
[ #4710 ] Wrong paths in file selector under user prefs
[ #4353 ] Using ^ char + click on Open/Load = Blender crash

Details:

Fixes for root paths like C:\ on Windows, where Blender still used '/'.

Also contains fixes for relative paths:
- no relative paths for the default dirs (forced to absolute)
- message if using relative paths when .blend file hasn't been saved.

Lastly also added '.' for refresh in root paths. Windows
FindFirstFile/FindNextFile also return '.' and '..', but not in root paths like C:\
This commit is contained in:
2006-08-20 14:41:13 +00:00
parent 8dd3a792f0
commit ffe630b452
9 changed files with 167 additions and 48 deletions

View File

@@ -88,6 +88,9 @@ typedef struct Global {
/* strings: lastsaved */
char ima[160], sce[160], lib[160];
/* flag: if != 0 G.sce contains valid relative base path */
int relbase_valid;
/* strings of recent opend files */
struct ListBase recent_files;

View File

@@ -94,7 +94,7 @@ char *BLI_gethome(void);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
void BLI_make_exist(char *dir);
void BLI_make_existing_file(char *name);
void BLI_split_dirfile(char *string, char *dir, char *file);
void BLI_split_dirfile(const char *string, char *dir, char *file);
int BLI_testextensie(char *str, char *ext);
void addlisttolist(ListBase *list1, ListBase *list2);
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);

View File

@@ -113,6 +113,7 @@ void RegisterBlendExtension(char * str);
DIR *opendir (const char *path);
struct dirent *readdir(DIR *dp);
int closedir (DIR *dp);
void get_default_root(char* root);
#endif /* __WINSTUFF_H__ */

View File

@@ -277,6 +277,14 @@ void BLI_builddir(char *dirname, char *relname)
BLI_addhead(dirbase,dlink);
newnum++;
}
#else // WIN32
if (seen_ == 0) { /* should only happen for root paths like "C:\" */
dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
strcpy(buf+rellen,".");
dlink->name = BLI_strdup(buf);
BLI_addhead(dirbase,dlink);
newnum++;
}
#endif
if (files) files=(struct direntry *)realloc(files,(totnum+newnum) * sizeof(struct direntry));

View File

@@ -449,8 +449,7 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
#ifdef WIN32
if(dir[0]=='.') { /* happens for example in FILE_MAIN */
dir[0]= '\\';
dir[1]= 0;
get_default_root(dir);
return;
}
@@ -534,6 +533,9 @@ void BLI_makestringcode(const char *relfile, char *file)
/* if file is already relative, bail out */
if(file[0]=='/' && file[1]=='/') return;
/* also bail out if relative path is not set */
if (relfile[0] == 0) return;
strcpy(temp, relfile);
#ifdef WIN32
@@ -596,7 +598,24 @@ int BLI_convertstringcode(char *path, const char *basepath, int framenum)
char tmp[FILE_MAXDIR+FILE_MAXFILE];
char base[FILE_MAXDIR];
wasrelative= (strncmp(path, "//", 2)==0);
#ifdef WIN32
if (!wasrelative && path[1] != ':') {
get_default_root(tmp);
// get rid of the slashes at the beginning of the path
while (*path == '\\' || *path == '/') {
path++;
}
strcat(tmp, path);
}
else {
strcpy(tmp, path);
}
#else
strcpy(tmp, path);
#endif
strcpy(base, basepath);
/* push slashes into unix mode - strings entering this part are
@@ -606,9 +625,7 @@ int BLI_convertstringcode(char *path, const char *basepath, int framenum)
of paths and solving some problems (and prevent potential future
ones) -jesterKing. */
BLI_char_switch(tmp, '\\', '/');
BLI_char_switch(base, '\\', '/');
wasrelative= (strncmp(tmp, "//", 2)==0);
BLI_char_switch(base, '\\', '/');
if (tmp[0] == '/' && tmp[1] == '/') {
char *filepart= BLI_strdup(tmp+2); /* skip code */
@@ -761,7 +778,8 @@ void BLI_make_exist(char *dir) {
}
if (a >= 0) dir[a+1] = 0;
else {
strcpy(dir,"\\");
/* defaulting to first valid drive hoping it's not empty CD and DVD drives */
get_default_root(dir);
break;
}
}
@@ -825,7 +843,29 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
dir+=2; /* Skip over the relative reference */
}
#ifdef WIN32
else {
if (strlen(dir) >= 2 && dir[1] == ':' ) {
BLI_strncpy(string, dir, 3);
dir += 2;
}
else { /* no drive specified */
/* first option: get the drive from the relabase if it has one */
if (relabase && strlen(relabase) >= 2 && relabase[1] == ':' ) {
BLI_strncpy(string, relabase, 3);
string[2] = '\\';
string[3] = '\0';
}
else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
get_default_root(string);
}
/* ignore leading slashes */
while (*dir == '/' || *dir == '\\') dir++;
}
}
#endif
strcat(string, dir);
/* Make sure string ends in one (and only one) slash */
@@ -868,56 +908,64 @@ int BLI_testextensie(char *str, char *ext)
void BLI_split_dirfile(char *string, char *dir, char *file)
void BLI_split_dirfile(const char *string, char *dir, char *file)
{
int a;
int sl;
short is_relative = 0;
dir[0]= 0;
file[0]= 0;
#ifdef WIN32
BLI_char_switch(string, '/', '\\'); /* make sure we have a valid path format */
if (strlen(string)) {
sl = strlen(string);
if (sl) {
int len;
if (string[0] == '/' || string[0] == '\\') {
BLI_strncpy(dir, string, FILE_MAXDIR);
} else if (string[1] == ':' && string[2] == '\\') {
BLI_strncpy(dir, string, FILE_MAXDIR);
} else {
BLI_getwdN(dir);
strcat(dir,"/");
strcat(dir,string);
BLI_strncpy(string,dir,FILE_MAXDIR+FILE_MAXFILE);
}
if (sl > 1 && string[0] == '\\' && string[1] == '\\') is_relative = 1;
} else if (sl > 2 && string[1] == ':' && string[2] == '\\') {
BLI_strncpy(dir, string, FILE_MAXDIR);
} else {
BLI_getwdN(dir);
strcat(dir,"\\");
strcat(dir,string);
BLI_strncpy(string,dir,FILE_MAXDIR+FILE_MAXFILE);
}
BLI_make_exist(dir);
// BLI_exist doesn't recognize a slashed dirname as a dir
// check if a trailing slash exists, and remove it. Do not do this
// when we are already at root. -jesterKing
a = strlen(dir);
if(a>=4 && dir[a-1]=='\\') dir[a-1] = 0;
// BLI_exist doesn't recognize a slashed dirname as a dir
// check if a trailing slash exists, and remove it. Do not do this
// when we are already at root. -jesterKing
a = strlen(dir);
if(a>=4 && dir[a-1]=='\\') dir[a-1] = 0;
if (is_relative) {
printf("WARNING: BLI_split_dirfile needs absolute dir");
}
else {
BLI_make_exist(dir);
}
if (S_ISDIR(BLI_exist(dir))) {
if (S_ISDIR(BLI_exist(dir))) {
/* copy from end of string into file, to ensure filename itself isn't truncated
if string is too long. (aphex) */
/* copy from end of string into file, to ensure filename itself isn't truncated
if string is too long. (aphex) */
len = FILE_MAXFILE - strlen(string);
len = FILE_MAXFILE - strlen(string);
if (len < 0)
BLI_strncpy(file,string + abs(len),FILE_MAXFILE);
else
BLI_strncpy(file,string,FILE_MAXFILE);
if (strrchr(string,'\\')){
BLI_strncpy(file,strrchr(string,'\\')+1,FILE_MAXFILE);
}
if (len < 0)
BLI_strncpy(file,string + abs(len),FILE_MAXFILE);
else
BLI_strncpy(file,string,FILE_MAXFILE);
if (strrchr(string,'\\')){
BLI_strncpy(file,strrchr(string,'\\')+1,FILE_MAXFILE);
}
if (a = strlen(dir)) {
if (dir[a-1] != '\\') strcat(dir,"\\");
}
if (a = strlen(dir)) {
if (dir[a-1] != '\\') strcat(dir,"\\");
}
}
else {
a = strlen(dir) - 1;
@@ -925,10 +973,11 @@ void BLI_split_dirfile(char *string, char *dir, char *file)
dir[a + 1] = 0;
BLI_strncpy(file, string + strlen(dir),FILE_MAXFILE);
}
}
else {
strcpy(dir, "\\");
/* defaulting to first valid drive hoping it's not empty CD and DVD drives */
get_default_root(dir);
file[0]=0;
}
#else

View File

@@ -55,7 +55,7 @@ int BLI_getInstallationDir( char * str ) {
int a;
GetModuleFileName(NULL,str,FILE_MAXDIR+FILE_MAXFILE);
BLI_split_dirfile(str,dir,file);
BLI_split_dirfile(str,dir,file); /* shouldn't be relative */
a = strlen(dir);
if(dir[a-1] == '\\') dir[a-1]=0;
@@ -104,7 +104,7 @@ DIR *opendir (const char *path) {
DIR *newd= MEM_mallocN(sizeof(DIR), "opendir");
newd->handle = INVALID_HANDLE_VALUE;
sprintf(newd->path, "%s/*.*",path);
sprintf(newd->path, "%s\\*",path);
newd->direntry.d_ino= 0;
newd->direntry.d_off= 0;
@@ -149,6 +149,30 @@ int closedir (DIR *dp) {
return 0;
}
void get_default_root(char* root) {
DWORD tmp;
int i;
tmp= GetLogicalDrives();
for (i=2; i < 26; i++) {
if ((tmp>>i) & 1) {
root[0] = 'a'+i;
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
if (GetFileAttributes(root) != 0xFFFFFFFF)
return;
}
}
printf("ERROR in 'get_default_root': can't find a valid drive!");
root[0] = 'c';
root[1] = ':';
root[2] = '\\';
root[3] = '\0';
}
#else
static void BLI_WINSTUFF_C_IS_EMPTY_FOR_UNIX(void)

View File

@@ -705,7 +705,9 @@ void parent(SpaceFile *sfile)
if( (a = strlen(dir)) ) {
if (dir[a-1] != '\\') strcat(dir,"\\");
}
else if(sfile->type!=FILE_MAIN) strcpy(dir,"\\");
else if(sfile->type!=FILE_MAIN) {
get_default_root(dir);
}
#else
if( (a = strlen(dir)) ) { /* remove all '/' at the end */
while(dir[a-1] == '/') {
@@ -1518,7 +1520,15 @@ static void filesel_execute(SpaceFile *sfile)
BLI_strncpy(name, sfile->dir, sizeof(name));
strcat(name, sfile->file);
if(sfile->flag & FILE_STRINGCODE) BLI_makestringcode(G.sce, name);
if(sfile->flag & FILE_STRINGCODE) {
if (!G.relbase_valid) {
okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
sfile->flag & ~FILE_STRINGCODE;
}
else {
BLI_makestringcode(G.sce, name);
}
}
sfile->returnfunc(name);
}
@@ -1549,6 +1559,8 @@ static void do_filesel_buttons(short event, SpaceFile *sfile)
BLI_cleanup_dir(G.sce, sfile->dir);
BLI_make_file_string(G.sce, butname, sfile->dir, "");
BLI_strncpy(sfile->dir, butname, sizeof(sfile->dir));
/* strip the trailing slash if its a real dir */
if (strlen(butname)!=1)
butname[strlen(butname)-1]=0;

View File

@@ -459,6 +459,8 @@ static void show_splash(void)
static void filesel_u_yfexportdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.yfexportdir, dir);
@@ -468,6 +470,8 @@ static void filesel_u_yfexportdir(char *name)
static void filesel_u_fontdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.fontdir, dir);
@@ -477,6 +481,8 @@ static void filesel_u_fontdir(char *name)
static void filesel_u_textudir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.textudir, dir);
@@ -486,6 +492,8 @@ static void filesel_u_textudir(char *name)
static void filesel_u_plugtexdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.plugtexdir, dir);
@@ -495,6 +503,8 @@ static void filesel_u_plugtexdir(char *name)
static void filesel_u_plugseqdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.plugseqdir, dir);
@@ -504,6 +514,8 @@ static void filesel_u_plugseqdir(char *name)
static void filesel_u_renderdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.renderdir, dir);
@@ -513,6 +525,8 @@ static void filesel_u_renderdir(char *name)
static void filesel_u_pythondir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.pythondir, dir);
@@ -522,6 +536,8 @@ static void filesel_u_pythondir(char *name)
static void filesel_u_sounddir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.sounddir, dir);
@@ -531,6 +547,8 @@ static void filesel_u_sounddir(char *name)
static void filesel_u_tempdir(char *name)
{
char dir[FILE_MAXDIR], file[FILE_MAXFILE];
BLI_cleanup_dir(G.sce, name);
BLI_split_dirfile(name, dir, file);
strcpy(U.tempdir, dir);

View File

@@ -368,6 +368,8 @@ void BIF_read_file(char *name)
if(retval==2) init_userdef_file(); // in case a userdef is read from regular .blend
G.relbase_valid = 1;
undo_editmode_clear();
BKE_reset_undo();
BKE_write_undo("original"); /* save current state */
@@ -417,6 +419,7 @@ int BIF_read_homefile(void)
}
BLI_freelistN(&G.ttfdata);
G.relbase_valid = 0;
BLI_make_file_string(G.sce, tstr, home, ".B.blend");
strcpy(scestr, G.sce); /* temporal store */
@@ -558,7 +561,7 @@ static void readBlog(void)
fsmenu_append_seperator();
/* add last saved file */
BLI_split_dirfile(G.sce, name, filename);
BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */
fsmenu_insert_entry(name, 0);
@@ -683,6 +686,7 @@ void BIF_write_file(char *target)
if (BLO_write_file(di, writeflags, &err)) {
strcpy(G.sce, di);
G.relbase_valid = 1;
strcpy(G.main->name, di); /* is guaranteed current file */
mainwindow_set_filename_to_title(G.main->name);