Blender  V2.93
filesel.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 
31 /* path/file handling stuff */
32 #ifdef WIN32
33 # include "BLI_winstuff.h"
34 # include <direct.h>
35 # include <io.h>
36 #else
37 # include <dirent.h>
38 # include <sys/times.h>
39 # include <unistd.h>
40 #endif
41 
42 #include "DNA_screen_types.h"
43 #include "DNA_space_types.h"
44 #include "DNA_userdef_types.h"
45 
46 #include "MEM_guardedalloc.h"
47 
48 #include "BLI_blenlib.h"
49 #include "BLI_fnmatch.h"
50 #include "BLI_math_base.h"
51 #include "BLI_utildefines.h"
52 
53 #include "BLO_readfile.h"
54 
55 #include "BLT_translation.h"
56 
57 #include "BKE_appdir.h"
58 #include "BKE_context.h"
59 #include "BKE_idtype.h"
60 #include "BKE_main.h"
61 #include "BKE_preferences.h"
62 
63 #include "BLF_api.h"
64 
65 #include "ED_fileselect.h"
66 #include "ED_screen.h"
67 
68 #include "WM_api.h"
69 #include "WM_types.h"
70 
71 #include "RNA_access.h"
72 
73 #include "UI_interface.h"
74 #include "UI_interface_icons.h"
75 #include "UI_view2d.h"
76 
77 #include "file_intern.h"
78 #include "filelist.h"
79 
80 #define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X)
81 
83 {
84  const char *blendfile_path = BKE_main_blendfile_path_from_global();
85 
86  /* operator has no setting for this */
87  params->active_file = -1;
88 
89  if (!params->dir[0]) {
90  if (blendfile_path[0] != '\0') {
91  BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir));
92  }
93  else {
94  const char *doc_path = BKE_appdir_folder_default();
95  if (doc_path) {
96  BLI_strncpy(params->dir, doc_path, sizeof(params->dir));
97  }
98  }
99  }
100 
102  folderlist_pushdir(sfile->folders_prev, params->dir);
103 
104  /* Switching thumbnails needs to recalc layout T28809. */
105  if (sfile->layout) {
106  sfile->layout->dirty = true;
107  }
108 }
109 
111 {
113  BLI_assert(sfile->op == NULL);
114 
115  FileAssetSelectParams *asset_params = sfile->asset_params;
116 
117  if (!asset_params) {
118  asset_params = sfile->asset_params = MEM_callocN(sizeof(*asset_params),
119  "FileAssetSelectParams");
122  asset_params->asset_library.custom_library_index = -1;
123  }
124 
125  FileSelectParams *base_params = &asset_params->base_params;
126  base_params->file[0] = '\0';
127  base_params->filter_glob[0] = '\0';
128  /* TODO this way of using filters to form categories is notably slower than specifying a
129  * "group" to read. That's because all types are read and filtering is applied afterwards. Would
130  * be nice if we could lazy-read individual groups. */
132  base_params->flag &= ~FILE_DIRSEL_ONLY;
133  base_params->filter |= FILE_TYPE_BLENDERLIB;
134  base_params->filter_id = FILTER_ID_OB | FILTER_ID_GR;
135  base_params->display = FILE_IMGDISPLAY;
136  base_params->sort = FILE_SORT_ALPHA;
137  base_params->recursion_level = 1;
138  /* 'SMALL' size by default. More reasonable since this is typically used as regular editor,
139  * space is more of an issue here. */
140  base_params->thumbnail_size = 96;
141 
142  fileselect_initialize_params_common(sfile, base_params);
143 }
144 
149 {
151 
153  wmOperator *op = sfile->op;
154 
155  const char *blendfile_path = BKE_main_blendfile_path_from_global();
156 
157  /* create new parameters if necessary */
158  if (!sfile->params) {
159  sfile->params = MEM_callocN(sizeof(FileSelectParams), "fileselparams");
160  /* set path to most recently opened .blend */
161  BLI_split_dirfile(blendfile_path,
162  sfile->params->dir,
163  sfile->params->file,
164  sizeof(sfile->params->dir),
165  sizeof(sfile->params->file));
166  sfile->params->filter_glob[0] = '\0';
170  }
171 
172  params = sfile->params;
173 
174  /* set the parameters from the operator, if it exists */
175  if (op) {
176  PropertyRNA *prop;
177  const bool is_files = (RNA_struct_find_property(op->ptr, "files") != NULL);
178  const bool is_filepath = (RNA_struct_find_property(op->ptr, "filepath") != NULL);
179  const bool is_filename = (RNA_struct_find_property(op->ptr, "filename") != NULL);
180  const bool is_directory = (RNA_struct_find_property(op->ptr, "directory") != NULL);
181  const bool is_relative_path = (RNA_struct_find_property(op->ptr, "relative_path") != NULL);
182 
184  params->title, WM_operatortype_name(op->type, op->ptr), sizeof(params->title));
185 
186  if ((prop = RNA_struct_find_property(op->ptr, "filemode"))) {
187  params->type = RNA_property_int_get(op->ptr, prop);
188  }
189  else {
190  params->type = FILE_SPECIAL;
191  }
192 
193  if (is_filepath && RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
194  char name[FILE_MAX];
195  RNA_string_get(op->ptr, "filepath", name);
196  if (params->type == FILE_LOADLIB) {
197  BLI_strncpy(params->dir, name, sizeof(params->dir));
198  params->file[0] = '\0';
199  }
200  else {
202  name, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
203  }
204  }
205  else {
206  if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", false)) {
207  RNA_string_get(op->ptr, "directory", params->dir);
208  params->file[0] = '\0';
209  }
210 
211  if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", false)) {
212  RNA_string_get(op->ptr, "filename", params->file);
213  }
214  }
215 
216  if (params->dir[0]) {
217  BLI_path_normalize_dir(blendfile_path, params->dir);
218  BLI_path_abs(params->dir, blendfile_path);
219  }
220 
221  params->flag = 0;
222  if (is_directory == true && is_filename == false && is_filepath == false &&
223  is_files == false) {
224  params->flag |= FILE_DIRSEL_ONLY;
225  }
226  if ((prop = RNA_struct_find_property(op->ptr, "check_existing"))) {
227  params->flag |= RNA_property_boolean_get(op->ptr, prop) ? FILE_CHECK_EXISTING : 0;
228  }
229  if ((prop = RNA_struct_find_property(op->ptr, "hide_props_region"))) {
230  params->flag |= RNA_property_boolean_get(op->ptr, prop) ? FILE_HIDE_TOOL_PROPS : 0;
231  }
232 
233  params->filter = 0;
234  if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) {
235  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0;
236  }
237  if ((prop = RNA_struct_find_property(op->ptr, "filter_blenlib"))) {
238  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDERLIB : 0;
239  }
240  if ((prop = RNA_struct_find_property(op->ptr, "filter_backup"))) {
241  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0;
242  }
243  if ((prop = RNA_struct_find_property(op->ptr, "filter_image"))) {
244  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0;
245  }
246  if ((prop = RNA_struct_find_property(op->ptr, "filter_movie"))) {
247  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0;
248  }
249  if ((prop = RNA_struct_find_property(op->ptr, "filter_python"))) {
250  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0;
251  }
252  if ((prop = RNA_struct_find_property(op->ptr, "filter_font"))) {
253  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FTFONT : 0;
254  }
255  if ((prop = RNA_struct_find_property(op->ptr, "filter_sound"))) {
256  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_SOUND : 0;
257  }
258  if ((prop = RNA_struct_find_property(op->ptr, "filter_text"))) {
259  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_TEXT : 0;
260  }
261  if ((prop = RNA_struct_find_property(op->ptr, "filter_archive"))) {
262  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_ARCHIVE : 0;
263  }
264  if ((prop = RNA_struct_find_property(op->ptr, "filter_folder"))) {
265  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FOLDER : 0;
266  }
267  if ((prop = RNA_struct_find_property(op->ptr, "filter_btx"))) {
268  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BTX : 0;
269  }
270  if ((prop = RNA_struct_find_property(op->ptr, "filter_collada"))) {
271  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_COLLADA : 0;
272  }
273  if ((prop = RNA_struct_find_property(op->ptr, "filter_alembic"))) {
274  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_ALEMBIC : 0;
275  }
276  if ((prop = RNA_struct_find_property(op->ptr, "filter_usd"))) {
277  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_USD : 0;
278  }
279  if ((prop = RNA_struct_find_property(op->ptr, "filter_volume"))) {
280  params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_VOLUME : 0;
281  }
282  if ((prop = RNA_struct_find_property(op->ptr, "filter_glob"))) {
283  /* Protection against Python scripts not setting proper size limit. */
284  char *tmp = RNA_property_string_get_alloc(
285  op->ptr, prop, params->filter_glob, sizeof(params->filter_glob), NULL);
286  if (tmp != params->filter_glob) {
287  BLI_strncpy(params->filter_glob, tmp, sizeof(params->filter_glob));
288  MEM_freeN(tmp);
289 
290  /* Fix stupid things that truncating might have generated,
291  * like last group being a 'match everything' wildcard-only one... */
293  }
295  }
296  else {
297  params->filter_glob[0] = '\0';
298  }
299 
300  if (params->filter != 0) {
301  if (U.uiflag & USER_FILTERFILEEXTS) {
302  params->flag |= FILE_FILTER;
303  }
304  else {
305  params->flag &= ~FILE_FILTER;
306  }
307  }
308 
309  if (U.uiflag & USER_HIDE_DOT) {
310  params->flag |= FILE_HIDE_DOT;
311  }
312  else {
313  params->flag &= ~FILE_HIDE_DOT;
314  }
315 
316  if (params->type == FILE_LOADLIB) {
317  params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0;
318  params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0;
319  params->flag |= RNA_boolean_get(op->ptr, "active_collection") ? FILE_ACTIVE_COLLECTION : 0;
320  }
321 
322  if ((prop = RNA_struct_find_property(op->ptr, "display_type"))) {
323  params->display = RNA_property_enum_get(op->ptr, prop);
324  }
325 
326  if (params->display == FILE_DEFAULTDISPLAY) {
328  }
329 
330  if ((prop = RNA_struct_find_property(op->ptr, "sort_method"))) {
331  params->sort = RNA_property_enum_get(op->ptr, prop);
332  }
333 
334  if (params->sort == FILE_SORT_DEFAULT) {
336  }
337 
338  if (is_relative_path) {
339  if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
340  if (!RNA_property_is_set_ex(op->ptr, prop, false)) {
341  RNA_property_boolean_set(op->ptr, prop, (U.flag & USER_RELPATHS) != 0);
342  }
343  }
344  }
345  }
346  else {
347  /* default values, if no operator */
348  params->type = FILE_UNIX;
350  params->flag &= ~FILE_DIRSEL_ONLY;
351  params->display = FILE_VERTICALDISPLAY;
352  params->sort = FILE_SORT_ALPHA;
353  params->filter = 0;
354  params->filter_glob[0] = '\0';
355  }
356 
358 
359  return params;
360 }
361 
366 {
367  switch ((eFileBrowse_Mode)sfile->browse_mode) {
369  if (!sfile->params) {
371  }
372  return sfile->params;
374  if (!sfile->asset_params) {
376  }
377  return &sfile->asset_params->base_params;
378  }
379 
380  BLI_assert(!"Invalid browse mode set in file space.");
381  return NULL;
382 }
383 
388 {
389  if (!sfile) {
390  /* Sometimes called in poll before space type was checked. */
391  return NULL;
392  }
393 
394  switch ((eFileBrowse_Mode)sfile->browse_mode) {
396  return sfile->params;
398  return (FileSelectParams *)sfile->asset_params;
399  }
400 
401  BLI_assert(!"Invalid browse mode set in file space.");
402  return NULL;
403 }
404 
406 {
407  return (sfile->browse_mode == FILE_BROWSE_MODE_FILES) ? sfile->params : NULL;
408 }
409 
411 {
412  return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) ? sfile->asset_params : NULL;
413 }
414 
416 {
418  FileSelectParams *base_params = &asset_params->base_params;
419  bUserAssetLibrary *user_library = NULL;
420 
421  /* Ensure valid repository, or fall-back to local one. */
422  if (library->type == FILE_ASSET_LIBRARY_CUSTOM) {
423  BLI_assert(library->custom_library_index >= 0);
424 
426  library->custom_library_index);
427  if (!user_library) {
429  }
430  }
431 
432  switch (library->type) {
434  base_params->dir[0] = '\0';
435  break;
437  BLI_assert(user_library);
438  BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir));
439  break;
440  }
441  base_params->type = (library->type == FILE_ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET : FILE_LOADLIB;
442 }
443 
445 {
447  if (asset_params) {
448  fileselect_refresh_asset_params(asset_params);
449  }
450 }
451 
453 {
454  return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS);
455 }
456 
458 {
459  if (!ED_fileselect_is_asset_browser(sfile)) {
460  return NULL;
461  }
462 
464  const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
465  if (file == NULL) {
466  return NULL;
467  }
468 
469  return filelist_file_get_id(file);
470 }
471 
472 static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data)
473 {
474  ID *asset_id = (ID *)custom_data;
475  ED_fileselect_activate_by_id(sfile, asset_id, false);
476 }
477 
478 void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool deferred)
479 {
480  if (!ED_fileselect_is_asset_browser(sfile)) {
481  return;
482  }
483 
484  /* If there are filelist operations running now ("pending" true) or soon ("force reset" true),
485  * there is a fair chance that the to-be-activated ID will only be present after these operations
486  * have completed. Defer activation until then. */
487  if (deferred || filelist_pending(sfile->files) || filelist_needs_force_reset(sfile->files)) {
488  /* This should be thread-safe, as this function is likely called from the main thread, and
489  * notifiers (which cause a call to the on-reload callback function) are handled on the main
490  * thread as well. */
492  return;
493  }
494 
496  struct FileList *files = sfile->files;
497 
498  const int num_files_filtered = filelist_files_ensure(files);
499  for (int file_index = 0; file_index < num_files_filtered; ++file_index) {
500  const FileDirEntry *file = filelist_file_ex(files, file_index, false);
501 
502  if (filelist_file_get_id(file) != asset_id) {
504  continue;
505  }
506 
507  params->active_file = file_index;
509 
510  /* Keep looping to deselect the other files. */
511  }
512 
515 }
516 
517 /* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA
518  * may also be remembered, but only conditionally. */
519 #define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT)
520 
521 void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized)
522 {
523  /* Get DPI/pixel-size independent size to be stored in preferences. */
524  WM_window_set_dpi(win); /* Ensure the DPI is taken from the right window. */
525 
526  win_size[0] = WM_window_pixels_x(win) / UI_DPI_FAC;
527  win_size[1] = WM_window_pixels_y(win) / UI_DPI_FAC;
528 
529  *is_maximized = WM_window_is_maximized(win);
530 }
531 
533 {
534  PropertyRNA *prop;
535  return (sfile->op == NULL) ||
536  !(prop = RNA_struct_find_property(sfile->op->ptr, "display_type")) ||
537  (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_DEFAULTDISPLAY);
538 }
539 
541 {
542  PropertyRNA *prop;
543  return (sfile->op == NULL) ||
544  !(prop = RNA_struct_find_property(sfile->op->ptr, "sort_method")) ||
545  (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_SORT_DEFAULT);
546 }
547 
549 {
550  wmOperator *op = sfile->op;
551  UserDef_FileSpaceData *sfile_udata = &U.file_space_data;
552 
554 
556  if (!op) {
557  return;
558  }
559 
560  params->thumbnail_size = sfile_udata->thumbnail_size;
561  params->details_flags = sfile_udata->details_flags;
562  params->filter_id = sfile_udata->filter_id;
563 
564  /* Combine flags we take from params with the flags we take from userdef. */
565  params->flag = (params->flag & ~PARAMS_FLAGS_REMEMBERED) |
566  (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED);
567 
569  params->display = sfile_udata->display_type;
570  }
572  params->sort = sfile_udata->sort_type;
573  /* For the default sorting, also take invert flag from userdef. */
574  params->flag = (params->flag & ~FILE_SORT_INVERT) | (sfile_udata->flag & FILE_SORT_INVERT);
575  }
576 }
577 
586  const int temp_win_size[2],
587  const bool is_maximized)
588 {
590  UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data;
591  UserDef_FileSpaceData sfile_udata_old = U.file_space_data;
592 
593  sfile_udata_new->thumbnail_size = params->thumbnail_size;
594  sfile_udata_new->details_flags = params->details_flags;
595  sfile_udata_new->flag = params->flag & PARAMS_FLAGS_REMEMBERED;
596  sfile_udata_new->filter_id = params->filter_id;
597 
598  /* In some rare cases, operators ask for a specific display or sort type (e.g. chronological
599  * sorting for "Recover Auto Save"). So the settings are optimized for a specific operation.
600  * Don't let that change the userdef memory for more general cases. */
602  sfile_udata_new->display_type = params->display;
603  }
605  sfile_udata_new->sort_type = params->sort;
606  /* In this case also remember the invert flag. */
607  sfile_udata_new->flag = (sfile_udata_new->flag & ~FILE_SORT_INVERT) |
608  (params->flag & FILE_SORT_INVERT);
609  }
610 
611  if (temp_win_size && !is_maximized) {
612  sfile_udata_new->temp_win_sizex = temp_win_size[0];
613  sfile_udata_new->temp_win_sizey = temp_win_size[1];
614  }
615 
616  /* Tag prefs as dirty if something has changed. */
617  if (memcmp(sfile_udata_new, &sfile_udata_old, sizeof(sfile_udata_old)) != 0) {
618  U.runtime.is_dirty = true;
619  }
620 }
621 
625 void fileselect_file_set(SpaceFile *sfile, const int index)
626 {
627  const struct FileDirEntry *file = filelist_file(sfile->files, index);
628  if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) {
630  BLI_strncpy(params->file, file->relpath, FILE_MAXFILE);
631  }
632 }
633 
635 {
636  int numfiles;
637 
638  /* Values in pixels.
639  *
640  * - *_item: size of each (row|col), (including padding)
641  * - *_view: (x|y) size of the view.
642  * - *_over: extra pixels, to take into account, when the fit isn't exact
643  * (needed since you may see the end of the previous column and the beginning of the next).
644  *
645  * Could be more clever and take scrolling into account,
646  * but for now don't bother.
647  */
648  if (layout->flag & FILE_LAYOUT_HOR) {
649  const int x_item = layout->tile_w + (2 * layout->tile_border_x);
650  const int x_view = (int)(BLI_rctf_size_x(&region->v2d.cur));
651  const int x_over = x_item - (x_view % x_item);
652  numfiles = (int)((float)(x_view + x_over) / (float)(x_item));
653  return numfiles * layout->rows;
654  }
655 
656  const int y_item = layout->tile_h + (2 * layout->tile_border_y);
657  const int y_view = (int)(BLI_rctf_size_y(&region->v2d.cur)) - layout->offset_top;
658  const int y_over = y_item - (y_view % y_item);
659  numfiles = (int)((float)(y_view + y_over) / (float)(y_item));
660  return numfiles * layout->flow_columns;
661 }
662 
663 static bool is_inside(int x, int y, int cols, int rows)
664 {
665  return ((x >= 0) && (x < cols) && (y >= 0) && (y < rows));
666 }
667 
669 {
670  int colmin, colmax, rowmin, rowmax;
671  FileSelection sel;
672  sel.first = sel.last = -1;
673 
674  if (layout == NULL) {
675  return sel;
676  }
677 
678  colmin = (rect->xmin) / (layout->tile_w + 2 * layout->tile_border_x);
679  rowmin = (rect->ymin - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
680  colmax = (rect->xmax) / (layout->tile_w + 2 * layout->tile_border_x);
681  rowmax = (rect->ymax - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
682 
683  if (is_inside(colmin, rowmin, layout->flow_columns, layout->rows) ||
684  is_inside(colmax, rowmax, layout->flow_columns, layout->rows)) {
685  CLAMP(colmin, 0, layout->flow_columns - 1);
686  CLAMP(rowmin, 0, layout->rows - 1);
687  CLAMP(colmax, 0, layout->flow_columns - 1);
688  CLAMP(rowmax, 0, layout->rows - 1);
689  }
690 
691  if ((colmin > layout->flow_columns - 1) || (rowmin > layout->rows - 1)) {
692  sel.first = -1;
693  }
694  else {
695  if (layout->flag & FILE_LAYOUT_HOR) {
696  sel.first = layout->rows * colmin + rowmin;
697  }
698  else {
699  sel.first = colmin + layout->flow_columns * rowmin;
700  }
701  }
702  if ((colmax > layout->flow_columns - 1) || (rowmax > layout->rows - 1)) {
703  sel.last = -1;
704  }
705  else {
706  if (layout->flag & FILE_LAYOUT_HOR) {
707  sel.last = layout->rows * colmax + rowmax;
708  }
709  else {
710  sel.last = colmax + layout->flow_columns * rowmax;
711  }
712  }
713 
714  return sel;
715 }
716 
718 {
719  int offsetx, offsety;
720  int active_file;
721 
722  if (layout == NULL) {
723  return -1;
724  }
725 
726  offsetx = (x) / (layout->tile_w + 2 * layout->tile_border_x);
727  offsety = (y - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
728 
729  if (offsetx > layout->flow_columns - 1) {
730  return -1;
731  }
732  if (offsety > layout->rows - 1) {
733  return -1;
734  }
735 
736  if (layout->flag & FILE_LAYOUT_HOR) {
737  active_file = layout->rows * offsetx + offsety;
738  }
739  else {
740  active_file = offsetx + layout->flow_columns * offsety;
741  }
742  return active_file;
743 }
744 
749 void ED_fileselect_layout_maskrect(const FileLayout *layout, const View2D *v2d, rcti *r_rect)
750 {
751  *r_rect = v2d->mask;
752  r_rect->ymax -= layout->offset_top;
753 }
754 
755 bool ED_fileselect_layout_is_inside_pt(const FileLayout *layout, const View2D *v2d, int x, int y)
756 {
757  rcti maskrect;
758  ED_fileselect_layout_maskrect(layout, v2d, &maskrect);
759  return BLI_rcti_isect_pt(&maskrect, x, y);
760 }
761 
763  const View2D *v2d,
764  const rcti *rect,
765  rcti *r_dst)
766 {
767  rcti maskrect;
768  ED_fileselect_layout_maskrect(layout, v2d, &maskrect);
769  return BLI_rcti_isect(&maskrect, rect, r_dst);
770 }
771 
772 void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y)
773 {
774  if (layout->flag == FILE_LAYOUT_HOR) {
775  *x = layout->tile_border_x +
776  (tile / layout->rows) * (layout->tile_w + 2 * layout->tile_border_x);
777  *y = layout->offset_top + layout->tile_border_y +
778  (tile % layout->rows) * (layout->tile_h + 2 * layout->tile_border_y);
779  }
780  else {
781  *x = layout->tile_border_x +
782  ((tile) % layout->flow_columns) * (layout->tile_w + 2 * layout->tile_border_x);
783  *y = layout->offset_top + layout->tile_border_y +
784  ((tile) / layout->flow_columns) * (layout->tile_h + 2 * layout->tile_border_y);
785  }
786 }
787 
792  const FileLayout *layout,
793  int x,
794  int y)
795 {
796  rcti header_rect = v2d->mask;
797  header_rect.ymin = header_rect.ymax - layout->attribute_column_header_h;
798  return BLI_rcti_isect_pt(&header_rect, x, y);
799 }
800 
803 {
804  switch (column) {
805  case COLUMN_NAME:
806  /* Always enabled */
807  return true;
808  case COLUMN_DATETIME:
809  return (params->details_flags & FILE_DETAILS_DATETIME) != 0;
810  case COLUMN_SIZE:
811  return (params->details_flags & FILE_DETAILS_SIZE) != 0;
812  default:
813  return false;
814  }
815 }
816 
821  const FileSelectParams *params,
822  FileLayout *layout,
823  int x)
824 {
825  float mx, my;
826  int offset_tile;
827 
828  UI_view2d_region_to_view(v2d, x, v2d->mask.ymax - layout->offset_top - 1, &mx, &my);
829  offset_tile = ED_fileselect_layout_offset(
830  layout, (int)(v2d->tot.xmin + mx), (int)(v2d->tot.ymax - my));
831  if (offset_tile > -1) {
832  int tile_x, tile_y;
833  int pos_x = 0;
834  int rel_x; /* x relative to the hovered tile */
835 
836  ED_fileselect_layout_tilepos(layout, offset_tile, &tile_x, &tile_y);
837  /* Column header drawing doesn't use left tile border, so subtract it. */
838  rel_x = mx - (tile_x - layout->tile_border_x);
839 
840  for (FileAttributeColumnType column = 0; column < ATTRIBUTE_COLUMN_MAX; column++) {
842  continue;
843  }
844  const int width = layout->attribute_columns[column].width;
845 
846  if (IN_RANGE(rel_x, pos_x, pos_x + width)) {
847  return column;
848  }
849 
850  pos_x += width;
851  }
852  }
853 
854  return COLUMN_NONE;
855 }
856 
857 float file_string_width(const char *str)
858 {
859  const uiStyle *style = UI_style_get();
860  float width;
861 
862  UI_fontstyle_set(&style->widget);
863  if (style->widget.kerning == 1) { /* for BLF_width */
865  }
866 
868 
869  if (style->widget.kerning == 1) {
871  }
872 
873  return width;
874 }
875 
877 {
878 #if 0
879  float s;
880  char tmp[2] = "X";
881  const uiStyle *style = UI_style_get();
882  UI_fontstyle_set(&style->widget);
883  s = BLF_height(style->widget.uifont_id, tmp);
884  return style->widget.points;
885 #else
886  const uiStyle *style = UI_style_get();
887  UI_fontstyle_set(&style->widget);
888  return style->widget.points * UI_DPI_FAC;
889 #endif
890 }
891 
893 {
894  FileAttributeColumn *columns = layout->attribute_columns;
895  const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size);
896  const int pad = small_size ? 0 : ATTRIBUTE_COLUMN_PADDING * 2;
897 
898  for (int i = 0; i < ATTRIBUTE_COLUMN_MAX; i++) {
899  layout->attribute_columns[i].width = 0;
900  }
901 
902  /* Biggest possible reasonable values... */
903  columns[COLUMN_DATETIME].width = file_string_width(small_size ? "23/08/89" :
904  "23 Dec 6789, 23:59") +
905  pad;
906  columns[COLUMN_SIZE].width = file_string_width(small_size ? "98.7 M" : "098.7 MiB") + pad;
907  if (params->display == FILE_IMGDISPLAY) {
908  columns[COLUMN_NAME].width = ((float)params->thumbnail_size / 8.0f) * UI_UNIT_X;
909  }
910  /* Name column uses remaining width */
911  else {
912  int remwidth = layout->tile_w;
913  for (FileAttributeColumnType column_type = ATTRIBUTE_COLUMN_MAX - 1; column_type >= 0;
914  column_type--) {
915  if ((column_type == COLUMN_NAME) ||
917  continue;
918  }
919  remwidth -= columns[column_type].width;
920  }
921  columns[COLUMN_NAME].width = remwidth;
922  }
923 }
924 
926 {
928 
929  layout->attribute_columns[COLUMN_NAME].name = N_("Name");
932  layout->attribute_columns[COLUMN_DATETIME].name = N_("Date Modified");
935  layout->attribute_columns[COLUMN_SIZE].name = N_("Size");
938 }
939 
940 void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region)
941 {
943  FileLayout *layout = NULL;
944  View2D *v2d = &region->v2d;
945  int numfiles;
946  int textheight;
947 
948  if (sfile->layout == NULL) {
949  sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout");
950  sfile->layout->dirty = true;
951  }
952  else if (sfile->layout->dirty == false) {
953  return;
954  }
955 
956  numfiles = filelist_files_ensure(sfile->files);
957  textheight = (int)file_font_pointsize();
958  layout = sfile->layout;
959  layout->textheight = textheight;
960 
961  if (params->display == FILE_IMGDISPLAY) {
962  layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
963  layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
964  layout->tile_border_x = 0.3f * UI_UNIT_X;
965  layout->tile_border_y = 0.3f * UI_UNIT_X;
966  layout->prv_border_x = 0.3f * UI_UNIT_X;
967  layout->prv_border_y = 0.3f * UI_UNIT_Y;
968  layout->tile_w = layout->prv_w + 2 * layout->prv_border_x;
969  layout->tile_h = layout->prv_h + 2 * layout->prv_border_y + textheight;
970  layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
971  layout->flow_columns = layout->width / (layout->tile_w + 2 * layout->tile_border_x);
972  layout->attribute_column_header_h = 0;
973  layout->offset_top = 0;
974  if (layout->flow_columns > 0) {
975  layout->rows = divide_ceil_u(numfiles, layout->flow_columns);
976  }
977  else {
978  layout->flow_columns = 1;
979  layout->rows = numfiles;
980  }
981  layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) +
982  layout->tile_border_y * 2 - layout->offset_top;
983  layout->flag = FILE_LAYOUT_VER;
984  }
985  else if (params->display == FILE_VERTICALDISPLAY) {
986  int rowcount;
987 
988  layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
989  layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
990  layout->tile_border_x = 0.4f * UI_UNIT_X;
991  layout->tile_border_y = 0.1f * UI_UNIT_Y;
992  layout->tile_h = textheight * 3 / 2;
993  layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
994  layout->tile_w = layout->width;
995  layout->flow_columns = 1;
996  layout->attribute_column_header_h = layout->tile_h * 1.2f + 2 * layout->tile_border_y;
997  layout->offset_top = layout->attribute_column_header_h;
998  rowcount = (int)(BLI_rctf_size_y(&v2d->cur) - layout->offset_top - 2 * layout->tile_border_y) /
999  (layout->tile_h + 2 * layout->tile_border_y);
1001 
1002  layout->rows = MAX2(rowcount, numfiles);
1003  BLI_assert(layout->rows != 0);
1004  layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) +
1005  layout->tile_border_y * 2 + layout->offset_top;
1006  layout->flag = FILE_LAYOUT_VER;
1007  }
1008  else if (params->display == FILE_HORIZONTALDISPLAY) {
1009  layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
1010  layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
1011  layout->tile_border_x = 0.4f * UI_UNIT_X;
1012  layout->tile_border_y = 0.1f * UI_UNIT_Y;
1013  layout->tile_h = textheight * 3 / 2;
1014  layout->attribute_column_header_h = 0;
1015  layout->offset_top = layout->attribute_column_header_h;
1016  layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y);
1017  /* Padding by full scrollbar H is too much, can overlap tile border Y. */
1018  layout->rows = (layout->height - V2D_SCROLL_HEIGHT + layout->tile_border_y) /
1019  (layout->tile_h + 2 * layout->tile_border_y);
1022 
1023  if (layout->rows > 0) {
1024  layout->flow_columns = divide_ceil_u(numfiles, layout->rows);
1025  }
1026  else {
1027  layout->rows = 1;
1028  layout->flow_columns = numfiles;
1029  }
1030  layout->width = sfile->layout->flow_columns * (layout->tile_w + 2 * layout->tile_border_x) +
1031  layout->tile_border_x * 2;
1032  layout->flag = FILE_LAYOUT_HOR;
1033  }
1034  layout->dirty = false;
1035 }
1036 
1038 {
1039  if (!sfile->layout) {
1040  ED_fileselect_init_layout(sfile, region);
1041  }
1042  return sfile->layout;
1043 }
1044 
1050 {
1051  /* May happen when manipulating non-active spaces. */
1052  if (UNLIKELY(area->spacetype != SPACE_FILE)) {
1053  return;
1054  }
1055  SpaceFile *sfile = area->spacedata.first;
1057  if (params) {
1060  if (LIKELY(scene != NULL)) {
1061  ED_fileselect_clear(wm, scene, sfile);
1062  }
1063 
1064  /* Clear search string, it is very rare to want to keep that filter while changing dir,
1065  * and usually very annoying to keep it actually! */
1066  params->filter_search[0] = '\0';
1067  params->active_file = -1;
1068 
1069  if (!filelist_is_dir(sfile->files, params->dir)) {
1070  BLI_strncpy(params->dir, filelist_dir(sfile->files), sizeof(params->dir));
1071  /* could return but just refresh the current dir */
1072  }
1073  filelist_setdir(sfile->files, params->dir);
1074 
1075  if (folderlist_clear_next(sfile)) {
1076  folderlist_free(sfile->folders_next);
1077  }
1078 
1079  folderlist_pushdir(sfile->folders_prev, params->dir);
1080 
1082  }
1083 }
1084 
1086 {
1087  bScreen *screen = CTX_wm_screen(C);
1088  ScrArea *area = CTX_wm_area(C);
1089  ED_file_change_dir_ex(C, screen, area);
1090 }
1091 
1092 int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
1093 {
1094  int match = 0;
1095 
1096  int n = filelist_files_ensure(sfile->files);
1097 
1098  /* select any file that matches the pattern, this includes exact match
1099  * if the user selects a single file by entering the filename
1100  */
1101  for (int i = 0; i < n; i++) {
1102  FileDirEntry *file = filelist_file(sfile->files, i);
1103  /* Do not check whether file is a file or dir here! Causes T44243
1104  * (we do accept dirs at this stage). */
1105  if (fnmatch(pattern, file->relpath, 0) == 0) {
1107  if (!match) {
1108  BLI_strncpy(matched_file, file->relpath, FILE_MAX);
1109  }
1110  match++;
1111  }
1112  }
1113 
1114  return match;
1115 }
1116 
1117 int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
1118 {
1119  SpaceFile *sfile = CTX_wm_space_file(C);
1120  int match = AUTOCOMPLETE_NO_MATCH;
1121 
1122  /* search if str matches the beginning of name */
1123  if (str[0] && sfile->files) {
1124  char dirname[FILE_MAX];
1125 
1126  DIR *dir;
1127  struct dirent *de;
1128 
1130 
1131  dir = opendir(dirname);
1132 
1133  if (dir) {
1135 
1136  while ((de = readdir(dir)) != NULL) {
1137  if (FILENAME_IS_CURRPAR(de->d_name)) {
1138  /* pass */
1139  }
1140  else {
1141  char path[FILE_MAX];
1142  BLI_stat_t status;
1143 
1144  BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
1145 
1146  if (BLI_stat(path, &status) == 0) {
1147  if (S_ISDIR(status.st_mode)) { /* is subdir */
1148  UI_autocomplete_update_name(autocpl, path);
1149  }
1150  }
1151  }
1152  }
1153  closedir(dir);
1154 
1155  match = UI_autocomplete_end(autocpl, str);
1156  if (match == AUTOCOMPLETE_FULL_MATCH) {
1158  }
1159  }
1160  }
1161 
1162  return match;
1163 }
1164 
1165 int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
1166 {
1167  SpaceFile *sfile = CTX_wm_space_file(C);
1168  int match = AUTOCOMPLETE_NO_MATCH;
1169 
1170  /* search if str matches the beginning of name */
1171  if (str[0] && sfile->files) {
1173  int nentries = filelist_files_ensure(sfile->files);
1174 
1175  for (int i = 0; i < nentries; i++) {
1176  FileDirEntry *file = filelist_file(sfile->files, i);
1177  UI_autocomplete_update_name(autocpl, file->relpath);
1178  }
1179  match = UI_autocomplete_end(autocpl, str);
1180  }
1181 
1182  return match;
1183 }
1184 
1185 void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
1186 {
1187  /* only NULL in rare cases - T29734. */
1188  if (sfile->files) {
1189  filelist_readjob_stop(wm, owner_scene);
1190  filelist_freelib(sfile->files);
1191  filelist_clear(sfile->files);
1192  }
1193 
1195  params->highlight_file = -1;
1197 }
1198 
1199 void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
1200 {
1201  if (!sfile) {
1202  return;
1203  }
1204  if (sfile->op) {
1205  wmWindow *temp_win = (wm->winactive && WM_window_is_temp_screen(wm->winactive)) ?
1206  wm->winactive :
1207  NULL;
1208  if (temp_win) {
1209  int win_size[2];
1210  bool is_maximized;
1211 
1212  ED_fileselect_window_params_get(temp_win, win_size, &is_maximized);
1213  ED_fileselect_params_to_userdef(sfile, win_size, is_maximized);
1214  }
1215  else {
1216  ED_fileselect_params_to_userdef(sfile, NULL, false);
1217  }
1218 
1220  sfile->op = NULL;
1221  }
1222 
1223  folder_history_list_free(sfile);
1224 
1225  if (sfile->files) {
1226  ED_fileselect_clear(wm, owner_scene, sfile);
1227  filelist_free(sfile->files);
1228  MEM_freeN(sfile->files);
1229  sfile->files = NULL;
1230  }
1231 }
1232 
1238 {
1239  BLI_assert(params->rename_flag != 0);
1240 
1242  0) {
1243  return;
1244  }
1245 
1246  BLI_assert(params->renamefile[0] != '\0');
1247 
1248  const int idx = filelist_file_findpath(sfile->files, params->renamefile);
1249  if (idx >= 0) {
1250  FileDirEntry *file = filelist_file(sfile->files, idx);
1251  BLI_assert(file != NULL);
1252 
1253  if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) {
1255  params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
1256  }
1257  else if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_PENDING) != 0) {
1259  params->renamefile[0] = '\0';
1261  }
1262  }
1263  /* File listing is now async, only reset renaming if matching entry is not found
1264  * when file listing is not done. */
1265  else if (filelist_is_ready(sfile->files)) {
1266  params->renamefile[0] = '\0';
1267  params->rename_flag = 0;
1268  }
1269 }
1270 
1272 {
1273  bScreen *screen = WM_window_get_active_screen(win);
1274 
1275  ED_screen_areas_iter (win, screen, area) {
1276  if (area->spacetype == SPACE_FILE) {
1277  SpaceFile *sfile = area->spacedata.first;
1278 
1279  if (sfile->op == file_operator) {
1280  return area;
1281  }
1282  }
1283  }
1284 
1285  return NULL;
1286 }
typedef float(TangentPoint)[2]
const char * BKE_appdir_folder_default(void)
Definition: appdir.c:157
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct SpaceFile * CTX_wm_space_file(const bContext *C)
Definition: context.c:818
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:439
struct bUserAssetLibrary * BKE_preferences_asset_library_find_from_index(const struct UserDef *userdef, int index) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
#define BLF_KERNING_DEFAULT
Definition: BLF_api.h:272
float BLF_width(int fontid, const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:723
#define BLF_DRAW_STR_DUMMY_MAX
Definition: BLF_api.h:283
void BLF_disable(int fontid, int option)
Definition: blf.c:283
float BLF_height(int fontid, const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:752
void BLF_enable(int fontid, int option)
Definition: blf.c:274
#define BLI_assert(a)
Definition: BLI_assert.h:58
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct stat BLI_stat_t
Definition: BLI_fileops.h:67
void BLI_path_normalize_dir(const char *relabase, char *dir) ATTR_NONNULL(2)
Definition: path_util.c:266
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
Definition: path_util.c:1682
#define FILE_MAXFILE
bool BLI_path_extension_glob_validate(char *ext_fnmatch) ATTR_NONNULL()
Definition: path_util.c:1541
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
#define FILENAME_IS_CURRPAR(_n)
int BLI_path_slash_ensure(char *string) ATTR_NONNULL()
Definition: path_util.c:1981
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
Definition: path_util.c:1654
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y)
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string_utf8.c:258
#define IN_RANGE(a, b, c)
#define UNUSED(x)
#define MAX2(a, b)
#define UNLIKELY(x)
#define LIKELY(x)
Compatibility-like things for windows.
struct __dirstream DIR
Definition: BLI_winstuff.h:100
int closedir(DIR *dp)
#define S_ISDIR(x)
Definition: BLI_winstuff.h:64
const char * dirname(char *path)
struct dirent * readdir(DIR *dp)
DIR * opendir(const char *path)
external readfile function prototypes.
const struct UserDef U_default
#define N_(msgid)
#define FILTER_ID_OB
Definition: DNA_ID.h:722
#define FILTER_ID_GR
Definition: DNA_ID.h:711
@ FILE_SORT_DEFAULT
@ FILE_SORT_ALPHA
@ FILE_SORT_TIME
@ FILE_SORT_SIZE
@ FILE_LOADLIB
@ FILE_SPECIAL
@ FILE_UNIX
@ FILE_MAIN_ASSET
@ FILE_TYPE_BTX
@ FILE_TYPE_BLENDER
@ FILE_TYPE_ALEMBIC
@ FILE_TYPE_ARCHIVE
@ FILE_TYPE_TEXT
@ FILE_TYPE_COLLADA
@ FILE_TYPE_PYSCRIPT
@ FILE_TYPE_BLENDER_BACKUP
@ FILE_TYPE_VOLUME
@ FILE_TYPE_MOVIE
@ FILE_TYPE_SOUND
@ FILE_TYPE_FOLDER
@ FILE_TYPE_FTFONT
@ FILE_TYPE_BLENDERLIB
@ FILE_TYPE_OPERATOR
@ FILE_TYPE_USD
@ FILE_TYPE_IMAGE
@ FILE_TYPE_DIR
@ SPACE_FILE
@ FILE_PARAMS_RENAME_POSTSCROLL_PENDING
@ FILE_PARAMS_RENAME_ACTIVE
@ FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE
@ FILE_PARAMS_RENAME_PENDING
@ FILE_DETAILS_DATETIME
@ FILE_DETAILS_SIZE
eFileBrowse_Mode
@ FILE_BROWSE_MODE_ASSETS
@ FILE_BROWSE_MODE_FILES
@ FILE_SEL_EDITING
@ FILE_SEL_HIGHLIGHTED
@ FILE_SEL_SELECTED
@ FILE_VERTICALDISPLAY
@ FILE_IMGDISPLAY
@ FILE_HORIZONTALDISPLAY
@ FILE_DEFAULTDISPLAY
@ FILE_ASSET_LIBRARY_LOCAL
@ FILE_ASSET_LIBRARY_CUSTOM
@ FILE_ACTIVE_COLLECTION
@ FILE_HIDE_TOOL_PROPS
@ FILE_CHECK_EXISTING
@ FILE_AUTOSELECT
@ FILE_FILTER
@ FILE_SORT_INVERT
@ FILE_DIRSEL_ONLY
@ FILE_LINK
@ FILE_ASSETS_ONLY
@ FILE_HIDE_DOT
@ USER_HIDE_DOT
@ USER_FILTERFILEEXTS
@ USER_RELPATHS
#define FILE_LAYOUT_HOR
Definition: ED_fileselect.h:44
#define FILE_LAYOUT_VER
Definition: ED_fileselect.h:45
FileAttributeColumnType
Definition: ED_fileselect.h:47
@ COLUMN_DATETIME
Definition: ED_fileselect.h:50
@ ATTRIBUTE_COLUMN_MAX
Definition: ED_fileselect.h:53
@ COLUMN_NAME
Definition: ED_fileselect.h:49
@ COLUMN_NONE
Definition: ED_fileselect.h:48
@ COLUMN_SIZE
Definition: ED_fileselect.h:51
#define ED_screen_areas_iter(win, screen, area_name)
Definition: ED_screen.h:189
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
#define C
Definition: RandGen.cpp:39
#define UI_UNIT_Y
#define AUTOCOMPLETE_FULL_MATCH
void UI_fontstyle_set(const struct uiFontStyle *fs)
const struct uiStyle * UI_style_get(void)
#define AUTOCOMPLETE_NO_MATCH
AutoComplete * UI_autocomplete_begin(const char *startname, size_t maxlen)
Definition: interface.c:4782
@ UI_STYLE_TEXT_LEFT
@ UI_STYLE_TEXT_RIGHT
int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
Definition: interface.c:4829
#define UI_DPI_FAC
Definition: UI_interface.h:309
#define UI_UNIT_X
void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
Definition: interface.c:4795
#define V2D_SCROLL_HEIGHT
Definition: UI_view2d.h:67
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
#define NA_ACTIVATED
Definition: WM_types.h:468
#define NC_ASSET
Definition: WM_types.h:305
#define NC_SPACE
Definition: WM_types.h:293
#define NA_SELECTED
Definition: WM_types.h:467
#define ND_SPACE_FILE_LIST
Definition: WM_types.h:419
unsigned int U
Definition: btGjkEpa3.h:78
FILE * file
Scene scene
#define str(s)
void file_on_reload_callback_register(struct SpaceFile *sfile, onReloadFn callback, onReloadFnData custom_data)
Definition: space_file.c:403
#define SMALL_SIZE_CHECK(_size)
Definition: file_intern.h:37
#define ATTRIBUTE_COLUMN_PADDING
Definition: file_intern.h:35
void * onReloadFnData
Definition: file_intern.h:116
void file_draw_check_ex(bContext *C, struct ScrArea *area)
Definition: file_ops.c:1664
void filelist_free(struct FileList *filelist)
Definition: filelist.c:1796
bool filelist_is_ready(struct FileList *filelist)
Definition: filelist.c:1910
void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene)
Definition: filelist.c:3500
void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile)
Definition: filelist.c:213
int filelist_file_findpath(struct FileList *filelist, const char *filename)
Definition: filelist.c:2046
void filelist_freelib(struct FileList *filelist)
Definition: filelist.c:1819
void folder_history_list_free(SpaceFile *sfile)
Definition: filelist.c:240
void filelist_setdir(struct FileList *filelist, char *r_dir)
Definition: filelist.c:1876
int folderlist_clear_next(struct SpaceFile *sfile)
Definition: filelist.c:155
void folderlist_pushdir(ListBase *folderlist, const char *dir)
Definition: filelist.c:119
ID * filelist_file_get_id(const FileDirEntry *file)
Definition: filelist.c:2071
void folderlist_free(ListBase *folderlist)
Definition: filelist.c:177
void filelist_clear(struct FileList *filelist)
Definition: filelist.c:1791
uint filelist_entry_select_set(const FileList *filelist, const FileDirEntry *entry, FileSelType select, uint flag, FileCheckType check)
Definition: filelist.c:2608
FileDirEntry * filelist_file(struct FileList *filelist, int index)
Definition: filelist.c:2041
bool filelist_pending(struct FileList *filelist)
Definition: filelist.c:1915
int filelist_files_ensure(FileList *filelist)
Definition: filelist.c:1931
FileDirEntry * filelist_file_ex(struct FileList *filelist, const int index, const bool use_request)
Definition: filelist.c:1993
bool filelist_needs_force_reset(FileList *filelist)
Definition: filelist.c:1900
bool filelist_is_dir(struct FileList *filelist, const char *path)
Definition: filelist.c:1868
const char * filelist_dir(struct FileList *filelist)
Definition: filelist.c:1863
@ FILE_SEL_REMOVE
Definition: filelist.h:39
@ FILE_SEL_ADD
Definition: filelist.h:40
@ CHECK_ALL
Definition: filelist.h:47
void ED_fileselect_params_to_userdef(SpaceFile *sfile, const int temp_win_size[2], const bool is_maximized)
Definition: filesel.c:585
struct ID * ED_fileselect_active_asset_get(const SpaceFile *sfile)
Definition: filesel.c:457
int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
Definition: filesel.c:1165
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
Definition: filesel.c:1092
int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *region)
Definition: filesel.c:634
int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
Definition: filesel.c:1117
FileSelectParams * ED_fileselect_get_active_params(const SpaceFile *sfile)
Definition: filesel.c:387
int ED_fileselect_layout_offset(FileLayout *layout, int x, int y)
Definition: filesel.c:717
FileSelectParams * ED_fileselect_get_file_params(const SpaceFile *sfile)
Definition: filesel.c:405
float file_string_width(const char *str)
Definition: filesel.c:857
static void fileselect_ensure_updated_asset_params(SpaceFile *sfile)
Definition: filesel.c:110
bool file_attribute_column_header_is_inside(const View2D *v2d, const FileLayout *layout, int x, int y)
Definition: filesel.c:791
void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
Definition: filesel.c:1185
#define VERTLIST_MAJORCOLUMN_WIDTH
Definition: filesel.c:80
static bool is_inside(int x, int y, int cols, int rows)
Definition: filesel.c:663
void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
Definition: filesel.c:1199
static void fileselect_initialize_params_common(SpaceFile *sfile, FileSelectParams *params)
Definition: filesel.c:82
void fileselect_refresh_params(SpaceFile *sfile)
Definition: filesel.c:444
FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d, const FileSelectParams *params, FileLayout *layout, int x)
Definition: filesel.c:820
FileLayout * ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *region)
Definition: filesel.c:1037
FileSelectParams * ED_fileselect_ensure_active_params(SpaceFile *sfile)
Definition: filesel.c:365
void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
Definition: filesel.c:1049
void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y)
Definition: filesel.c:772
bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
Definition: filesel.c:452
FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *rect)
Definition: filesel.c:668
void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool deferred)
Definition: filesel.c:478
bool file_attribute_column_type_enabled(const FileSelectParams *params, FileAttributeColumnType column)
Definition: filesel.c:801
void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
Definition: filesel.c:548
static void file_attribute_columns_init(const FileSelectParams *params, FileLayout *layout)
Definition: filesel.c:925
float file_font_pointsize(void)
Definition: filesel.c:876
void fileselect_file_set(SpaceFile *sfile, const int index)
Definition: filesel.c:625
bool ED_fileselect_layout_is_inside_pt(const FileLayout *layout, const View2D *v2d, int x, int y)
Definition: filesel.c:755
#define PARAMS_FLAGS_REMEMBERED
Definition: filesel.c:519
static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
Definition: filesel.c:415
void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params)
Definition: filesel.c:1237
FileAssetSelectParams * ED_fileselect_get_asset_params(const SpaceFile *sfile)
Definition: filesel.c:410
void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region)
Definition: filesel.c:940
static bool file_select_use_default_display_type(const SpaceFile *sfile)
Definition: filesel.c:532
static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data)
Definition: filesel.c:472
static void file_attribute_columns_widths(const FileSelectParams *params, FileLayout *layout)
Definition: filesel.c:892
static FileSelectParams * fileselect_ensure_updated_file_params(SpaceFile *sfile)
Definition: filesel.c:148
bool ED_fileselect_layout_isect_rect(const FileLayout *layout, const View2D *v2d, const rcti *rect, rcti *r_dst)
Definition: filesel.c:762
void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized)
Definition: filesel.c:521
void ED_fileselect_layout_maskrect(const FileLayout *layout, const View2D *v2d, rcti *r_rect)
Definition: filesel.c:749
void ED_file_change_dir(bContext *C)
Definition: filesel.c:1085
static bool file_select_use_default_sort_type(const SpaceFile *sfile)
Definition: filesel.c:540
ScrArea * ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator *file_operator)
Definition: filesel.c:1271
static FT_Library library
Definition: freetypefont.c:51
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
MINLINE uint divide_ceil_u(uint a, uint b)
static void area(int d1, int d2, int e1, int e2, float weights[2])
bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost)
Definition: rna_access.c:6645
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
Definition: rna_access.c:6673
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2331
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3339
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2607
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
FileSelectAssetLibraryUID asset_library
FileSelectParams base_params
const char * name
Definition: ED_fileselect.h:58
int prv_border_x
Definition: ED_fileselect.h:79
int prv_border_y
Definition: ED_fileselect.h:80
FileAttributeColumn attribute_columns[ATTRIBUTE_COLUMN_MAX]
Definition: ED_fileselect.h:92
int attribute_column_header_h
Definition: ED_fileselect.h:72
int tile_border_y
Definition: ED_fileselect.h:78
int flow_columns
Definition: ED_fileselect.h:84
int tile_border_x
Definition: ED_fileselect.h:77
unsigned short thumbnail_size
Definition: DNA_ID.h:273
struct FileLayout * layout
struct wmOperator * op
ListBase * folders_prev
struct FileList * files
FileSelectParams * params
FileAssetSelectParams * asset_params
ListBase * folders_next
UserDef_FileSpaceData file_space_data
char * d_name
Definition: BLI_winstuff.h:96
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
uiFontStyle widget
struct wmOperatorType * type
struct PointerRNA * ptr
struct wmWindow * winactive
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval)
@ EVT_FILESELECT_EXTERNAL_CANCEL
const char * WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties)
Scene * WM_windows_scene_get_from_screen(const wmWindowManager *wm, const bScreen *screen)
Definition: wm_window.c:2217
int WM_window_pixels_y(const wmWindow *win)
Definition: wm_window.c:2136
void WM_window_set_dpi(const wmWindow *win)
Definition: wm_window.c:469
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2372
bool WM_window_is_temp_screen(const wmWindow *win)
Definition: wm_window.c:2383
bool WM_window_is_maximized(const wmWindow *win)
Definition: wm_window.c:2192
int WM_window_pixels_x(const wmWindow *win)
Definition: wm_window.c:2130