Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_file/fsmenu.c
| Show All 25 Lines | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <math.h> | #include <math.h> | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLT_translation.h" | |||||
| #include "BKE_appdir.h" | #include "BKE_appdir.h" | ||||
| #include "BKE_main.h" | |||||
| #include "ED_fileselect.h" | #include "ED_fileselect.h" | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| /* Need to include windows.h so _WIN32_IE is defined. */ | /* Need to include windows.h so _WIN32_IE is defined. */ | ||||
| # include <windows.h> | # include <windows.h> | ||||
| /* For SHGetSpecialFolderPath, has to be done before BLI_winstuff | /* For SHGetSpecialFolderPath, has to be done before BLI_winstuff | ||||
| * because 'near' is disabled through BLI_windstuff. */ | * because 'near' is disabled through BLI_windstuff. */ | ||||
| # include <shlobj.h> | # include <shlobj.h> | ||||
| # include "BLI_winstuff.h" | # include "BLI_winstuff.h" | ||||
| #endif | #endif | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "UI_interface_icons.h" | |||||
| #include "UI_resources.h" | |||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||
| # include <Carbon/Carbon.h> | # include <Carbon/Carbon.h> | ||||
| #endif /* __APPLE__ */ | #endif /* __APPLE__ */ | ||||
| #ifdef __linux__ | #ifdef __linux__ | ||||
| # include <mntent.h> | # include <mntent.h> | ||||
| # include "BLI_fileops_types.h" | # include "BLI_fileops_types.h" | ||||
| ▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | if (!STREQ(name, fsentry->name)) { | ||||
| BLI_make_file_string("/", | BLI_make_file_string("/", | ||||
| tmp_name, | tmp_name, | ||||
| BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), | BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), | ||||
| BLENDER_BOOKMARK_FILE); | BLENDER_BOOKMARK_FILE); | ||||
| fsmenu_write_file(ED_fsmenu_get(), tmp_name); | fsmenu_write_file(ED_fsmenu_get(), tmp_name); | ||||
| } | } | ||||
| } | } | ||||
| int ED_fsmenu_entry_get_icon(struct FSMenuEntry *fsentry) | |||||
| { | |||||
| return (fsentry->icon) ? fsentry->icon : ICON_FILE_FOLDER; | |||||
| } | |||||
| void ED_fsmenu_entry_set_icon(struct FSMenuEntry *fsentry, const int icon) | |||||
| { | |||||
| fsentry->icon = icon; | |||||
| } | |||||
| void fsmenu_entry_refresh_valid(struct FSMenuEntry *fsentry) | void fsmenu_entry_refresh_valid(struct FSMenuEntry *fsentry) | ||||
| { | { | ||||
| if (fsentry->path && fsentry->path[0]) { | if (fsentry->path && fsentry->path[0]) { | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| /* XXX Special case, always consider those as valid. | /* XXX Special case, always consider those as valid. | ||||
| * Thanks to Windows, which can spend five seconds to perform a mere stat() call on those paths | * Thanks to Windows, which can spend five seconds to perform a mere stat() call on those paths | ||||
| * See T43684. */ | * See T43684. */ | ||||
| const char *exceptions[] = {"A:\\", "B:\\", NULL}; | const char *exceptions[] = {"A:\\", "B:\\", NULL}; | ||||
| Show All 25 Lines | short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx) | ||||
| return fsm_iter ? fsm_iter->save : 0; | return fsm_iter ? fsm_iter->save : 0; | ||||
| } | } | ||||
| void fsmenu_insert_entry(struct FSMenu *fsmenu, | void fsmenu_insert_entry(struct FSMenu *fsmenu, | ||||
| FSMenuCategory category, | FSMenuCategory category, | ||||
| const char *path, | const char *path, | ||||
| const char *name, | const char *name, | ||||
| const int icon, | |||||
| FSMenuInsert flag) | FSMenuInsert flag) | ||||
| { | { | ||||
| FSMenuEntry *fsm_prev; | FSMenuEntry *fsm_prev; | ||||
| FSMenuEntry *fsm_iter; | FSMenuEntry *fsm_iter; | ||||
| FSMenuEntry *fsm_head; | FSMenuEntry *fsm_head; | ||||
| fsm_head = ED_fsmenu_get_category(fsmenu, category); | fsm_head = ED_fsmenu_get_category(fsmenu, category); | ||||
| fsm_prev = fsm_head; /* this is odd and not really correct? */ | fsm_prev = fsm_head; /* this is odd and not really correct? */ | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | void fsmenu_insert_entry(struct FSMenu *fsmenu, | ||||
| } | } | ||||
| if (name && name[0]) { | if (name && name[0]) { | ||||
| BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name)); | BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name)); | ||||
| } | } | ||||
| else { | else { | ||||
| fsm_iter->name[0] = '\0'; | fsm_iter->name[0] = '\0'; | ||||
| } | } | ||||
| fsm_iter->icon = icon; | |||||
Severin: Can just call `ED_fsmenu_entry_set_icon()` here. | |||||
| fsmenu_entry_refresh_valid(fsm_iter); | fsmenu_entry_refresh_valid(fsm_iter); | ||||
| if (fsm_prev) { | if (fsm_prev) { | ||||
| if (flag & FS_INSERT_FIRST) { | if (flag & FS_INSERT_FIRST) { | ||||
| fsm_iter->next = fsm_head; | fsm_iter->next = fsm_head; | ||||
| ED_fsmenu_set_category(fsmenu, category, fsm_iter); | ED_fsmenu_set_category(fsmenu, category, fsm_iter); | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | else { | ||||
| } | } | ||||
| /* don't do this because it can be slow on network drives, | /* don't do this because it can be slow on network drives, | ||||
| * having a bookmark from a drive that's ejected or so isn't | * having a bookmark from a drive that's ejected or so isn't | ||||
| * all _that_ bad */ | * all _that_ bad */ | ||||
| #if 0 | #if 0 | ||||
| if (BLI_exists(line)) | if (BLI_exists(line)) | ||||
| #endif | #endif | ||||
| { | { | ||||
| fsmenu_insert_entry(fsmenu, category, line, name, FS_INSERT_SAVE); | fsmenu_insert_entry(fsmenu, category, line, name, ICON_FILE_FOLDER, FS_INSERT_SAVE); | ||||
| } | } | ||||
| } | } | ||||
| /* always reset name. */ | /* always reset name. */ | ||||
| name[0] = '\0'; | name[0] = '\0'; | ||||
| } | } | ||||
| } | } | ||||
| fclose(fp); | fclose(fp); | ||||
| } | } | ||||
| Show All 28 Lines | for (i = 0; i < 26; i++) { | ||||
| BLI_strncpy_wchar_as_utf8(line, shFile.szDisplayName, FILE_MAXDIR); | BLI_strncpy_wchar_as_utf8(line, shFile.szDisplayName, FILE_MAXDIR); | ||||
| name = line; | name = line; | ||||
| } | } | ||||
| } | } | ||||
| if (name == NULL) { | if (name == NULL) { | ||||
| name = tmps; | name = tmps; | ||||
| } | } | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, name, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, tmps, name, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| } | } | ||||
| } | } | ||||
| /* Adding Desktop and My Documents */ | /* Adding My Documents and Desktop */ | ||||
| if (read_bookmarks) { | if (read_bookmarks) { | ||||
| SHGetSpecialFolderPathW(0, wline, CSIDL_PERSONAL, 0); | SHGetSpecialFolderPathW(0, wline, CSIDL_PERSONAL, 0); | ||||
| BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR); | BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, ICON_ASSET_MANAGER, FS_INSERT_LAST); | |||||
| SHGetSpecialFolderPathW(0, wline, CSIDL_DESKTOPDIRECTORY, 0); | SHGetSpecialFolderPathW(0, wline, CSIDL_DESKTOPDIRECTORY, 0); | ||||
| BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR); | BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, ICON_FILE_FOLDER, FS_INSERT_LAST); | |||||
| } | } | ||||
| } | } | ||||
| #else | #else | ||||
| # ifdef __APPLE__ | # ifdef __APPLE__ | ||||
| { | { | ||||
| /* Get mounted volumes better method OSX 10.6 and higher, see: | /* Get mounted volumes better method OSX 10.6 and higher, see: | ||||
| * https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html | * https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html | ||||
| */ | */ | ||||
| Show All 13 Lines | while (result != kCFURLEnumeratorEnd) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); | CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); | ||||
| /* Add end slash for consistency with other platforms */ | /* Add end slash for consistency with other platforms */ | ||||
| BLI_add_slash(defPath); | BLI_add_slash(defPath); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, defPath, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, defPath, NULL, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| } | } | ||||
| CFRelease(volEnum); | CFRelease(volEnum); | ||||
| /* Finally get user favorite places */ | /* Finally get user favorite places */ | ||||
| if (read_bookmarks) { | if (read_bookmarks) { | ||||
| UInt32 seed; | UInt32 seed; | ||||
| LSSharedFileListRef list = LSSharedFileListCreate( | LSSharedFileListRef list = LSSharedFileListCreate( | ||||
| Show All 23 Lines | if (read_bookmarks) { | ||||
| } | } | ||||
| /* Add end slash for consistency with other platforms */ | /* Add end slash for consistency with other platforms */ | ||||
| BLI_add_slash(line); | BLI_add_slash(line); | ||||
| /* Exclude "all my files" as it makes no sense in blender fileselector */ | /* Exclude "all my files" as it makes no sense in blender fileselector */ | ||||
| /* Exclude "airdrop" if wlan not active as it would show "" ) */ | /* Exclude "airdrop" if wlan not active as it would show "" ) */ | ||||
| if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { | if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, ICON_FILE_FOLDER, FS_INSERT_LAST); | |||||
| } | } | ||||
| CFRelease(pathString); | CFRelease(pathString); | ||||
| CFRelease(cfURL); | CFRelease(cfURL); | ||||
| } | } | ||||
| CFRelease(pathesArray); | CFRelease(pathesArray); | ||||
| CFRelease(list); | CFRelease(list); | ||||
| } | } | ||||
| } | } | ||||
| # else | # else | ||||
| /* unix */ | /* unix */ | ||||
| { | { | ||||
| const char *home = BLI_getenv("HOME"); | const char *home = BLI_getenv("HOME"); | ||||
| if (read_bookmarks && home) { | if (read_bookmarks && home) { | ||||
| BLI_snprintf(line, sizeof(line), "%s/", home); | BLI_snprintf(line, sizeof(line), "%s/", home); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, ICON_FILE_FOLDER, FS_INSERT_SORTED); | |||||
| BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); | BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); | ||||
| if (BLI_exists(line)) { | if (BLI_exists(line)) { | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, ICON_FILE_FOLDER, FS_INSERT_SORTED); | |||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| int found = 0; | int found = 0; | ||||
| # ifdef __linux__ | # ifdef __linux__ | ||||
| /* loop over mount points */ | /* loop over mount points */ | ||||
| struct mntent *mnt; | struct mntent *mnt; | ||||
| Show All 17 Lines | # ifdef __linux__ | ||||
| /* The dev/loop* entries are SNAPS used by desktop environment | /* The dev/loop* entries are SNAPS used by desktop environment | ||||
| * (Gnome) no need for them to show up in the list. */ | * (Gnome) no need for them to show up in the list. */ | ||||
| continue; | continue; | ||||
| } | } | ||||
| len = strlen(mnt->mnt_dir); | len = strlen(mnt->mnt_dir); | ||||
| if (len && mnt->mnt_dir[len - 1] != '/') { | if (len && mnt->mnt_dir[len - 1] != '/') { | ||||
| BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir); | BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, line, NULL, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| } | } | ||||
| else { | else { | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| } | } | ||||
| found = 1; | found = 1; | ||||
| } | } | ||||
| if (endmntent(fp) == 0) { | if (endmntent(fp) == 0) { | ||||
| fprintf(stderr, "could not close the list of mounted filesystems\n"); | fprintf(stderr, "could not close the list of mounted filesystems\n"); | ||||
| } | } | ||||
| } | } | ||||
| Show All 13 Lines | # ifdef __linux__ | ||||
| const char *label = strstr(dirname, "share="); | const char *label = strstr(dirname, "share="); | ||||
| if (label != NULL) { | if (label != NULL) { | ||||
| /* Move pointer so "share=" is trimmed off | /* Move pointer so "share=" is trimmed off | ||||
| * or use full dirname as label. */ | * or use full dirname as label. */ | ||||
| const char *label_test = label + 6; | const char *label_test = label + 6; | ||||
| label = *label_test ? label_test : dirname; | label = *label_test ? label_test : dirname; | ||||
| } | } | ||||
| BLI_snprintf(line, sizeof(line), "%s%s/", name, dirname); | BLI_snprintf(line, sizeof(line), "%s%s/", name, dirname); | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, label, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, line, label, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| found = 1; | found = 1; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_filelist_free(dir, dir_len); | BLI_filelist_free(dir, dir_len); | ||||
| } | } | ||||
| # endif | # endif | ||||
| /* fallback */ | /* fallback */ | ||||
| if (!found) { | if (!found) { | ||||
| fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, FS_INSERT_SORTED); | fsmenu_insert_entry( | ||||
| fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, ICON_DISK_DRIVE, FS_INSERT_SORTED); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| # endif | # endif | ||||
| #endif | #endif | ||||
| /* Include blend file location if available */ | |||||
| const char *blendfile_path = BKE_main_blendfile_path_from_global(); | |||||
| if (blendfile_path[0] != '\0') { | |||||
| static char dir[FILE_MAX]; | |||||
| BLI_split_dir_part(blendfile_path, dir, FILE_MAX); | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| dir, | |||||
| TIP_("Blend File"), | |||||
| ICON_FILE_BLEND, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| /* Include Textures folder preference if set and not \\ */ | |||||
| if (strlen(U.textudir) > 2) { | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| U.textudir, | |||||
| TIP_("Textures"), | |||||
| ICON_FILE_IMAGE, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| /* Include Sound folder preference if set and not \\ */ | |||||
| if (strlen(U.sounddir) > 2) { | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| U.sounddir, | |||||
| TIP_("Sounds"), | |||||
| ICON_FILE_SOUND, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| /* Include Fonts folder preference if set and not \\ */ | |||||
| if (strlen(U.fontdir) > 2) { | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| U.fontdir, | |||||
| TIP_("Fonts"), | |||||
| ICON_FILE_FONT, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| /* Include Scripts folder preference if set and not \\ */ | |||||
| if (strlen(U.pythondir) > 2) { | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| U.pythondir, | |||||
| TIP_("Scripts"), | |||||
| ICON_FILE_SCRIPT, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| /* Include temp folder preference if set and not \\ */ | |||||
| if (strlen(U.tempdir) > 2) { | |||||
| fsmenu_insert_entry(fsmenu, | |||||
| FS_CATEGORY_SYSTEM_BOOKMARKS, | |||||
| U.tempdir, | |||||
| TIP_("Temp"), | |||||
| ICON_MOD_TIME, | |||||
| FS_INSERT_LAST); | |||||
| } | |||||
| } | } | ||||
| static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) | static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) | ||||
| { | { | ||||
| FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); | FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); | ||||
| while (fsm_iter) { | while (fsm_iter) { | ||||
| FSMenuEntry *fsm_next = fsm_iter->next; | FSMenuEntry *fsm_next = fsm_iter->next; | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||
Can just call ED_fsmenu_entry_set_icon() here.