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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user