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