diff options
Diffstat (limited to 'source/blender/editors/space_file/fsmenu.c')
-rw-r--r-- | source/blender/editors/space_file/fsmenu.c | 207 |
1 files changed, 157 insertions, 50 deletions
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 05dfdf66ab6..8d4384acba6 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -40,6 +40,12 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BKE_appdir.h" + +#include "DNA_space_types.h" + +#include "ED_fileselect.h" + #ifdef WIN32 # include <windows.h> /* need to include windows.h so _WIN32_IE is defined */ # ifndef _WIN32_IE @@ -63,15 +69,6 @@ /* FSMENU HANDLING */ -/* FSMenuEntry's without paths indicate seperators */ -typedef struct _FSMenuEntry FSMenuEntry; -struct _FSMenuEntry { - FSMenuEntry *next; - - char *path; - short save; -}; - typedef struct FSMenu { FSMenuEntry *fsmenu_system; FSMenuEntry *fsmenu_system_bookmarks; @@ -81,7 +78,7 @@ typedef struct FSMenu { static FSMenu *g_fsmenu = NULL; -FSMenu *fsmenu_get(void) +FSMenu *ED_fsmenu_get(void) { if (!g_fsmenu) { g_fsmenu = MEM_callocN(sizeof(struct FSMenu), "fsmenu"); @@ -89,7 +86,7 @@ FSMenu *fsmenu_get(void) return g_fsmenu; } -static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) +struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_head = NULL; @@ -110,7 +107,7 @@ static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory ca return fsm_head; } -static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) +void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) { switch (category) { case FS_CATEGORY_SYSTEM: @@ -128,47 +125,115 @@ static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, } } -int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) +int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_iter; int count = 0; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { count++; } return count; } -char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx) +FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { - idx--; + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && index; fsm_iter = fsm_iter->next) { + index--; + } + + return fsm_iter; +} + +char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) +{ + return fsentry->path; +} + +void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path) +{ + if ((!fsentry->path || !path || !STREQ(path, fsentry->path)) && (fsentry->path != path)) { + char tmp_name[FILE_MAXFILE]; + + MEM_SAFE_FREE(fsentry->path); + + fsentry->path = (path && path[0]) ? BLI_strdup(path) : NULL; + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } +} + +static void fsmenu_entry_generate_name(struct FSMenuEntry *fsentry, char *name, size_t name_size) +{ + char temp[FILE_MAX]; + + BLI_strncpy(temp, fsentry->path, FILE_MAX); + BLI_add_slash(temp); + BLI_getlastdir(temp, name, name_size); + BLI_del_slash(name); + if (!name[0]) { + name[0] = '/'; + name[1] = '\0'; } +} - return fsm_iter ? fsm_iter->path : NULL; +char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) +{ + if (fsentry->name[0]) { + return fsentry->name; + } + else { + /* Here we abuse fsm_iter->name, keeping first char NULL. */ + char *name = fsentry->name + 1; + size_t name_size = sizeof(fsentry->name) - 1; + + fsmenu_entry_generate_name(fsentry, name, name_size); + return name; + } +} + +void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) +{ + if (!STREQ(name, fsentry->name)) { + char tmp_name[FILE_MAXFILE]; + size_t tmp_name_size = sizeof(tmp_name); + + fsmenu_entry_generate_name(fsentry, tmp_name, tmp_name_size); + if (!name[0] || STREQ(tmp_name, name)) { + /* reset name to default behavior. */ + fsentry->name[0] = '\0'; + } + else { + BLI_strncpy(fsentry->name, name, sizeof(fsentry->name)); + } + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } } short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { idx--; } return fsm_iter ? fsm_iter->save : 0; } -void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, FSMenuInsert flag) +void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const char *name, FSMenuInsert flag) { FSMenuEntry *fsm_prev; FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); fsm_prev = fsm_head; /* this is odd and not really correct? */ for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) { @@ -179,7 +244,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c if (fsm_iter != fsm_head) { fsm_prev->next = fsm_iter->next; fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } return; @@ -201,11 +266,17 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c fsm_iter = MEM_mallocN(sizeof(*fsm_iter), "fsme"); fsm_iter->path = BLI_strdup(path); fsm_iter->save = (flag & FS_INSERT_SAVE) != 0; + if (name && name[0]) { + BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name)); + } + else { + fsm_iter->name[0] = '\0'; + } if (fsm_prev) { if (flag & FS_INSERT_FIRST) { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } else { fsm_iter->next = fsm_prev->next; @@ -214,7 +285,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c } else { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } @@ -224,7 +295,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) idx--; @@ -241,7 +312,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx } else { fsm_head = fsm_iter->next; - fsmenu_set_category(fsmenu, category, fsm_head); + ED_fsmenu_set_category(fsmenu, category, fsm_head); } /* free entry */ MEM_freeN(fsm_iter->path); @@ -253,20 +324,29 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) { FSMenuEntry *fsm_iter = NULL; + char fsm_name[FILE_MAX]; int nwritten = 0; FILE *fp = BLI_fopen(filename, "w"); if (!fp) return; - + fprintf(fp, "[Bookmarks]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } fprintf(fp, "[Recent]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } @@ -276,12 +356,15 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) { char line[FILE_MAXDIR]; + char name[FILE_MAXFILE]; FSMenuCategory category = FS_CATEGORY_BOOKMARKS; FILE *fp; fp = BLI_fopen(filename, "r"); if (!fp) return; + name[0] = '\0'; + while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */ if (STREQLEN(line, "[Bookmarks]", 11)) { category = FS_CATEGORY_BOOKMARKS; @@ -289,6 +372,15 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) else if (STREQLEN(line, "[Recent]", 8)) { category = FS_CATEGORY_RECENT; } + else if (line[0] == '!') { + int len = strlen(line); + if (len > 0) { + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + BLI_strncpy(name, line + 1, sizeof(name)); + } + } else { int len = strlen(line); if (len > 0) { @@ -302,9 +394,11 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) if (BLI_exists(line)) #endif { - fsmenu_insert_entry(fsmenu, category, line, FS_INSERT_SAVE); + fsmenu_insert_entry(fsmenu, category, line, name, FS_INSERT_SAVE); } } + /* always reset name. */ + name[0] = '\0'; } } fclose(fp); @@ -329,16 +423,16 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) tmps[2] = '\\'; tmps[3] = 0; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, NULL, FS_INSERT_SORTED); } } /* Adding Desktop and My Documents */ if (read_bookmarks) { SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else @@ -361,7 +455,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) FSRefMakePath(&dir, path, FILE_MAX); if (!STREQ((char *)path, "/home") && !STREQ((char *)path, "/net")) { /* /net and /home are meaningless on OSX, home folders are stored in /Users */ - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, NULL, FS_INSERT_SORTED); } } @@ -371,26 +465,26 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) home = getenv("HOME"); if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Documents/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Pictures/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Music/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Movies/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else /* OSX 10.6+ */ @@ -410,7 +504,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) continue; CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED); } CFRelease(volEnum); @@ -447,7 +541,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Exclude "all my files" as it makes no sense in blender fileselector */ /* Exclude "airdrop" if wlan not active as it would show "" ) */ if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_APPEND_LAST); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST); } CFRelease(pathString); @@ -466,10 +560,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } @@ -494,10 +588,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) len = strlen(mnt->mnt_dir); if (len && mnt->mnt_dir[len - 1] != '/') { BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, NULL, FS_INSERT_SORTED); } else { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, FS_INSERT_SORTED); } found = 1; @@ -510,7 +604,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* fallback */ if (!found) - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, FS_INSERT_SORTED); } } #endif @@ -520,7 +614,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) { - FSMenuEntry *fsm_iter = fsmenu_get_category(fsmenu, category); + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); while (fsm_iter) { FSMenuEntry *fsm_next = fsm_iter->next; @@ -537,10 +631,10 @@ static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) void fsmenu_refresh_system_category(struct FSMenu *fsmenu) { fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); /* Add all entries to system category */ fsmenu_read_system(fsmenu, true); @@ -559,3 +653,16 @@ void fsmenu_free(void) g_fsmenu = NULL; } +int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir) +{ + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); + int i; + + for (i = 0; fsm_iter; fsm_iter = fsm_iter->next, i++) { + if (BLI_path_cmp(dir, fsm_iter->path) == 0) { + return i; + } + } + + return -1; +} |