|
Blender
V2.59
|
00001 /* 00002 * $Id: filesel.c 37688 2011-06-21 04:03:26Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <string.h> 00035 #include <stdio.h> 00036 #include <math.h> 00037 00038 #include <sys/stat.h> 00039 #include <sys/types.h> 00040 00041 #ifdef WIN32 00042 #include <io.h> 00043 #include <direct.h> 00044 #include "BLI_winstuff.h" 00045 #else 00046 #include <unistd.h> 00047 #include <sys/times.h> 00048 #endif 00049 00050 /* path/file handeling stuff */ 00051 #ifndef WIN32 00052 #include <dirent.h> 00053 #include <unistd.h> 00054 #else 00055 #include <io.h> 00056 #include "BLI_winstuff.h" 00057 #endif 00058 00059 #include "DNA_space_types.h" 00060 #include "DNA_screen_types.h" 00061 #include "DNA_userdef_types.h" 00062 00063 #include "MEM_guardedalloc.h" 00064 00065 #include "BLI_blenlib.h" 00066 #include "BLI_linklist.h" 00067 #include "BLI_path_util.h" 00068 #include "BLI_storage_types.h" 00069 #include "BLI_dynstr.h" 00070 #include "BLI_utildefines.h" 00071 00072 #include "BKE_context.h" 00073 #include "BKE_global.h" 00074 #include "BKE_main.h" 00075 00076 #include "BLF_api.h" 00077 00078 00079 #include "ED_fileselect.h" 00080 00081 #include "WM_api.h" 00082 #include "WM_types.h" 00083 00084 00085 #include "RNA_access.h" 00086 00087 #include "UI_interface.h" 00088 #include "UI_interface_icons.h" 00089 00090 #include "file_intern.h" 00091 #include "filelist.h" 00092 00093 #if defined WIN32 && !defined _LIBC 00094 # include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ 00095 #else 00096 # include <fnmatch.h> 00097 #endif 00098 00099 FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile) 00100 { 00101 if (!sfile->params) { 00102 ED_fileselect_set_params(sfile); 00103 } 00104 return sfile->params; 00105 } 00106 00107 short ED_fileselect_set_params(SpaceFile *sfile) 00108 { 00109 FileSelectParams *params; 00110 wmOperator *op = sfile->op; 00111 00112 /* create new parameters if necessary */ 00113 if (!sfile->params) { 00114 sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); 00115 /* set path to most recently opened .blend */ 00116 BLI_split_dirfile(G.main->name, sfile->params->dir, sfile->params->file); 00117 sfile->params->filter_glob[0] = '\0'; 00118 } 00119 00120 params = sfile->params; 00121 00122 /* set the parameters from the operator, if it exists */ 00123 if (op) { 00124 const short is_files= (RNA_struct_find_property(op->ptr, "files") != NULL); 00125 const short is_filepath= (RNA_struct_find_property(op->ptr, "filepath") != NULL); 00126 const short is_filename= (RNA_struct_find_property(op->ptr, "filename") != NULL); 00127 const short is_directory= (RNA_struct_find_property(op->ptr, "directory") != NULL); 00128 00129 BLI_strncpy(params->title, op->type->name, sizeof(params->title)); 00130 00131 if(RNA_struct_find_property(op->ptr, "filemode")) 00132 params->type = RNA_int_get(op->ptr, "filemode"); 00133 else 00134 params->type = FILE_SPECIAL; 00135 00136 if (is_filepath && RNA_property_is_set(op->ptr, "filepath")) { 00137 char name[FILE_MAX]; 00138 RNA_string_get(op->ptr, "filepath", name); 00139 if (params->type == FILE_LOADLIB) { 00140 BLI_strncpy(params->dir, name, sizeof(params->dir)); 00141 sfile->params->file[0]= '\0'; 00142 } 00143 else { 00144 BLI_split_dirfile(name, sfile->params->dir, sfile->params->file); 00145 } 00146 } 00147 else { 00148 if (is_directory && RNA_property_is_set(op->ptr, "directory")) { 00149 RNA_string_get(op->ptr, "directory", params->dir); 00150 sfile->params->file[0]= '\0'; 00151 } 00152 00153 if (is_filename && RNA_property_is_set(op->ptr, "filename")) { 00154 RNA_string_get(op->ptr, "filename", params->file); 00155 } 00156 } 00157 00158 if(params->dir[0]) { 00159 BLI_cleanup_dir(G.main->name, params->dir); 00160 BLI_path_abs(params->dir, G.main->name); 00161 } 00162 00163 if(is_directory==TRUE && is_filename==FALSE && is_filepath==FALSE && is_files==FALSE) { 00164 params->flag |= FILE_DIRSEL_ONLY; 00165 } 00166 else { 00167 params->flag &= ~FILE_DIRSEL_ONLY; 00168 } 00169 00170 params->filter = 0; 00171 if(RNA_struct_find_property(op->ptr, "filter_blender")) 00172 params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; 00173 if(RNA_struct_find_property(op->ptr, "filter_image")) 00174 params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; 00175 if(RNA_struct_find_property(op->ptr, "filter_movie")) 00176 params->filter |= RNA_boolean_get(op->ptr, "filter_movie") ? MOVIEFILE : 0; 00177 if(RNA_struct_find_property(op->ptr, "filter_text")) 00178 params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; 00179 if(RNA_struct_find_property(op->ptr, "filter_python")) 00180 params->filter |= RNA_boolean_get(op->ptr, "filter_python") ? PYSCRIPTFILE : 0; 00181 if(RNA_struct_find_property(op->ptr, "filter_font")) 00182 params->filter |= RNA_boolean_get(op->ptr, "filter_font") ? FTFONTFILE : 0; 00183 if(RNA_struct_find_property(op->ptr, "filter_sound")) 00184 params->filter |= RNA_boolean_get(op->ptr, "filter_sound") ? SOUNDFILE : 0; 00185 if(RNA_struct_find_property(op->ptr, "filter_text")) 00186 params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; 00187 if(RNA_struct_find_property(op->ptr, "filter_folder")) 00188 params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; 00189 if(RNA_struct_find_property(op->ptr, "filter_btx")) 00190 params->filter |= RNA_boolean_get(op->ptr, "filter_btx") ? BTXFILE : 0; 00191 if(RNA_struct_find_property(op->ptr, "filter_collada")) 00192 params->filter |= RNA_boolean_get(op->ptr, "filter_collada") ? COLLADAFILE : 0; 00193 if (RNA_struct_find_property(op->ptr, "filter_glob")) { 00194 RNA_string_get(op->ptr, "filter_glob", params->filter_glob); 00195 params->filter |= (OPERATORFILE|FOLDERFILE); 00196 } 00197 else { 00198 params->filter_glob[0] = '\0'; 00199 } 00200 00201 if (params->filter != 0) { 00202 if (U.uiflag & USER_FILTERFILEEXTS) { 00203 params->flag |= FILE_FILTER; 00204 } else { 00205 params->flag &= ~FILE_FILTER; 00206 } 00207 } 00208 00209 if (U.uiflag & USER_HIDE_DOT) { 00210 params->flag |= FILE_HIDE_DOT; 00211 } else { 00212 params->flag &= ~FILE_HIDE_DOT; 00213 } 00214 00215 00216 if (params->type == FILE_LOADLIB) { 00217 params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; 00218 params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; 00219 params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; 00220 } 00221 00222 if (U.uiflag & USER_SHOW_THUMBNAILS) { 00223 if(params->filter & (IMAGEFILE|MOVIEFILE)) 00224 params->display= FILE_IMGDISPLAY; 00225 else 00226 params->display= FILE_SHORTDISPLAY; 00227 } else { 00228 params->display= FILE_SHORTDISPLAY; 00229 } 00230 00231 } 00232 else { 00233 /* default values, if no operator */ 00234 params->type = FILE_UNIX; 00235 params->flag |= FILE_HIDE_DOT; 00236 params->flag &= ~FILE_DIRSEL_ONLY; 00237 params->display = FILE_SHORTDISPLAY; 00238 params->filter = 0; 00239 params->filter_glob[0] = '\0'; 00240 params->sort = FILE_SORT_ALPHA; 00241 } 00242 00243 00244 /* initialize the list with previous folders */ 00245 if (!sfile->folders_prev) 00246 sfile->folders_prev = folderlist_new(); 00247 folderlist_pushdir(sfile->folders_prev, sfile->params->dir); 00248 00249 return 1; 00250 } 00251 00252 void ED_fileselect_reset_params(SpaceFile *sfile) 00253 { 00254 sfile->params->type = FILE_UNIX; 00255 sfile->params->flag = 0; 00256 sfile->params->title[0] = '\0'; 00257 } 00258 00259 int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar) 00260 { 00261 int numfiles; 00262 00263 if (layout->flag & FILE_LAYOUT_HOR) { 00264 int width = (int)(ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x); 00265 numfiles = (int)((float)width / (float)layout->tile_w + 0.5f); 00266 return numfiles*layout->rows; 00267 } else { 00268 int height = (int)(ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y); 00269 numfiles = (int)((float)height/(float)layout->tile_h + 0.5f); 00270 return numfiles*layout->columns; 00271 } 00272 } 00273 00274 static int is_inside(int x, int y, int cols, int rows) 00275 { 00276 return ( (x >= 0) && (x<cols) && (y>=0) && (y<rows) ); 00277 } 00278 00279 FileSelection ED_fileselect_layout_offset_rect(FileLayout* layout, const rcti* rect) 00280 { 00281 int colmin, colmax, rowmin, rowmax; 00282 FileSelection sel; 00283 sel.first = sel.last = -1; 00284 00285 if (layout == NULL) 00286 return sel; 00287 00288 colmin = (rect->xmin)/(layout->tile_w + 2*layout->tile_border_x); 00289 rowmin = (rect->ymin)/(layout->tile_h + 2*layout->tile_border_y); 00290 colmax = (rect->xmax)/(layout->tile_w + 2*layout->tile_border_x); 00291 rowmax = (rect->ymax)/(layout->tile_h + 2*layout->tile_border_y); 00292 00293 if ( is_inside(colmin, rowmin, layout->columns, layout->rows) || 00294 is_inside(colmax, rowmax, layout->columns, layout->rows) ) { 00295 CLAMP(colmin, 0, layout->columns-1); 00296 CLAMP(rowmin, 0, layout->rows-1); 00297 CLAMP(colmax, 0, layout->columns-1); 00298 CLAMP(rowmax, 0, layout->rows-1); 00299 } 00300 00301 if ( (colmin > layout->columns-1) || (rowmin > layout->rows-1) ) { 00302 sel.first = -1; 00303 } else { 00304 if (layout->flag & FILE_LAYOUT_HOR) 00305 sel.first = layout->rows*colmin + rowmin; 00306 else 00307 sel.first = colmin + layout->columns*rowmin; 00308 } 00309 if ( (colmax > layout->columns-1) || (rowmax > layout->rows-1) ) { 00310 sel.last = -1; 00311 } else { 00312 if (layout->flag & FILE_LAYOUT_HOR) 00313 sel.last = layout->rows*colmax + rowmax; 00314 else 00315 sel.last = colmax + layout->columns*rowmax; 00316 } 00317 00318 return sel; 00319 } 00320 00321 int ED_fileselect_layout_offset(FileLayout* layout, int x, int y) 00322 { 00323 int offsetx, offsety; 00324 int active_file; 00325 00326 if (layout == NULL) 00327 return -1; 00328 00329 offsetx = (x)/(layout->tile_w + 2*layout->tile_border_x); 00330 offsety = (y)/(layout->tile_h + 2*layout->tile_border_y); 00331 00332 if (offsetx > layout->columns-1) return -1 ; 00333 if (offsety > layout->rows-1) return -1 ; 00334 00335 if (layout->flag & FILE_LAYOUT_HOR) 00336 active_file = layout->rows*offsetx + offsety; 00337 else 00338 active_file = offsetx + layout->columns*offsety; 00339 return active_file; 00340 } 00341 00342 void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y) 00343 { 00344 if (layout->flag == FILE_LAYOUT_HOR) { 00345 *x = layout->tile_border_x + (tile/layout->rows)*(layout->tile_w+2*layout->tile_border_x); 00346 *y = layout->tile_border_y + (tile%layout->rows)*(layout->tile_h+2*layout->tile_border_y); 00347 } else { 00348 *x = layout->tile_border_x + ((tile)%layout->columns)*(layout->tile_w+2*layout->tile_border_x); 00349 *y = layout->tile_border_y + ((tile)/layout->columns)*(layout->tile_h+2*layout->tile_border_y); 00350 } 00351 } 00352 00353 /* Shorten a string to a given width w. 00354 If front is set, shorten from the front, 00355 otherwise shorten from the end. */ 00356 float file_shorten_string(char* string, float w, int front) 00357 { 00358 char temp[FILE_MAX]; 00359 short shortened = 0; 00360 float sw = 0; 00361 float pad = 0; 00362 00363 if (w <= 0) { 00364 *string = '\0'; 00365 return 0.0; 00366 } 00367 00368 sw = file_string_width(string); 00369 if (front == 1) { 00370 char *s = string; 00371 BLI_strncpy(temp, "...", 4); 00372 pad = file_string_width(temp); 00373 while ((*s) && (sw+pad>w)) { 00374 s++; 00375 sw = file_string_width(s); 00376 shortened = 1; 00377 } 00378 if (shortened) { 00379 int slen = strlen(s); 00380 BLI_strncpy(temp+3, s, slen+1); 00381 temp[slen+4] = '\0'; 00382 BLI_strncpy(string, temp, slen+4); 00383 } 00384 } else { 00385 char *s = string; 00386 while (sw>w) { 00387 int slen = strlen(string); 00388 string[slen-1] = '\0'; 00389 sw = file_string_width(s); 00390 shortened = 1; 00391 } 00392 00393 if (shortened) { 00394 int slen = strlen(string); 00395 if (slen > 3) { 00396 BLI_strncpy(string+slen-3, "...", 4); 00397 } 00398 } 00399 } 00400 00401 return sw; 00402 } 00403 00404 float file_string_width(const char* str) 00405 { 00406 uiStyle *style= U.uistyles.first; 00407 uiStyleFontSet(&style->widget); 00408 return BLF_width(style->widget.uifont_id, str); 00409 } 00410 00411 float file_font_pointsize(void) 00412 { 00413 #if 0 00414 float s; 00415 char tmp[2] = "X"; 00416 uiStyle *style= U.uistyles.first; 00417 uiStyleFontSet(&style->widget); 00418 s = BLF_height(style->widget.uifont_id, tmp); 00419 return style->widget.points; 00420 #else 00421 uiStyle *style= U.uistyles.first; 00422 uiStyleFontSet(&style->widget); 00423 return style->widget.points * UI_DPI_FAC; 00424 #endif 00425 } 00426 00427 static void column_widths(struct FileList* files, struct FileLayout* layout) 00428 { 00429 int i; 00430 int numfiles = filelist_numfiles(files); 00431 00432 for (i=0; i<MAX_FILE_COLUMN; ++i) { 00433 layout->column_widths[i] = 0; 00434 } 00435 00436 for (i=0; (i < numfiles); ++i) 00437 { 00438 struct direntry* file = filelist_file(files, i); 00439 if (file) { 00440 float len; 00441 len = file_string_width(file->relname); 00442 if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len; 00443 len = file_string_width(file->date); 00444 if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len; 00445 len = file_string_width(file->time); 00446 if (len > layout->column_widths[COLUMN_TIME]) layout->column_widths[COLUMN_TIME] = len; 00447 len = file_string_width(file->size); 00448 if (len > layout->column_widths[COLUMN_SIZE]) layout->column_widths[COLUMN_SIZE] = len; 00449 len = file_string_width(file->mode1); 00450 if (len > layout->column_widths[COLUMN_MODE1]) layout->column_widths[COLUMN_MODE1] = len; 00451 len = file_string_width(file->mode2); 00452 if (len > layout->column_widths[COLUMN_MODE2]) layout->column_widths[COLUMN_MODE2] = len; 00453 len = file_string_width(file->mode3); 00454 if (len > layout->column_widths[COLUMN_MODE3]) layout->column_widths[COLUMN_MODE3] = len; 00455 len = file_string_width(file->owner); 00456 if (len > layout->column_widths[COLUMN_OWNER]) layout->column_widths[COLUMN_OWNER] = len; 00457 } 00458 } 00459 } 00460 00461 void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar) 00462 { 00463 FileSelectParams *params = ED_fileselect_get_params(sfile); 00464 FileLayout *layout= NULL; 00465 View2D *v2d= &ar->v2d; 00466 int maxlen = 0; 00467 int numfiles; 00468 int textheight; 00469 if (sfile->layout == NULL) { 00470 sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout"); 00471 sfile->layout->dirty = 1; 00472 } 00473 00474 if (!sfile->layout->dirty) return; 00475 00476 numfiles = filelist_numfiles(sfile->files); 00477 textheight = (int)file_font_pointsize(); 00478 layout = sfile->layout; 00479 layout->textheight = textheight; 00480 00481 if (params->display == FILE_IMGDISPLAY) { 00482 layout->prv_w = 96; 00483 layout->prv_h = 96; 00484 layout->tile_border_x = 6; 00485 layout->tile_border_y = 6; 00486 layout->prv_border_x = 6; 00487 layout->prv_border_y = 6; 00488 layout->tile_w = layout->prv_w + 2*layout->prv_border_x; 00489 layout->tile_h = layout->prv_h + 2*layout->prv_border_y + textheight; 00490 layout->width= (int)(v2d->cur.xmax - v2d->cur.xmin - 2*layout->tile_border_x); 00491 layout->columns= layout->width / (layout->tile_w + 2*layout->tile_border_x); 00492 if(layout->columns > 0) 00493 layout->rows= numfiles/layout->columns + 1; // XXX dirty, modulo is zero 00494 else { 00495 layout->columns = 1; 00496 layout->rows= numfiles + 1; // XXX dirty, modulo is zero 00497 } 00498 layout->height= sfile->layout->rows*(layout->tile_h+2*layout->tile_border_y) + layout->tile_border_y*2; 00499 layout->flag = FILE_LAYOUT_VER; 00500 } else { 00501 layout->prv_w = 0; 00502 layout->prv_h = 0; 00503 layout->tile_border_x = 8; 00504 layout->tile_border_y = 2; 00505 layout->prv_border_x = 0; 00506 layout->prv_border_y = 0; 00507 layout->tile_h = textheight*3/2; 00508 layout->height= (int)(v2d->cur.ymax - v2d->cur.ymin - 2*layout->tile_border_y); 00509 layout->rows = layout->height / (layout->tile_h + 2*layout->tile_border_y); 00510 00511 column_widths(sfile->files, layout); 00512 00513 if (params->display == FILE_SHORTDISPLAY) { 00514 maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 + 00515 (int)layout->column_widths[COLUMN_NAME] + 12 + 00516 (int)layout->column_widths[COLUMN_SIZE] + 12; 00517 } else { 00518 maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 + 00519 (int)layout->column_widths[COLUMN_NAME] + 12 + 00520 #ifndef WIN32 00521 (int)layout->column_widths[COLUMN_MODE1] + 12 + 00522 (int)layout->column_widths[COLUMN_MODE2] + 12 + 00523 (int)layout->column_widths[COLUMN_MODE3] + 12 + 00524 (int)layout->column_widths[COLUMN_OWNER] + 12 + 00525 #endif 00526 (int)layout->column_widths[COLUMN_DATE] + 12 + 00527 (int)layout->column_widths[COLUMN_TIME] + 12 + 00528 (int)layout->column_widths[COLUMN_SIZE] + 12; 00529 00530 } 00531 layout->tile_w = maxlen; 00532 if(layout->rows > 0) 00533 layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero 00534 else { 00535 layout->rows = 1; 00536 layout->columns = numfiles + 1; // XXX dirty, modulo is zero 00537 } 00538 layout->width = sfile->layout->columns * (layout->tile_w + 2*layout->tile_border_x) + layout->tile_border_x*2; 00539 layout->flag = FILE_LAYOUT_HOR; 00540 } 00541 layout->dirty= 0; 00542 } 00543 00544 FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar) 00545 { 00546 if (!sfile->layout) { 00547 ED_fileselect_init_layout(sfile, ar); 00548 } 00549 return sfile->layout; 00550 } 00551 00552 void file_change_dir(bContext *C, int checkdir) 00553 { 00554 SpaceFile *sfile= CTX_wm_space_file(C); 00555 00556 if (sfile->params) { 00557 00558 ED_fileselect_clear(C, sfile); 00559 00560 if(checkdir && BLI_is_dir(sfile->params->dir)==0) { 00561 BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); 00562 /* could return but just refresh the current dir */ 00563 } 00564 filelist_setdir(sfile->files, sfile->params->dir); 00565 00566 if(folderlist_clear_next(sfile)) 00567 folderlist_free(sfile->folders_next); 00568 00569 folderlist_pushdir(sfile->folders_prev, sfile->params->dir); 00570 00571 } 00572 } 00573 00574 int file_select_match(struct SpaceFile *sfile, const char *pattern) 00575 { 00576 int match = 0; 00577 if (strchr(pattern, '*') || strchr(pattern, '?') || strchr(pattern, '[')) { 00578 int i; 00579 struct direntry *file; 00580 int n = filelist_numfiles(sfile->files); 00581 00582 for (i = 0; i < n; i++) { 00583 file = filelist_file(sfile->files, i); 00584 if (fnmatch(pattern, file->relname, 0) == 0) { 00585 file->selflag |= SELECTED_FILE; 00586 match = 1; 00587 } 00588 } 00589 } 00590 return match; 00591 } 00592 00593 void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) 00594 { 00595 SpaceFile *sfile= CTX_wm_space_file(C); 00596 00597 /* search if str matches the beginning of name */ 00598 if(str[0] && sfile->files) { 00599 char dirname[FILE_MAX]; 00600 00601 DIR *dir; 00602 struct dirent *de; 00603 00604 BLI_split_dirfile(str, dirname, NULL); 00605 00606 dir = opendir(dirname); 00607 00608 if(dir) { 00609 AutoComplete *autocpl= autocomplete_begin(str, FILE_MAX); 00610 00611 while ((de = readdir(dir)) != NULL) { 00612 if (strcmp(".", de->d_name)==0 || strcmp("..", de->d_name)==0) { 00613 /* pass */ 00614 } 00615 else { 00616 char path[FILE_MAX]; 00617 struct stat status; 00618 00619 BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); 00620 00621 if (stat(path, &status) == 0) { 00622 if (S_ISDIR(status.st_mode)) { /* is subdir */ 00623 autocomplete_do_name(autocpl, path); 00624 } 00625 } 00626 } 00627 } 00628 closedir(dir); 00629 00630 autocomplete_end(autocpl, str); 00631 if (BLI_exists(str)) { 00632 BLI_add_slash(str); 00633 } else { 00634 BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir)); 00635 } 00636 } 00637 } 00638 } 00639 00640 void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) 00641 { 00642 SpaceFile *sfile= CTX_wm_space_file(C); 00643 00644 /* search if str matches the beginning of name */ 00645 if(str[0] && sfile->files) { 00646 AutoComplete *autocpl= autocomplete_begin(str, FILE_MAX); 00647 int nentries = filelist_numfiles(sfile->files); 00648 int i; 00649 00650 for(i= 0; i<nentries; ++i) { 00651 struct direntry* file = filelist_file(sfile->files, i); 00652 if (file && S_ISREG(file->type)) { 00653 autocomplete_do_name(autocpl, file->relname); 00654 } 00655 } 00656 autocomplete_end(autocpl, str); 00657 } 00658 } 00659 00660 void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile) 00661 { 00662 thumbnails_stop(sfile->files, C); 00663 filelist_freelib(sfile->files); 00664 filelist_free(sfile->files); 00665 sfile->params->active_file = -1; 00666 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00667 } 00668 00669 void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile) 00670 { 00671 if(!sfile) return; 00672 if(sfile->op) { 00673 WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL); 00674 sfile->op = NULL; 00675 } 00676 00677 folderlist_free(sfile->folders_prev); 00678 folderlist_free(sfile->folders_next); 00679 00680 if (sfile->files) { 00681 ED_fileselect_clear(C, sfile); 00682 MEM_freeN(sfile->files); 00683 sfile->files= NULL; 00684 } 00685 00686 }