From ffe630b452f4abb28c105fca2b8eb9fdb6e72370 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Aug 2006 14:41:13 +0000 Subject: 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:\ --- source/blender/blenkernel/BKE_global.h | 3 + source/blender/blenlib/BLI_blenlib.h | 2 +- source/blender/blenlib/BLI_winstuff.h | 1 + source/blender/blenlib/intern/storage.c | 8 ++ source/blender/blenlib/intern/util.c | 147 ++++++++++++++++++++----------- source/blender/blenlib/intern/winstuff.c | 28 +++++- source/blender/src/filesel.c | 16 +++- source/blender/src/headerbuttons.c | 18 ++++ source/blender/src/usiblender.c | 6 +- 9 files changed, 174 insertions(+), 55 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 3051403c412..e239d4de3c0 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -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; diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 28fca2c29a6..d26afbc350c 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -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); diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 1783443ea3b..0f39d37c31f 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -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__ */ diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 0487154f7df..f667676117b 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -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)); diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 0936fb234de..c559761fb32 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -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); - } - - 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; - - 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) */ - - 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 (a = strlen(dir)) { - if (dir[a-1] != '\\') strcat(dir,"\\"); - } + 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_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))) { + + /* 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); + + 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,"\\"); + } } 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 diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 34b9d9cf9b9..6b861ad43df 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -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) diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index bc1bfba9161..da73aa33225 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -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; diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index dd582aa0203..a31f17d1638 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -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); diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 381a8482371..27f2248d985 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -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); -- cgit v1.2.3