int BLI_copy(const char *file, const char *to) { int err; // windows doesn't support copying to a directory // it has to be 'cp filename filename' and not // 'cp filename destdir' BLI_strncpy(str, to, sizeof(str)); // points 'to' to a directory ? if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } err= !CopyFile(file,str,FALSE); if (err) { callLocalErrorCallBack("Unable to copy file!"); printf(" Copy from '%s' to '%s' failed\n", file, str); } return err; }
int BLI_copy(const char *file, const char *to) { int err; /* windows doesn't support copying to a directory * it has to be 'cp filename filename' and not * 'cp filename destdir' */ BLI_strncpy(str, to, sizeof(str)); /* points 'to' to a directory ? */ if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } UTF16_ENCODE(file); UTF16_ENCODE(str); err = !CopyFileW(file_16, str_16, false); UTF16_UN_ENCODE(str); UTF16_UN_ENCODE(file); if (err) { callLocalErrorCallBack("Unable to copy file!"); printf(" Copy from '%s' to '%s' failed\n", file, str); } return err; }
void BLI_recurdir_fileops(char *dirname) { char *lslash; char tmp[MAXPATHLEN]; // First remove possible slash at the end of the dirname. // This routine otherwise tries to create // blah1/blah2/ (with slash) after creating // blah1/blah2 (without slash) strcpy(tmp, dirname); lslash= BLI_last_slash(tmp); if (lslash == tmp + strlen(tmp) - 1) { *lslash = 0; } if (BLI_exists(tmp)) return; lslash= BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_recurdir_fileops(tmp); } if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */ if (!CreateDirectory(dirname, NULL)) callLocalErrorCallBack("Unable to create directory\n"); }
static char *check_destination(const char *file, const char *to) { struct stat st; if (!stat(to, &st)) { if (S_ISDIR(st.st_mode)) { char *str, *path; const char *filename; size_t len = 0; str = strip_last_slash(file); filename = BLI_last_slash(str); if (!filename) { MEM_freeN(str); return (char *)to; } /* skip slash */ filename += 1; len = strlen(to) + strlen(filename) + 1; path = MEM_callocN(len + 1, "check_destination path"); BLI_join_dirfile(path, len + 1, to, filename); MEM_freeN(str); return path; } } return (char *)to; }
void BLI_dir_create_recursive(const char *dirname) { char *lslash; size_t size; #ifdef MAXPATHLEN char static_buf[MAXPATHLEN]; #endif char *tmp; if (BLI_exists(dirname)) return; #ifdef MAXPATHLEN size = MAXPATHLEN; tmp = static_buf; #else size = strlen(dirname) + 1; tmp = MEM_callocN(size, __func__); #endif BLI_strncpy(tmp, dirname, size); lslash = (char *)BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_dir_create_recursive(tmp); } #ifndef MAXPATHLEN MEM_freeN(tmp); #endif mkdir(dirname, 0777); }
static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len) { size_t ofs = 0; str[0] = 0; if (ima == NULL) return; if (ibuf == NULL) { ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs); } else { if (ima->source == IMA_SRC_MOVIE) { ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs); if (ima->anim) ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(" %d frs"), IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN)); } else { ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs); } ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y); if (ibuf->rect_float) { if (ibuf->channels != 4) { ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels); } else if (ibuf->planes == R_IMF_PLANES_RGBA) ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs); else ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs); } else { if (ibuf->planes == R_IMF_PLANES_RGBA) ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs); else ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs); } if (ibuf->zbuf || ibuf->zbuf_float) ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs); if (ima->source == IMA_SRC_SEQUENCE) { const char *file = BLI_last_slash(ibuf->name); if (file == NULL) file = ibuf->name; else file++; ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file); } } /* the frame number, even if we cant */ if (ima->source == IMA_SRC_SEQUENCE) { /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL); ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr); } }
static int file_browse_exec(bContext *C, wmOperator *op) { FileBrowseOp *fbo = op->customdata; ID *id; char *str, path[FILE_MAX]; const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; if (RNA_struct_property_is_set(op->ptr, path_prop) == 0 || fbo == NULL) return OPERATOR_CANCELLED; str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0); /* add slash for directories, important for some properties */ if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) { int is_relative = RNA_boolean_get(op->ptr, "relative_path"); id = fbo->ptr.id.data; BLI_strncpy(path, str, FILE_MAX); BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name); if (BLI_is_dir(path)) { /* do this first so '//' isnt converted to '//\' on windows */ BLI_add_slash(path); if (is_relative) { BLI_strncpy(path, str, FILE_MAX); BLI_path_rel(path, G.main->name); str = MEM_reallocN(str, strlen(path) + 2); BLI_strncpy(str, path, FILE_MAX); } else { str = MEM_reallocN(str, strlen(str) + 2); } } else { char * const lslash = (char *)BLI_last_slash(str); if (lslash) lslash[1] = '\0'; } } RNA_property_string_set(&fbo->ptr, fbo->prop, str); RNA_property_update(C, &fbo->ptr, fbo->prop); MEM_freeN(str); /* special, annoying exception, filesel on redo panel [#26618] */ { wmOperator *redo_op = WM_operator_last_redo(C); if (redo_op) { if (fbo->ptr.data == redo_op->ptr->data) { ED_undo_operator_repeat(C, redo_op); } } } MEM_freeN(op->customdata); return OPERATOR_FINISHED; }
static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) { PointerRNA ptr; PropertyRNA *prop; FileBrowseOp *fbo; char *str; uiFileBrowseContextProperty(C, &ptr, &prop); if(!prop) return OPERATOR_CANCELLED; str= RNA_property_string_get_alloc(&ptr, prop, NULL, 0); /* useful yet irritating feature, Shift+Click to open the file * Alt+Click to browse a folder in the OS's browser */ if(event->shift || event->alt) { PointerRNA props_ptr; if(event->alt) { char *lslash= BLI_last_slash(str); if(lslash) *lslash= '\0'; } WM_operator_properties_create(&props_ptr, "WM_OT_path_open"); RNA_string_set(&props_ptr, "filepath", str); WM_operator_name_call(C, "WM_OT_path_open", WM_OP_EXEC_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); MEM_freeN(str); return OPERATOR_CANCELLED; } else { const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; fbo= MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp"); fbo->ptr= ptr; fbo->prop= prop; op->customdata= fbo; RNA_string_set(op->ptr, path_prop, str); MEM_freeN(str); if(RNA_struct_find_property(op->ptr, "relative_path")) { if(!RNA_property_is_set(op->ptr, "relative_path")) { /* annoying exception!, if were dealign with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } } WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } }
static int groupname_to_code(const char *group) { char buf[32]; char *lslash; BLI_strncpy(buf, group, sizeof(buf)); lslash= BLI_last_slash(buf); if (lslash) lslash[0]= '\0'; return BKE_idcode_from_name(buf); }
/* 'di's filename component is moved into 'fi', di is made a dir path */ void BLI_splitdirstring(char *di, char *fi) { char *lslash= BLI_last_slash(di); if (lslash) { BLI_strncpy(fi, lslash+1, FILE_MAXFILE); *(lslash+1)=0; } else { BLI_strncpy(fi, di, FILE_MAXFILE); di[0]= 0; } }
static int groupname_to_code(const char *group) { char buf[BLO_GROUP_MAX]; char *lslash; BLI_strncpy(buf, group, sizeof(buf)); lslash = (char *)BLI_last_slash(buf); if (lslash) lslash[0] = '\0'; return buf[0] ? BKE_idcode_from_name(buf) : 0; }
int BLI_move(char *file, char *to) { int err; // windows doesn't support moveing to a directory // it has to be 'mv filename filename' and not // 'mv filename destdir' strcpy(str, to); // points 'to' to a directory ? if (BLI_last_slash(str) == (str + strlen(str) - 1)) { if (BLI_last_slash(file) != NULL) { strcat(str, BLI_last_slash(file) + 1); } } err= !MoveFile(file, str); if (err) { callLocalErrorCallBack("Unable to move file"); printf(" Move from '%s' to '%s' failed\n", file, str); } return err; }
void BLI_dir_create_recursive(const char *dirname) { char *lslash; char tmp[MAXPATHLEN]; /* First remove possible slash at the end of the dirname. * This routine otherwise tries to create * blah1/blah2/ (with slash) after creating * blah1/blah2 (without slash) */ BLI_strncpy(tmp, dirname, sizeof(tmp)); lslash = (char *)BLI_last_slash(tmp); if (lslash && (*(lslash + 1) == '\0')) { *lslash = '\0'; } /* check special case "c:\foo", don't try create "c:", harmless but prints an error below */ if (isalpha(tmp[0]) && (tmp[1] == ':') && tmp[2] == '\0') return; if (BLI_exists(tmp)) return; lslash = (char *)BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_dir_create_recursive(tmp); } if (dirname[0]) { /* patch, this recursive loop tries to create a nameless directory */ if (umkdir(dirname) == -1) { printf("Unable to create directory %s\n", dirname); } } }
static void ensure_digits(char *path, int digits) { char *file = BLI_last_slash(path); if (file == NULL) file = path; if (strrchr(file, '#') == NULL) { int len = strlen(file); while (digits--) { file[len++] = '#'; } file[len] = '\0'; } }
/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt" * - wont change 'string' * - wont create any directories * - dosnt use CWD, or deal with relative paths. * - Only fill's in *dir and *file when they are non NULL * */ void BLI_split_dirfile(const char *string, char *dir, char *file) { char *lslash_str = BLI_last_slash(string); int lslash= lslash_str ? (int)(lslash_str - string) + 1 : 0; if (dir) { if (lslash) { BLI_strncpy( dir, string, lslash + 1); /* +1 to include the slash and the last char */ } else { dir[0] = '\0'; } } if (file) { strcpy( file, string+lslash); } }
void BLI_recurdir_fileops(char *dirname) { char *lslash; char tmp[MAXPATHLEN]; if (BLI_exists(dirname)) return; strcpy(tmp, dirname); lslash= BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_recurdir_fileops(tmp); } mkdir(dirname, 0777); }
/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt" * - wont change 'string' * - wont create any directories * - dosnt use CWD, or deal with relative paths. * - Only fill's in *dir and *file when they are non NULL * */ void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen) { char *lslash_str = BLI_last_slash(string); size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0; if (dir) { if (lslash) { BLI_strncpy(dir, string, MIN2(dirlen, lslash + 1)); /* +1 to include the slash and the last char */ } else { dir[0] = '\0'; } } if (file) { BLI_strncpy(file, string + lslash, filelen); } }
void BLI_dir_create_recursive(const char *dirname) { char *lslash; char tmp[MAXPATHLEN]; if (BLI_exists(dirname)) return; BLI_strncpy(tmp, dirname, sizeof(tmp)); lslash= BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ *lslash = 0; BLI_dir_create_recursive(tmp); } mkdir(dirname, 0777); }
int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *numlen) { unsigned short len, len2, lenlslash = 0, nums = 0, nume = 0; short i, found = 0; char *lslash = BLI_last_slash(string); len2 = len = strlen(string); if (lslash) lenlslash = (int)(lslash - string); while (len > lenlslash && string[--len] != '.') {} if (len == lenlslash && string[len] != '.') len = len2; for (i = len - 1; i >= lenlslash; i--) { if (isdigit(string[i])) { if (found) { nums = i; } else { nume = i; nums = i; found = 1; } } else { if (found) break; } } if (found) { if (tail) strcpy(tail, &string[nume + 1]); if (head) { strcpy(head, string); head[nums] = 0; } if (numlen) *numlen = nume - nums + 1; return ((int)atoi(&(string[nums]))); } if (tail) strcpy(tail, string + len); if (head) { strncpy(head, string, len); head[len] = '\0'; } if (numlen) *numlen = 0; return 0; }
int BLI_path_abs(char *path, const char *basepath) { int wasrelative = BLI_path_is_rel(path); char tmp[FILE_MAX]; char base[FILE_MAX]; #ifdef WIN32 char vol[3] = {'\0', '\0', '\0'}; BLI_strncpy(vol, path, 3); /* we are checking here if we have an absolute path that is not in the current * blend file as a lib main - we are basically checking for the case that a * UNIX root '/' is passed. */ if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) { char *p = path; get_default_root(tmp); // get rid of the slashes at the beginning of the path while (*p == '\\' || *p == '/') { p++; } strcat(tmp, p); } else { BLI_strncpy(tmp, path, FILE_MAX); } #else BLI_strncpy(tmp, path, sizeof(tmp)); /* Check for loading a windows path on a posix system * in this case, there is no use in trying C:/ since it * will never exist on a unix os. * * Add a / prefix and lowercase the driveletter, remove the : * C:\foo.JPG -> /c/foo.JPG */ if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/') ) { tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */ tmp[0] = '/'; /* '\' the slash will be converted later */ } #endif BLI_strncpy(base, basepath, sizeof(base)); /* file component is ignored, so don't bother with the trailing slash */ BLI_cleanup_path(NULL, base); /* push slashes into unix mode - strings entering this part are * potentially messed up: having both back- and forward slashes. * Here we push into one conform direction, and at the end we * push them into the system specific dir. This ensures uniformity * of paths and solving some problems (and prevent potential future * ones) -jesterKing. */ BLI_char_switch(tmp, '\\', '/'); BLI_char_switch(base, '\\', '/'); /* Paths starting with // will get the blend file as their base, * this isn't standard in any os but is used in blender all over the place */ if (wasrelative) { char *lslash = BLI_last_slash(base); if (lslash) { int baselen = (int) (lslash - base) + 1; /* use path for temp storage here, we copy back over it right away */ BLI_strncpy(path, tmp + 2, FILE_MAX); memcpy(tmp, base, baselen); BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); BLI_strncpy(path, tmp, FILE_MAX); } else { BLI_strncpy(path, tmp + 2, FILE_MAX); } } else { BLI_strncpy(path, tmp, FILE_MAX); } BLI_cleanup_path(NULL, path); #ifdef WIN32 /* skip first two chars, which in case of * absolute path will be drive:/blabla and * in case of relpath //blabla/. So relpath * // will be retained, rest will be nice and * shiny win32 backward slashes :) -jesterKing */ BLI_char_switch(path + 2, '/', '\\'); #endif return wasrelative; }
void BLI_path_rel(char *file, const char *relfile) { char *lslash; char temp[FILE_MAX]; char res[FILE_MAX]; /* if file is already relative, bail out */ if (BLI_path_is_rel(file)) { return; } /* also bail out if relative path is not set */ if (relfile[0] == '\0') { return; } #ifdef WIN32 if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') { char *ptemp; /* fix missing volume name in relative base, * can happen with old recent-files.txt files */ get_default_root(temp); ptemp = &temp[2]; if (relfile[0] != '\\' && relfile[0] != '/') { ptemp++; } BLI_strncpy(ptemp, relfile, FILE_MAX - 3); } else { BLI_strncpy(temp, relfile, FILE_MAX); } if (BLI_strnlen(file, 3) > 2) { if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) return; } #else BLI_strncpy(temp, relfile, FILE_MAX); #endif BLI_char_switch(temp, '\\', '/'); BLI_char_switch(file, '\\', '/'); /* remove /./ which confuse the following slash counting... */ BLI_cleanup_path(NULL, file); BLI_cleanup_path(NULL, temp); /* the last slash in the file indicates where the path part ends */ lslash = BLI_last_slash(temp); if (lslash) { /* find the prefix of the filename that is equal for both filenames. * This is replaced by the two slashes at the beginning */ char *p = temp; char *q = file; #ifdef WIN32 while (tolower(*p) == tolower(*q)) #else while (*p == *q) #endif { p++; q++; /* don't search beyond the end of the string * in the rare case they match */ if ((*p == '\0') || (*q == '\0')) { break; } } /* we might have passed the slash when the beginning of a dir matches * so we rewind. Only check on the actual filename */ if (*q != '/') { while ( (q >= file) && (*q != '/') ) { --q; --p; } } else if (*p != '/') { while ( (p >= temp) && (*p != '/') ) { --p; --q; } } strcpy(res, "//"); /* p now points to the slash that is at the beginning of the part * where the path is different from the relative path. * We count the number of directories we need to go up in the * hierarchy to arrive at the common 'prefix' of the path */ while (p && p < lslash) { if (*p == '/') strcat(res, "../"); p++; } strcat(res, q + 1); /* don't copy the slash at the beginning */ #ifdef WIN32 BLI_char_switch(res + 2, '/', '\\'); #endif strcpy(file, res); } }
/** * Checks if name is a fully qualified filename to an executable. * If not it searches $PATH for the file. On Windows it also * adds the correct extension (.com .exe etc) from * $PATHEXT if necessary. Also on Windows it translates * the name to its 8.3 version to prevent problems with * spaces and stuff. Final result is returned in fullname. * * \param fullname The full path and full name of the executable * (must be FILE_MAX minimum) * \param name The name of the executable (usually argv[0]) to be checked */ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) { char filename[FILE_MAX]; const char *path = NULL, *temp; #ifdef _WIN32 const char *separator = ";"; #else const char *separator = ":"; #endif #ifdef WITH_BINRELOC /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ path = br_find_exe(NULL); if (path) { BLI_strncpy(fullname, path, maxlen); free((void *)path); return; } #endif #ifdef _WIN32 wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); if (GetModuleFileNameW(0, fullname_16, maxlen)) { conv_utf_16_to_8(fullname_16, fullname, maxlen); if (!BLI_exists(fullname)) { printf("path can't be found: \"%.*s\"\n", maxlen, fullname); MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); } MEM_freeN(fullname_16); return; } MEM_freeN(fullname_16); #endif /* unix and non linux */ if (name && name[0]) { BLI_strncpy(fullname, name, maxlen); if (name[0] == '.') { char wdir[FILE_MAX] = ""; BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ // not needed but avoids annoying /./ in name if (name[1] == SEP) BLI_join_dirfile(fullname, maxlen, wdir, name + 2); else BLI_join_dirfile(fullname, maxlen, wdir, name); add_win32_extension(fullname); /* XXX, doesnt respect length */ } else if (BLI_last_slash(name)) { // full path BLI_strncpy(fullname, name, maxlen); add_win32_extension(fullname); } else { // search for binary in $PATH path = getenv("PATH"); if (path) { do { temp = strstr(path, separator); if (temp) { strncpy(filename, path, temp - path); filename[temp - path] = 0; path = temp + 1; } else { strncpy(filename, path, sizeof(filename)); } BLI_join_dirfile(fullname, maxlen, fullname, name); if (add_win32_extension(filename)) { BLI_strncpy(fullname, filename, maxlen); break; } } while (temp); } } #if defined(DEBUG) if (strcmp(name, fullname)) { printf("guessing '%s' == '%s'\n", name, fullname); } #endif } }
/* like pythons os.path.basename( ) */ char *BLI_path_basename(char *path) { char *filename = BLI_last_slash(path); return filename ? filename + 1 : path; }
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file) { int sl; if (string) { /* ensure this is always set even if dir/file are NULL */ string[0] = '\0'; if (ELEM(NULL, dir, file)) { return; /* We don't want any NULLs */ } } else { return; /* string is NULL, probably shouldnt happen but return anyway */ } /* we first push all slashes into unix mode, just to make sure we don't get * any mess with slashes later on. -jesterKing */ /* constant strings can be passed for those parameters - don't change them - elubie */ #if 0 BLI_char_switch(relabase, '\\', '/'); BLI_char_switch(dir, '\\', '/'); BLI_char_switch(file, '\\', '/'); #endif /* Resolve relative references */ if (relabase && dir[0] == '/' && dir[1] == '/') { char *lslash; /* Get the file name, chop everything past the last slash (ie. the filename) */ strcpy(string, relabase); lslash = BLI_last_slash(string); if (lslash) *(lslash + 1) = 0; dir += 2; /* Skip over the relative reference */ } #ifdef WIN32 else { if (BLI_strnlen(dir, 3) >= 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 */ /* first trim all slashes from the end of the string */ sl = strlen(string); while (sl > 0 && (string[sl - 1] == '/' || string[sl - 1] == '\\') ) { string[sl - 1] = '\0'; sl--; } /* since we've now removed all slashes, put back one slash at the end. */ strcat(string, "/"); while (*file && (*file == '/' || *file == '\\')) /* Trim slashes from the front of file */ file++; strcat(string, file); /* Push all slashes to the system preferred direction */ BLI_clean(string); }
static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) { PointerRNA ptr; PropertyRNA *prop; bool is_undo; FileBrowseOp *fbo; char *str; if (CTX_wm_space_file(C)) { BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open"); return OPERATOR_CANCELLED; } UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo); if (!prop) return OPERATOR_CANCELLED; str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); /* useful yet irritating feature, Shift+Click to open the file * Alt+Click to browse a folder in the OS's browser */ if (event->shift || event->alt) { wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true); PointerRNA props_ptr; if (event->alt) { char *lslash = (char *)BLI_last_slash(str); if (lslash) *lslash = '\0'; } WM_operator_properties_create_ptr(&props_ptr, ot); RNA_string_set(&props_ptr, "filepath", str); WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); MEM_freeN(str); return OPERATOR_CANCELLED; } else { PropertyRNA *prop_relpath; const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp"); fbo->ptr = ptr; fbo->prop = prop; fbo->is_undo = is_undo; op->customdata = fbo; RNA_string_set(op->ptr, path_prop, str); MEM_freeN(str); /* normally ED_fileselect_get_params would handle this but we need to because of stupid * user-prefs exception - campbell */ if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) { if (!RNA_property_is_set(op->ptr, prop_relpath)) { /* annoying exception!, if were dealing with the user prefs, default relative to be off */ RNA_property_boolean_set(op->ptr, prop_relpath, U.flag & USER_RELPATHS && (ptr.data != &U)); } } WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } }