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