81
typedef struct FSMenu {
82
82
FSMenuEntry *fsmenu_system;
83
FSMenuEntry *fsmenu_system_bookmarks;
83
84
FSMenuEntry *fsmenu_bookmarks;
84
85
FSMenuEntry *fsmenu_recent;
88
88
static FSMenu *g_fsmenu = NULL;
90
struct FSMenu* fsmenu_get(void)
90
FSMenu *fsmenu_get(void)
93
g_fsmenu=MEM_callocN(sizeof(struct FSMenu), "fsmenu");
93
g_fsmenu = MEM_callocN(sizeof(struct FSMenu), "fsmenu");
98
static FSMenuEntry *fsmenu_get_category(struct FSMenu* fsmenu, FSMenuCategory category)
100
FSMenuEntry *fsms = NULL;
103
case FS_CATEGORY_SYSTEM:
104
fsms = fsmenu->fsmenu_system;
106
case FS_CATEGORY_BOOKMARKS:
107
fsms = fsmenu->fsmenu_bookmarks;
109
case FS_CATEGORY_RECENT:
110
fsms = fsmenu->fsmenu_recent;
116
static void fsmenu_set_category(struct FSMenu* fsmenu, FSMenuCategory category, FSMenuEntry *fsms)
119
case FS_CATEGORY_SYSTEM:
120
fsmenu->fsmenu_system = fsms;
122
case FS_CATEGORY_BOOKMARKS:
123
fsmenu->fsmenu_bookmarks = fsms;
125
case FS_CATEGORY_RECENT:
126
fsmenu->fsmenu_recent = fsms;
131
int fsmenu_get_nentries(struct FSMenu* fsmenu, FSMenuCategory category)
136
for (fsme= fsmenu_get_category(fsmenu, category); fsme; fsme= fsme->next)
98
static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category)
100
FSMenuEntry *fsm_head = NULL;
103
case FS_CATEGORY_SYSTEM:
104
fsm_head = fsmenu->fsmenu_system;
106
case FS_CATEGORY_SYSTEM_BOOKMARKS:
107
fsm_head = fsmenu->fsmenu_system_bookmarks;
109
case FS_CATEGORY_BOOKMARKS:
110
fsm_head = fsmenu->fsmenu_bookmarks;
112
case FS_CATEGORY_RECENT:
113
fsm_head = fsmenu->fsmenu_recent;
119
static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head)
122
case FS_CATEGORY_SYSTEM:
123
fsmenu->fsmenu_system = fsm_head;
125
case FS_CATEGORY_SYSTEM_BOOKMARKS:
126
fsmenu->fsmenu_system_bookmarks = fsm_head;
128
case FS_CATEGORY_BOOKMARKS:
129
fsmenu->fsmenu_bookmarks = fsm_head;
131
case FS_CATEGORY_RECENT:
132
fsmenu->fsmenu_recent = fsm_head;
137
int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category)
139
FSMenuEntry *fsm_iter;
142
for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) {
142
char *fsmenu_get_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
146
for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
149
return fsme?fsme->path:NULL;
152
short fsmenu_can_save (struct FSMenu* fsmenu, FSMenuCategory category, int idx)
156
for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
159
return fsme?fsme->save:0;
162
void fsmenu_insert_entry(struct FSMenu* fsmenu, FSMenuCategory category, const char *path, int sorted, short save)
168
fsms = fsmenu_get_category(fsmenu, category);
171
for (; fsme; prev= fsme, fsme= fsme->next) {
173
const int cmp_ret= BLI_path_cmp(path, fsme->path);
149
char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx)
151
FSMenuEntry *fsm_iter;
153
for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) {
157
return fsm_iter ? fsm_iter->path : NULL;
160
short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx)
162
FSMenuEntry *fsm_iter;
164
for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) {
168
return fsm_iter ? fsm_iter->save : 0;
171
void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, FSMenuInsert flag)
173
FSMenuEntry *fsm_prev;
174
FSMenuEntry *fsm_iter;
175
FSMenuEntry *fsm_head;
177
fsm_head = fsmenu_get_category(fsmenu, category);
178
fsm_prev = fsm_head; /* this is odd and not really correct? */
180
for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) {
181
if (fsm_iter->path) {
182
const int cmp_ret = BLI_path_cmp(path, fsm_iter->path);
174
183
if (cmp_ret == 0) {
184
if (flag & FS_INSERT_FIRST) {
185
if (fsm_iter != fsm_head) {
186
fsm_prev->next = fsm_iter->next;
187
fsm_iter->next = fsm_head;
188
fsmenu_set_category(fsmenu, category, fsm_iter);
177
else if (sorted && cmp_ret < 0) {
193
else if ((flag & FS_INSERT_SORTED) && cmp_ret < 0) {
182
// if we're bookmarking this, file should come
183
// before the last separator, only automatically added
184
// current dir go after the last sep.
198
/* if we're bookmarking this, file should come
199
* before the last separator, only automatically added
200
* current dir go after the last sep. */
201
if (flag & FS_INSERT_SAVE) {
191
fsme= MEM_mallocN(sizeof(*fsme), "fsme");
192
fsme->path= BLI_strdup(path);
196
fsme->next= prev->next;
207
fsm_iter = MEM_mallocN(sizeof(*fsm_iter), "fsme");
208
fsm_iter->path = BLI_strdup(path);
209
fsm_iter->save = (flag & FS_INSERT_SAVE) != 0;
212
if (flag & FS_INSERT_FIRST) {
213
fsm_iter->next = fsm_head;
214
fsmenu_set_category(fsmenu, category, fsm_iter);
217
fsm_iter->next = fsm_prev->next;
218
fsm_prev->next = fsm_iter;
201
fsmenu_set_category(fsmenu, category, fsme);
222
fsm_iter->next = fsm_head;
223
fsmenu_set_category(fsmenu, category, fsm_iter);
205
void fsmenu_remove_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
227
void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx)
207
FSMenuEntry *prev= NULL, *fsme= NULL;
208
FSMenuEntry *fsms = fsmenu_get_category(fsmenu, category);
210
for (fsme= fsms; fsme && idx; prev= fsme, fsme= fsme->next)
229
FSMenuEntry *fsm_prev = NULL;
230
FSMenuEntry *fsm_iter;
231
FSMenuEntry *fsm_head;
233
fsm_head = fsmenu_get_category(fsmenu, category);
235
for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next)
214
239
/* you should only be able to remove entries that were
215
240
* not added by default, like windows drives.
216
241
* also separators (where path == NULL) shouldn't be removed */
217
if (fsme->save && fsme->path) {
242
if (fsm_iter->save && fsm_iter->path) {
219
244
/* remove fsme from list */
221
prev->next= fsme->next;
246
fsm_prev->next = fsm_iter->next;
225
fsmenu_set_category(fsmenu, category, fsms);
249
fsm_head = fsm_iter->next;
250
fsmenu_set_category(fsmenu, category, fsm_head);
228
MEM_freeN(fsme->path);
253
MEM_freeN(fsm_iter->path);
234
void fsmenu_write_file(struct FSMenu* fsmenu, const char *filename)
259
void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename)
236
FSMenuEntry *fsme= NULL;
261
FSMenuEntry *fsm_iter = NULL;
239
264
FILE *fp = BLI_fopen(filename, "w");
242
267
fprintf(fp, "[Bookmarks]\n");
243
for (fsme= fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsme; fsme= fsme->next) {
244
if (fsme->path && fsme->save) {
245
fprintf(fp, "%s\n", fsme->path);
268
for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) {
269
if (fsm_iter->path && fsm_iter->save) {
270
fprintf(fp, "%s\n", fsm_iter->path);
248
273
fprintf(fp, "[Recent]\n");
249
nskip = fsmenu_get_nentries(fsmenu, FS_CATEGORY_RECENT) - FSMENU_RECENT_MAX;
250
// skip first entries if list too long
251
for (fsme= fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsme && (nskip>0); fsme= fsme->next, --nskip) {
254
for (; fsme; fsme= fsme->next) {
255
if (fsme->path && fsme->save) {
256
fprintf(fp, "%s\n", fsme->path);
274
for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) {
275
if (fsm_iter->path && fsm_iter->save) {
276
fprintf(fp, "%s\n", fsm_iter->path);
262
void fsmenu_read_bookmarks(struct FSMenu* fsmenu, const char *filename)
282
void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
265
285
FSMenuCategory category = FS_CATEGORY_BOOKMARKS;
304
tmp= GetLogicalDrives();
329
tmp = GetLogicalDrives();
306
for (i=0; i < 26; i++) {
331
for (i = 0; i < 26; i++) {
332
if ((tmp >> i) & 1) {
313
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, 1, 0);
338
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, FS_INSERT_SORTED);
317
342
/* Adding Desktop and My Documents */
318
SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0);
319
fsmenu_insert_entry(fsmenu,FS_CATEGORY_BOOKMARKS, line, 1, 0);
320
SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0);
321
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
343
if (read_bookmarks) {
344
SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0);
345
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
346
SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0);
347
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
326
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
353
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040)
329
356
const char *home;
331
358
/* loop through all the OS X Volumes, and add them to the SYSTEM section */
332
for (i=1; err!=nsvErr; i++)
359
for (i = 1; err != nsvErr; i++) {
335
361
unsigned char path[FILE_MAX];
349
375
* assume they are the standard ones
350
376
* TODO : replace hardcoded paths with proper BLI_get_folder calls */
351
377
home = getenv("HOME");
378
if (read_bookmarks && home) {
353
379
BLI_snprintf(line, 256, "%s/", home);
354
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
380
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
355
381
BLI_snprintf(line, 256, "%s/Desktop/", home);
356
382
if (BLI_exists(line)) {
357
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
383
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
359
385
BLI_snprintf(line, 256, "%s/Documents/", home);
360
386
if (BLI_exists(line)) {
361
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
387
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
363
389
BLI_snprintf(line, 256, "%s/Pictures/", home);
364
390
if (BLI_exists(line)) {
365
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
391
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
367
393
BLI_snprintf(line, 256, "%s/Music/", home);
368
394
if (BLI_exists(line)) {
369
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
395
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
371
397
BLI_snprintf(line, 256, "%s/Movies/", home);
372
398
if (BLI_exists(line)) {
373
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
399
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
434
458
FSRefMakePath(&dir, path, FILE_MAX);
435
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, 1, 0);
459
if (strcmp((char *)path, "/home") && strcmp((char *)path, "/net")) {
460
/* /net and /home are meaningless on OSX, home folders are stored in /Users */
461
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED);
438
465
/* Finally get user favorite places */
439
list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
440
pathesArray = LSSharedFileListCopySnapshot(list, &seed);
441
pathesCount = CFArrayGetCount(pathesArray);
443
for (i=0; i<pathesCount; i++)
445
itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(pathesArray, i);
447
err = LSSharedFileListItemResolve(itemRef,
448
kLSSharedFileListNoUserInteraction
449
| kLSSharedFileListDoNotMountVolumes,
454
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
456
if (!CFStringGetCString(pathString,line,256,kCFStringEncodingASCII))
458
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
460
CFRelease(pathString);
466
if (read_bookmarks) {
467
list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
468
pathesArray = LSSharedFileListCopySnapshot(list, &seed);
469
pathesCount = CFArrayGetCount(pathesArray);
471
for (i = 0; i < pathesCount; i++) {
472
itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(pathesArray, i);
474
err = LSSharedFileListItemResolve(itemRef,
475
kLSSharedFileListNoUserInteraction |
476
kLSSharedFileListDoNotMountVolumes,
481
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
483
if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII))
485
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
487
CFRelease(pathString);
491
CFRelease(pathesArray);
464
CFRelease(pathesArray);
466
494
#endif /* OSX 10.5+ */
471
const char *home= getenv("HOME");
499
const char *home = getenv("HOME");
501
if (read_bookmarks && home) {
474
502
BLI_snprintf(line, FILE_MAXDIR, "%s/", home);
475
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
503
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
476
504
BLI_snprintf(line, FILE_MAXDIR, "%s/Desktop/", home);
477
505
if (BLI_exists(line)) {
478
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
506
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
485
513
/* loop over mount points */
486
514
struct mntent *mnt;
490
fp = setmntent (MOUNTED, "r");
518
fp = setmntent(MOUNTED, "r");
491
519
if (fp == NULL) {
492
520
fprintf(stderr, "could not get a list of mounted filesystemts\n");
495
while ((mnt = getmntent (fp))) {
523
while ((mnt = getmntent(fp))) {
496
524
/* not sure if this is right, but seems to give the relevant mnts */
497
525
if (strncmp(mnt->mnt_fsname, "/dev", 4))
500
len= strlen(mnt->mnt_dir);
501
if (len && mnt->mnt_dir[len-1] != '/') {
528
len = strlen(mnt->mnt_dir);
529
if (len && mnt->mnt_dir[len - 1] != '/') {
502
530
BLI_snprintf(line, FILE_MAXDIR, "%s/", mnt->mnt_dir);
503
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, 1, 0);
506
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, 1, 0);
531
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
534
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, FS_INSERT_SORTED);
510
if (endmntent (fp) == 0) {
539
if (endmntent(fp) == 0) {
511
540
fprintf(stderr, "could not close the list of mounted filesystemts\n");
518
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", 1, 0);
526
static void fsmenu_free_category(struct FSMenu* fsmenu, FSMenuCategory category)
528
FSMenuEntry *fsme= fsmenu_get_category(fsmenu, category);
531
FSMenuEntry *n= fsme->next;
533
if (fsme->path) MEM_freeN(fsme->path);
540
void fsmenu_free(struct FSMenu* fsmenu)
542
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM);
547
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", FS_INSERT_SORTED);
555
static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category)
557
FSMenuEntry *fsm_iter = fsmenu_get_category(fsmenu, category);
560
FSMenuEntry *fsm_next = fsm_iter->next;
562
if (fsm_iter->path) {
563
MEM_freeN(fsm_iter->path);
571
void fsmenu_refresh_system_category(struct FSMenu *fsmenu)
573
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM);
574
fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL);
576
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
577
fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL);
579
/* Add all entries to system category */
580
fsmenu_read_system(fsmenu, TRUE);
583
void fsmenu_free(struct FSMenu *fsmenu)
585
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM);
586
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
543
587
fsmenu_free_category(fsmenu, FS_CATEGORY_BOOKMARKS);
544
588
fsmenu_free_category(fsmenu, FS_CATEGORY_RECENT);
545
589
MEM_freeN(fsmenu);