Blender V4.5
fsmenu.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13
14#include "MEM_guardedalloc.h"
15
16#include "BLI_fileops.h"
17#include "BLI_path_utils.hh"
18#include "BLI_string.h"
19#include "BLI_string_utils.hh"
20#include "BLI_utildefines.h"
21
22#include "BLT_translation.hh"
23
24#include "BKE_appdir.hh"
25
26#include "ED_fileselect.hh"
27
28#include "UI_resources.hh"
29#include "WM_api.hh"
30#include "WM_types.hh"
31
32#include "fsmenu.h" /* include ourselves */
33
34/* FSMENU HANDLING */
35
43
44static FSMenu *g_fsmenu = nullptr;
45
47{
48 if (!g_fsmenu) {
49 g_fsmenu = MEM_callocN<FSMenu>(__func__);
50 }
51 return g_fsmenu;
52}
53
55{
56 FSMenuEntry *fsm_head = nullptr;
57
58 switch (category) {
60 fsm_head = fsmenu->fsmenu_system;
61 break;
63 fsm_head = fsmenu->fsmenu_system_bookmarks;
64 break;
66 fsm_head = fsmenu->fsmenu_bookmarks;
67 break;
69 fsm_head = fsmenu->fsmenu_recent;
70 break;
72 fsm_head = fsmenu->fsmenu_other;
73 break;
74 }
75 return fsm_head;
76}
77
78void ED_fsmenu_set_category(FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head)
79{
80 switch (category) {
82 fsmenu->fsmenu_system = fsm_head;
83 break;
85 fsmenu->fsmenu_system_bookmarks = fsm_head;
86 break;
88 fsmenu->fsmenu_bookmarks = fsm_head;
89 break;
91 fsmenu->fsmenu_recent = fsm_head;
92 break;
94 fsmenu->fsmenu_other = fsm_head;
95 break;
96 }
97}
98
100{
101 FSMenuEntry *fsm_iter;
102 int count = 0;
103
104 for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) {
105 count++;
106 }
107
108 return count;
109}
110
112{
113 FSMenuEntry *fsm_iter;
114
115 for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx;
116 fsm_iter = fsm_iter->next)
117 {
118 idx--;
119 }
120
121 return fsm_iter;
122}
123
125{
126 return fsentry->path;
127}
128
129void ED_fsmenu_entry_set_path(FSMenuEntry *fsentry, const char *path)
130{
131 if ((!fsentry->path || !path || !STREQ(path, fsentry->path)) && (fsentry->path != path)) {
132 char tmp_name[FILE_MAXFILE];
133
134 MEM_SAFE_FREE(fsentry->path);
135
136 fsentry->path = (path && path[0]) ? BLI_strdup(path) : nullptr;
137
138 const std::optional<std::string> user_config_dir = BKE_appdir_folder_id_create(
139 BLENDER_USER_CONFIG, nullptr);
140
141 if (user_config_dir.has_value()) {
142 BLI_path_join(tmp_name, sizeof(tmp_name), user_config_dir->c_str(), BLENDER_BOOKMARK_FILE);
143 fsmenu_write_file(ED_fsmenu_get(), tmp_name);
144 }
145 }
146}
147
149{
150 return (fsentry->icon) ? fsentry->icon : ICON_FILE_FOLDER;
151}
152
153void ED_fsmenu_entry_set_icon(FSMenuEntry *fsentry, const int icon)
154{
155 fsentry->icon = icon;
156}
157
158static void fsmenu_entry_generate_name(FSMenuEntry *fsentry, char *name, size_t name_size)
159{
160 int offset = 0;
161 int len = name_size;
162
163 if (BLI_path_name_at_index(fsentry->path, -1, &offset, &len)) {
164 /* use as size */
165 len += 1;
166 }
167
168 BLI_strncpy(name, &fsentry->path[offset], std::min(size_t(len), name_size));
169 if (!name[0]) {
170 name[0] = '/';
171 name[1] = '\0';
172 }
173}
174
176{
177 if (fsentry->name[0]) {
178 return fsentry->name;
179 }
180
181 /* Here we abuse fsm_iter->name, keeping first char nullptr. */
182 char *name = fsentry->name + 1;
183 size_t name_size = sizeof(fsentry->name) - 1;
184
185 fsmenu_entry_generate_name(fsentry, name, name_size);
186 return name;
187}
188
189void ED_fsmenu_entry_set_name(FSMenuEntry *fsentry, const char *name)
190{
191 if (!STREQ(name, fsentry->name)) {
192 char tmp_name[FILE_MAXFILE];
193 size_t tmp_name_size = sizeof(tmp_name);
194
195 fsmenu_entry_generate_name(fsentry, tmp_name, tmp_name_size);
196 if (!name[0] || STREQ(tmp_name, name)) {
197 /* reset name to default behavior. */
198 fsentry->name[0] = '\0';
199 }
200 else {
201 STRNCPY(fsentry->name, name);
202 }
203
204 const std::optional<std::string> user_config_dir = BKE_appdir_folder_id_create(
205 BLENDER_USER_CONFIG, nullptr);
206
207 if (user_config_dir.has_value()) {
208 BLI_path_join(tmp_name, sizeof(tmp_name), user_config_dir->c_str(), BLENDER_BOOKMARK_FILE);
209 fsmenu_write_file(ED_fsmenu_get(), tmp_name);
210 }
211 }
212}
213
215{
216 if (fsentry->path && fsentry->path[0]) {
217#ifdef WIN32
218 /* XXX Special case, always consider those as valid.
219 * Thanks to Windows, which can spend five seconds to perform a mere stat() call on those paths
220 * See #43684. */
221 const char *exceptions[] = {"A:\\", "B:\\", nullptr};
222 const size_t exceptions_len[] = {strlen(exceptions[0]), strlen(exceptions[1]), 0};
223 int i;
224
225 for (i = 0; exceptions[i]; i++) {
226 if (STRCASEEQLEN(fsentry->path, exceptions[i], exceptions_len[i])) {
227 fsentry->valid = true;
228 return;
229 }
230 }
231#endif
232 fsentry->valid = BLI_is_dir(fsentry->path);
233 }
234 else {
235 fsentry->valid = false;
236 }
237}
238
239short fsmenu_can_save(FSMenu *fsmenu, FSMenuCategory category, int idx)
240{
241 FSMenuEntry *fsm_iter;
242
243 for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx;
244 fsm_iter = fsm_iter->next)
245 {
246 idx--;
247 }
248
249 return fsm_iter ? fsm_iter->save : 0;
250}
251
253 FSMenuCategory category,
254 const char *path,
255 const char *name,
256 int icon,
258{
259 const uint path_len = strlen(path);
260 BLI_assert(path_len > 0);
261 if (path_len == 0) {
262 return;
263 }
265 const bool has_trailing_slash = (path[path_len - 1] == SEP);
266 FSMenuEntry *fsm_prev;
267 FSMenuEntry *fsm_iter;
268 FSMenuEntry *fsm_head;
269
270 fsm_head = ED_fsmenu_get_category(fsmenu, category);
271 fsm_prev = fsm_head; /* this is odd and not really correct? */
272
273 for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) {
274 if (fsm_iter->path) {
275 /* Compare, with/without the trailing slash in 'path'. */
276 const int cmp_ret = BLI_path_ncmp(path, fsm_iter->path, path_len);
277 if (cmp_ret == 0 && STREQ(fsm_iter->path + path_len, has_trailing_slash ? "" : SEP_STR)) {
278 if (flag & FS_INSERT_FIRST) {
279 if (fsm_iter != fsm_head) {
280 fsm_prev->next = fsm_iter->next;
281 fsm_iter->next = fsm_head;
282 ED_fsmenu_set_category(fsmenu, category, fsm_iter);
283 }
284 }
285 return;
286 }
287 if ((flag & FS_INSERT_SORTED) && cmp_ret < 0) {
288 break;
289 }
290 }
291 else {
292 /* if we're bookmarking this, file should come
293 * before the last separator, only automatically added
294 * current dir go after the last separator. */
295 if (flag & FS_INSERT_SAVE) {
296 break;
297 }
298 }
299 }
300
301 fsm_iter = MEM_mallocN<FSMenuEntry>("fsme");
302 fsm_iter->path = has_trailing_slash ? BLI_strdup(path) : BLI_string_joinN(path, SEP_STR);
303 fsm_iter->save = (flag & FS_INSERT_SAVE) != 0;
304
305 /* If entry is also in another list, use that icon and maybe name. */
306 /* On macOS we get icons and names for System Bookmarks from the FS_CATEGORY_OTHER list. */
308
309 const FSMenuCategory cats[] = {
314 };
315 int i = ARRAY_SIZE(cats);
316 if (category == FS_CATEGORY_BOOKMARKS) {
317 i--;
318 }
319
320 while (i--) {
321 FSMenuEntry *tfsm = ED_fsmenu_get_category(fsmenu, cats[i]);
322 for (; tfsm; tfsm = tfsm->next) {
323 if (STREQ(tfsm->path, fsm_iter->path)) {
324 icon = tfsm->icon;
325 if (tfsm->name[0] && (!name || !name[0])) {
326 name = DATA_(tfsm->name);
327 }
328 break;
329 }
330 }
331 if (tfsm) {
332 break;
333 }
334 }
335 }
336
337 if (name && name[0]) {
338 STRNCPY(fsm_iter->name, name);
339 }
340 else {
341 fsm_iter->name[0] = '\0';
342 }
343
344 ED_fsmenu_entry_set_icon(fsm_iter, icon);
345
347 fsm_iter->valid = true;
348 }
349 else {
351 }
352
353 if (fsm_prev) {
354 if (flag & FS_INSERT_FIRST) {
355 fsm_iter->next = fsm_head;
356 ED_fsmenu_set_category(fsmenu, category, fsm_iter);
357 }
358 else {
359 fsm_iter->next = fsm_prev->next;
360 fsm_prev->next = fsm_iter;
361 }
362 }
363 else {
364 fsm_iter->next = fsm_head;
365 ED_fsmenu_set_category(fsmenu, category, fsm_iter);
366 }
367}
368
369void fsmenu_remove_entry(FSMenu *fsmenu, FSMenuCategory category, int idx)
370{
371 FSMenuEntry *fsm_prev = nullptr;
372 FSMenuEntry *fsm_iter;
373 FSMenuEntry *fsm_head;
374
375 fsm_head = ED_fsmenu_get_category(fsmenu, category);
376
377 for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) {
378 idx--;
379 }
380
381 if (fsm_iter) {
382 /* you should only be able to remove entries that were
383 * not added by default, like windows drives.
384 * also separators (where path == nullptr) shouldn't be removed */
385 if (fsm_iter->save && fsm_iter->path) {
386
387 /* remove fsme from list */
388 if (fsm_prev) {
389 fsm_prev->next = fsm_iter->next;
390 }
391 else {
392 fsm_head = fsm_iter->next;
393 ED_fsmenu_set_category(fsmenu, category, fsm_head);
394 }
395 /* free entry */
396 MEM_freeN(fsm_iter->path);
397 MEM_freeN(fsm_iter);
398 }
399 }
400}
401
402bool fsmenu_write_file(FSMenu *fsmenu, const char *filepath)
403{
404 FSMenuEntry *fsm_iter = nullptr;
405 char fsm_name[FILE_MAX];
406 int nwritten = 0;
407
408 FILE *fp = BLI_fopen(filepath, "w");
409 if (!fp) {
410 return false;
411 }
412
413 bool has_error = false;
414 has_error |= (fprintf(fp, "[Bookmarks]\n") < 0);
415 for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter;
416 fsm_iter = fsm_iter->next)
417 {
418 if (fsm_iter->path && fsm_iter->save) {
419 fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name));
420 if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) {
421 has_error |= (fprintf(fp, "!%s\n", fsm_iter->name) < 0);
422 }
423 has_error |= (fprintf(fp, "%s\n", fsm_iter->path) < 0);
424 }
425 }
426 has_error = (fprintf(fp, "[Recent]\n") < 0);
427 for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT);
428 fsm_iter && (nwritten < FSMENU_RECENT_MAX);
429 fsm_iter = fsm_iter->next, nwritten++)
430 {
431 if (fsm_iter->path && fsm_iter->save) {
432 fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name));
433 if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) {
434 has_error |= (fprintf(fp, "!%s\n", fsm_iter->name) < 0);
435 }
436 has_error |= (fprintf(fp, "%s\n", fsm_iter->path) < 0);
437 }
438 }
439 fclose(fp);
440
441 return !has_error;
442}
443
444void fsmenu_read_bookmarks(FSMenu *fsmenu, const char *filepath)
445{
446 char line[FILE_MAXDIR];
447 char name[FILE_MAXFILE];
449 FILE *fp;
450
451 fp = BLI_fopen(filepath, "r");
452 if (!fp) {
453 return;
454 }
455
456 name[0] = '\0';
457
458 while (fgets(line, sizeof(line), fp) != nullptr) { /* read a line */
459 if (STRPREFIX(line, "[Bookmarks]")) {
460 category = FS_CATEGORY_BOOKMARKS;
461 }
462 else if (STRPREFIX(line, "[Recent]")) {
463 category = FS_CATEGORY_RECENT;
464 }
465 else if (line[0] == '!') {
466 int len = strlen(line);
467 if (len > 0) {
468 if (line[len - 1] == '\n') {
469 line[len - 1] = '\0';
470 }
471 STRNCPY(name, line + 1);
472 }
473 }
474 else {
475 int len = strlen(line);
476 if (len > 0) {
477 if (line[len - 1] == '\n') {
478 line[len - 1] = '\0';
479 }
480 /* don't do this because it can be slow on network drives,
481 * having a bookmark from a drive that's ejected or so isn't
482 * all _that_ bad */
483#if 0
484 if (BLI_exists(line))
485#endif
486 {
487 fsmenu_insert_entry(fsmenu, category, line, name, ICON_FILE_FOLDER, FS_INSERT_SAVE);
488 }
489 }
490 /* always reset name. */
491 name[0] = '\0';
492 }
493 }
494 fclose(fp);
495}
496
497static void fsmenu_free_category(FSMenu *fsmenu, FSMenuCategory category)
498{
499 FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category);
500
501 while (fsm_iter) {
502 FSMenuEntry *fsm_next = fsm_iter->next;
503
504 if (fsm_iter->path) {
505 MEM_freeN(fsm_iter->path);
506 }
507 MEM_freeN(fsm_iter);
508
509 fsm_iter = fsm_next;
510 }
511}
512
514{
517
520
521 /* Add all entries to system category */
522 fsmenu_read_system(fsmenu, true);
523}
524
525static void fsmenu_free_ex(FSMenu **fsmenu)
526{
527 if (*fsmenu != nullptr) {
533 MEM_freeN(*fsmenu);
534 }
535
536 *fsmenu = nullptr;
537}
538
540{
542}
543
544static void fsmenu_copy_category(FSMenu *fsmenu_dst,
545 FSMenu *fsmenu_src,
546 const FSMenuCategory category)
547{
548 FSMenuEntry *fsm_dst_prev = nullptr, *fsm_dst_head = nullptr;
549 FSMenuEntry *fsm_src_iter = ED_fsmenu_get_category(fsmenu_src, category);
550
551 for (; fsm_src_iter != nullptr; fsm_src_iter = fsm_src_iter->next) {
552 FSMenuEntry *fsm_dst = static_cast<FSMenuEntry *>(MEM_dupallocN(fsm_src_iter));
553 if (fsm_dst->path != nullptr) {
554 fsm_dst->path = static_cast<char *>(MEM_dupallocN(fsm_dst->path));
555 }
556
557 if (fsm_dst_prev != nullptr) {
558 fsm_dst_prev->next = fsm_dst;
559 }
560 else {
561 fsm_dst_head = fsm_dst;
562 }
563 fsm_dst_prev = fsm_dst;
564 }
565
566 ED_fsmenu_set_category(fsmenu_dst, category, fsm_dst_head);
567}
568
581
582int fsmenu_get_active_indices(FSMenu *fsmenu, enum FSMenuCategory category, const char *dir)
583{
584 FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category);
585 int i;
586
587 for (i = 0; fsm_iter; fsm_iter = fsm_iter->next, i++) {
588 if (BLI_path_cmp(dir, fsm_iter->path) == 0) {
589 return i;
590 }
591 }
592
593 return -1;
594}
595
601static void fsmenu_bookmark_validate_job_startjob(void *fsmenuv, wmJobWorkerStatus *worker_status)
602{
603 FSMenu *fsmenu = static_cast<FSMenu *>(fsmenuv);
604
605 int categories[] = {
607
608 for (size_t i = ARRAY_SIZE(categories); i--;) {
609 FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, FSMenuCategory(categories[i]));
610 for (; fsm_iter; fsm_iter = fsm_iter->next) {
611 if (worker_status->stop) {
612 return;
613 }
614 /* Note that we do not really need atomics primitives or thread locks here, since this only
615 * sets one short, which is assumed to be *atomic* enough for us here. */
617 worker_status->do_update = true;
618 }
619 }
620}
621
622static void fsmenu_bookmark_validate_job_update(void *fsmenuv)
623{
624 FSMenu *fsmenu_job = static_cast<FSMenu *>(fsmenuv);
625
626 int categories[] = {
628
629 for (size_t i = ARRAY_SIZE(categories); i--;) {
630 FSMenuEntry *fsm_iter_src = ED_fsmenu_get_category(fsmenu_job, FSMenuCategory(categories[i]));
632 FSMenuCategory(categories[i]));
633 for (; fsm_iter_dst != nullptr; fsm_iter_dst = fsm_iter_dst->next) {
634 while (fsm_iter_src != nullptr && !STREQ(fsm_iter_dst->path, fsm_iter_src->path)) {
635 fsm_iter_src = fsm_iter_src->next;
636 }
637 if (fsm_iter_src == nullptr) {
638 return;
639 }
640 fsm_iter_dst->valid = fsm_iter_src->valid;
641 }
642 }
643}
644
645static void fsmenu_bookmark_validate_job_end(void *fsmenuv)
646{
647 /* In case there would be some dangling update... */
649}
650
651static void fsmenu_bookmark_validate_job_free(void *fsmenuv)
652{
653 FSMenu *fsmenu = static_cast<FSMenu *>(fsmenuv);
654 fsmenu_free_ex(&fsmenu);
655}
656
658{
659 wmJob *wm_job;
660 FSMenu *fsmenu_job = fsmenu_copy(g_fsmenu);
661
662 /* setup job */
663 wm_job = WM_jobs_get(wm,
664 wm->winactive,
665 wm,
666 "Validating Bookmarks...",
667 eWM_JobFlag(0),
671 WM_jobs_callbacks(wm_job,
673 nullptr,
676
677 /* start the job */
678 WM_jobs_start(wm, wm_job);
679}
680
685
#define BLENDER_BOOKMARK_FILE
@ BLENDER_USER_CONFIG
std::optional< std::string > BKE_appdir_folder_id_create(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
Definition appdir.cc:777
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:373
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:456
#define BLI_path_ncmp
#define FILE_MAXFILE
#define FILE_MAX
#define BLI_path_join(...)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define SEP
#define FILE_MAXDIR
bool BLI_path_name_at_index(const char *__restrict path, int index, int *__restrict r_offset, int *__restrict r_len) ATTR_NONNULL(1
#define BLI_path_cmp
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define BLI_string_joinN(...)
unsigned int uint
#define STRPREFIX(a, b)
#define ARRAY_SIZE(arr)
#define UNUSED_VARS_NDEBUG(...)
#define STRCASEEQLEN(a, b, n)
#define ELEM(...)
#define STREQ(a, b)
#define DATA_(msgid)
FSMenuCategory
@ FS_CATEGORY_RECENT
@ FS_CATEGORY_BOOKMARKS
@ FS_CATEGORY_SYSTEM_BOOKMARKS
@ FS_CATEGORY_OTHER
@ FS_CATEGORY_SYSTEM
FSMenuInsert
@ FS_INSERT_SAVE
@ FS_INSERT_FIRST
@ FS_INSERT_NO_VALIDATE
@ FS_INSERT_SORTED
Read Guarded memory(de)allocation.
@ WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE
Definition WM_api.hh:1753
eWM_JobFlag
Definition WM_api.hh:1709
#define NC_SPACE
Definition WM_types.hh:389
#define ND_SPACE_FILE_LIST
Definition WM_types.hh:521
FSMenuEntry * ED_fsmenu_get_entry(FSMenu *fsmenu, FSMenuCategory category, int idx)
Definition fsmenu.cc:111
int ED_fsmenu_get_nentries(FSMenu *fsmenu, FSMenuCategory category)
Definition fsmenu.cc:99
FSMenu * ED_fsmenu_get()
Definition fsmenu.cc:46
static void fsmenu_free_ex(FSMenu **fsmenu)
Definition fsmenu.cc:525
static void fsmenu_bookmark_validate_job_start(wmWindowManager *wm)
Definition fsmenu.cc:657
static void fsmenu_bookmark_validate_job_free(void *fsmenuv)
Definition fsmenu.cc:651
short fsmenu_can_save(FSMenu *fsmenu, FSMenuCategory category, int idx)
Definition fsmenu.cc:239
static void fsmenu_bookmark_validate_job_startjob(void *fsmenuv, wmJobWorkerStatus *worker_status)
Definition fsmenu.cc:601
void ED_fsmenu_entry_set_name(FSMenuEntry *fsentry, const char *name)
Definition fsmenu.cc:189
char * ED_fsmenu_entry_get_name(FSMenuEntry *fsentry)
Definition fsmenu.cc:175
int fsmenu_get_active_indices(FSMenu *fsmenu, enum FSMenuCategory category, const char *dir)
Definition fsmenu.cc:582
void ED_fsmenu_set_category(FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head)
Definition fsmenu.cc:78
static void fsmenu_bookmark_validate_job_update(void *fsmenuv)
Definition fsmenu.cc:622
char * ED_fsmenu_entry_get_path(FSMenuEntry *fsentry)
Definition fsmenu.cc:124
int ED_fsmenu_entry_get_icon(FSMenuEntry *fsentry)
Definition fsmenu.cc:148
void fsmenu_refresh_bookmarks_status(wmWindowManager *wm, FSMenu *fsmenu)
Definition fsmenu.cc:686
static FSMenu * g_fsmenu
Definition fsmenu.cc:44
static void fsmenu_free_category(FSMenu *fsmenu, FSMenuCategory category)
Definition fsmenu.cc:497
void fsmenu_entry_refresh_valid(FSMenuEntry *fsentry)
Definition fsmenu.cc:214
void fsmenu_remove_entry(FSMenu *fsmenu, FSMenuCategory category, int idx)
Definition fsmenu.cc:369
static void fsmenu_copy_category(FSMenu *fsmenu_dst, FSMenu *fsmenu_src, const FSMenuCategory category)
Definition fsmenu.cc:544
FSMenuEntry * ED_fsmenu_get_category(FSMenu *fsmenu, FSMenuCategory category)
Definition fsmenu.cc:54
static void fsmenu_bookmark_validate_job_stop(wmWindowManager *wm)
Definition fsmenu.cc:681
static FSMenu * fsmenu_copy(FSMenu *fsmenu)
Definition fsmenu.cc:569
void fsmenu_read_bookmarks(FSMenu *fsmenu, const char *filepath)
Definition fsmenu.cc:444
void ED_fsmenu_entry_set_path(FSMenuEntry *fsentry, const char *path)
Definition fsmenu.cc:129
void fsmenu_refresh_system_category(FSMenu *fsmenu)
Definition fsmenu.cc:513
void fsmenu_free()
Definition fsmenu.cc:539
static void fsmenu_entry_generate_name(FSMenuEntry *fsentry, char *name, size_t name_size)
Definition fsmenu.cc:158
void ED_fsmenu_entry_set_icon(FSMenuEntry *fsentry, const int icon)
Definition fsmenu.cc:153
static void fsmenu_bookmark_validate_job_end(void *fsmenuv)
Definition fsmenu.cc:645
void fsmenu_insert_entry(FSMenu *fsmenu, FSMenuCategory category, const char *path, const char *name, int icon, FSMenuInsert flag)
Definition fsmenu.cc:252
bool fsmenu_write_file(FSMenu *fsmenu, const char *filepath)
Definition fsmenu.cc:402
#define FSMENU_RECENT_MAX
Definition fsmenu.h:14
void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
#define MEM_SAFE_FREE(v)
int count
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
char name[256]
FSMenuEntry * next
FSMenuEntry * fsmenu_bookmarks
Definition fsmenu.cc:39
FSMenuEntry * fsmenu_other
Definition fsmenu.cc:41
FSMenuEntry * fsmenu_system_bookmarks
Definition fsmenu.cc:38
FSMenuEntry * fsmenu_recent
Definition fsmenu.cc:40
FSMenuEntry * fsmenu_system
Definition fsmenu.cc:37
struct wmWindow * winactive
i
Definition text_draw.cc:230
#define SEP_STR
Definition unit.cc:39
uint len
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:353
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:456
void WM_jobs_kill_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:598
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
Definition wm_jobs.cc:190
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition wm_jobs.cc:365
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:337
uint8_t flag
Definition wm_window.cc:139