FileBrowser: Editable Bookmarks.
[blender-staging.git] / source / blender / editors / space_file / fsmenu.c
index 05dfdf66ab6300eaa50a078535ffd0b6c474428f..8d4384acba6e0e7266281a738bf7c69bf2359c87 100644 (file)
 #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
 
 /* 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;
+}