Fixes for:
authorAndrea Weikert <elubie@gmx.net>
Sun, 20 Aug 2006 14:41:13 +0000 (14:41 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sun, 20 Aug 2006 14:41:13 +0000 (14:41 +0000)
[ #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
source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/BLI_winstuff.h
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/util.c
source/blender/blenlib/intern/winstuff.c
source/blender/src/filesel.c
source/blender/src/headerbuttons.c
source/blender/src/usiblender.c

index 3051403c412851a9ebf389046bb2839f9e0ee6d0..e239d4de3c03d400a47f21a1b6ae6f28410cd9e6 100644 (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;
     
index 28fca2c29a61d3c25b6a4e395c7e9a79df77b7a9..d26afbc350c238e4da31790668776344a503ade3 100644 (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);
index 1783443ea3b6af9898d7a9b70782941288e33204..0f39d37c31f15c01079092b5e7080364ccfdb09d 100644 (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__ */
 
index 0487154f7df9048f9a5d558faf3a210b49f1b3fa..f667676117b43340715dbda91ee2747c5a4ede60 100644 (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));
index 0936fb234de0b6031a56c30d679a87fe4dd380ef..c559761fb3229a6648d33c702149274559df6ffe 100644 (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);
-        }
-
-        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
index 34b9d9cf9b9c62c8dd8c03ad4869120a3a40f42a..6b861ad43dfcb050ac178c1592f4fdf34de103d1 100644 (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) 
index bc1bfba9161f5cacc848d6956bdb05d59a0e9171..da73aa33225a476bb8a309098bd2a56927b8cd59 100644 (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;
index dd582aa0203b6da2bfa990a268ed7ccfb55e2a94..a31f17d1638dae66e43ddbfa256bb94bb8e9ea79 100644 (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);
index 381a848237167ae4ce44485d7e150d9c6ad868c1..27f2248d985d9f7bc11e102461827118f708bf11 100644 (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);