FileBrowser: Editable Bookmarks.
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 10 Feb 2015 23:09:45 +0000 (00:09 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 10 Feb 2015 23:09:45 +0000 (00:09 +0100)
Bookmarks are now editable (i.e. you can rename them, and reorder them).
They are also listed in regular UILists, so you can filter/sort them as usual too.

Also, FileBrowser 'T' side area is changed to something similar to 3DView one,
in this case because we need op panel to remain at the bottom, and later because
we'll more than likely need tabs here!

Thanks to Campbell and Sergey for reviews.

Differential Revision: https://developer.blender.org/D1093

17 files changed:
release/scripts/startup/bl_ui/space_filebrowser.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/include/ED_fileselect.h
source/blender/editors/screen/area.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/file_intern.h
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/file_panels.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/fsmenu.c
source/blender/editors/space_file/fsmenu.h
source/blender/editors/space_file/space_file.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_space.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index 6fe50c7eeb519fd959e540a69003b0211562facc..cda3dfe499d74a6e1e657afbc50f552e7d4a583c 100644 (file)
@@ -18,7 +18,7 @@
 
 # <pep8 compliant>
 import bpy
-from bpy.types import Header
+from bpy.types import Header, Panel, Menu
 
 
 class FILEBROWSER_HT_header(Header):
@@ -81,5 +81,128 @@ class FILEBROWSER_HT_header(Header):
             row.prop(params, "filter_search", text="", icon='VIEWZOOM')
 
 
+
+class FILEBROWSER_UL_dir(bpy.types.UIList):
+    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+        direntry = item
+        space = context.space_data
+        icon = 'NONE'
+        if active_propname == "system_folders_active":
+            icon = 'DISK_DRIVE'
+        if active_propname == "system_bookmarks_active":
+            icon = 'BOOKMARKS'
+        if active_propname == "bookmarks_active":
+            icon = 'BOOKMARKS'
+        if active_propname == "recent_folders_active":
+            icon = 'FILE_FOLDER'
+
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            row = layout.row(align=True)
+            row.prop(direntry, "name", text="", emboss=False, icon=icon)
+
+        elif self.layout_type in {'GRID'}:
+            layout.alignment = 'CENTER'
+            layout.prop(direntry, "path", text="")
+
+
+class FILEBROWSER_PT_system_folders(Panel):
+    bl_space_type = 'FILE_BROWSER'
+    bl_region_type = 'TOOLS'
+    bl_category = "Bookmarks"
+    bl_label = "System"
+
+    def draw(self, context):
+        layout = self.layout
+        space = context.space_data
+
+        if space.system_folders:
+            row = layout.row()
+            row.template_list("FILEBROWSER_UL_dir", "system_folders", space, "system_folders",
+                              space, "system_folders_active", item_dyntip_propname="path", rows=1, maxrows=6)
+
+
+class FILEBROWSER_PT_system_bookmarks(Panel):
+    bl_space_type = 'FILE_BROWSER'
+    bl_region_type = 'TOOLS'
+    bl_category = "Bookmarks"
+    bl_label = "System Bookmarks"
+
+    @classmethod
+    def poll(cls, context):
+        return not context.user_preferences.filepaths.hide_system_bookmarks
+
+    def draw(self, context):
+        layout = self.layout
+        space = context.space_data
+
+        if space.system_bookmarks:
+            row = layout.row()
+            row.template_list("FILEBROWSER_UL_dir", "system_bookmarks", space, "system_bookmarks",
+                              space, "system_bookmarks_active", item_dyntip_propname="path", rows=1, maxrows=6)
+
+
+class FILEBROWSER_MT_bookmarks_specials(Menu):
+    bl_label = "Bookmarks Specials"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("file.bookmark_move", icon='TRIA_UP_BAR', text="Move To Top").direction = 'TOP'
+        layout.operator("file.bookmark_move", icon='TRIA_DOWN_BAR', text="Move To Bottom").direction = 'BOTTOM'
+
+
+class FILEBROWSER_PT_bookmarks(Panel):
+    bl_space_type = 'FILE_BROWSER'
+    bl_region_type = 'TOOLS'
+    bl_category = "Bookmarks"
+    bl_label = "Bookmarks"
+
+    def draw(self, context):
+        layout = self.layout
+        space = context.space_data
+
+        if space.bookmarks:
+            row = layout.row()
+            num_rows = len(space.bookmarks)
+            row.template_list("FILEBROWSER_UL_dir", "bookmarks", space, "bookmarks",
+                              space, "bookmarks_active", item_dyntip_propname="path",
+                              rows=(2 if num_rows < 2 else 4), maxrows=6)
+
+            col = row.column(align=True)
+            col.operator("file.bookmark_add", icon='ZOOMIN', text="")
+            col.operator("file.bookmark_delete", icon='ZOOMOUT', text="")
+            col.menu("FILEBROWSER_MT_bookmarks_specials", icon='DOWNARROW_HLT', text="")
+
+            if num_rows > 1:
+                col.separator()
+                col.operator("file.bookmark_move", icon='TRIA_UP', text="").direction = 'UP'
+                col.operator("file.bookmark_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+        else:
+            layout.operator("file.bookmark_add", icon='ZOOMIN')
+
+
+class FILEBROWSER_PT_recent_folders(Panel):
+    bl_space_type = 'FILE_BROWSER'
+    bl_region_type = 'TOOLS'
+    bl_category = "Bookmarks"
+    bl_label = "Recent"
+
+    @classmethod
+    def poll(cls, context):
+        return not context.user_preferences.filepaths.hide_recent_locations
+
+    def draw(self, context):
+        layout = self.layout
+        space = context.space_data
+
+        if space.recent_folders:
+            row = layout.row()
+            row.template_list("FILEBROWSER_UL_dir", "recent_folders", space, "recent_folders",
+                              space, "recent_folders_active", item_dyntip_propname="path", rows=1, maxrows=6)
+
+            col = row.column(align=True)
+            col.operator("file.reset_recent", icon='X', text="")
+
+
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
index 2c53a247f6d8650332ca60e6a52fa7c122ab3ee0..610a63cb9542d5b2eb281d9049d29da887ab8eb6 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         273
-#define BLENDER_SUBVERSION      6
+#define BLENDER_SUBVERSION      7
 /* 262 was the last editmesh release but it has compatibility code for bmesh data */
 #define BLENDER_MINVERSION      270
 #define BLENDER_MINSUBVERSION   5
index 4ca1a44d64e6e3b63e9c854fda085cb424517514..572566df6a2e76a1b428cccd321939038a92bb3a 100644 (file)
@@ -51,6 +51,7 @@
 
 #include "BKE_main.h"
 #include "BKE_node.h"
+#include "BKE_screen.h"
 
 #include "BLI_math.h"
 #include "BLI_listbase.h"
@@ -60,6 +61,7 @@
 
 #include "readfile.h"
 
+#include "MEM_guardedalloc.h"
 
 static void do_version_constraints_radians_degrees_270_1(ListBase *lb)
 {
@@ -561,4 +563,32 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                        FOREACH_NODETREE_END
                }
        }
+
+       if (!MAIN_VERSION_ATLEAST(main, 273, 7)) {
+               bScreen *scr;
+               ScrArea *sa;
+               SpaceLink *sl;
+               ARegion *ar;
+
+               for (scr = main->screen.first; scr; scr = scr->id.next) {
+                       /* Remove old deprecated region from filebrowsers */
+                       for (sa = scr->areabase.first; sa; sa = sa->next) {
+                               for (sl = sa->spacedata.first; sl; sl = sl->next) {
+                                       if (sl->spacetype == SPACE_FILE) {
+                                               for (ar = sl->regionbase.first; ar; ar = ar->next) {
+                                                       if (ar->regiontype == RGN_TYPE_CHANNELS) {
+                                                               break;
+                                                       }
+                                               }
+
+                                               if (ar) {
+                                                       /* Free old deprecated 'channel' region... */
+                                                       BKE_area_region_free(NULL, ar);
+                                                       BLI_freelinkN(&sl->regionbase, ar);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
 }
index f2a6ce0b12995b6a458b208445ccaf0403e6293f..b81ea55cca829006337420ec5ecefabe35bbcc67 100644 (file)
@@ -108,5 +108,40 @@ int ED_file_extension_icon(const char *relname);
 
 void ED_file_read_bookmarks(void);
 
+void ED_file_change_dir(struct bContext *C, const bool checkdir);
+
+/* File menu stuff */
+
+typedef enum FSMenuCategory {
+       FS_CATEGORY_SYSTEM,
+       FS_CATEGORY_SYSTEM_BOOKMARKS,
+       FS_CATEGORY_BOOKMARKS,
+       FS_CATEGORY_RECENT
+} FSMenuCategory;
+
+typedef enum FSMenuInsert {
+       FS_INSERT_SORTED = (1 << 0),
+       FS_INSERT_SAVE   = (1 << 1),
+       FS_INSERT_FIRST  = (1 << 2),  /* moves the item to the front of the list when its not already there */
+       FS_INSERT_LAST   = (1 << 3),  /* just append to preseve delivered order */
+} FSMenuInsert;
+
+struct FSMenu;
+struct FSMenuEntry;
+
+struct FSMenu *ED_fsmenu_get(void);
+struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category);
+void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, struct FSMenuEntry *fsm_head);
+
+int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category);
+
+struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+
+char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry);
+void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path);
+
+char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry);
+void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name);
+
 #endif /* __ED_FILESELECT_H__ */
 
index 83b22bb1a8aaca0693586893b04d76fdcb3ae3fa..4225b4bbd6e33a50eb82a4bec0a295e4a9cea4c5 100644 (file)
@@ -1478,7 +1478,7 @@ void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
 /* exported to all editors, uses fading default */
 void ED_region_toggle_hidden(bContext *C, ARegion *ar)
 {
-       region_toggle_hidden(C, ar, 1);
+       region_toggle_hidden(C, ar, true);
 }
 
 /**
index 57611930e99a090e99fb164e423f5bbf1882bbfa..9fe6ed73205fee5d5d4700d21fe1e76a8d5de8a2 100644 (file)
@@ -119,7 +119,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
 
        /* exception to make space for collapsed region icon */
        for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) {
-               if (artmp->regiontype == RGN_TYPE_CHANNELS && artmp->flag & RGN_FLAG_HIDDEN) {
+               if (artmp->regiontype == RGN_TYPE_TOOLS && artmp->flag & RGN_FLAG_HIDDEN) {
                        chan_offs = 16;
                        min_x += chan_offs;
                        available_w -= chan_offs;
index 7147353b3f17ed7abfa4835d79e450f3dcd32580..31d479b4617ab3086a5e5e4aa4219b689eeece29 100644 (file)
@@ -38,7 +38,7 @@ struct ARegionType;
 struct SpaceFile;
 
 /* file_ops.c */
-struct ARegion *file_buttons_region(struct ScrArea *sa);
+struct ARegion *file_tools_region(struct ScrArea *sa);
 
 /* file_draw.c */
 #define TILE_BORDER_X (UI_UNIT_X / 4)
@@ -66,6 +66,7 @@ void FILE_OT_select_border(struct wmOperatorType *ot);
 void FILE_OT_select_bookmark(struct wmOperatorType *ot);
 void FILE_OT_bookmark_add(struct wmOperatorType *ot);
 void FILE_OT_bookmark_delete(struct wmOperatorType *ot);
+void FILE_OT_bookmark_move(struct wmOperatorType *ot);
 void FILE_OT_reset_recent(wmOperatorType *ot);
 void FILE_OT_hidedot(struct wmOperatorType *ot);
 void FILE_OT_execute(struct wmOperatorType *ot);
@@ -103,7 +104,6 @@ float file_shorten_string(char *string, float w, int front);
 float file_string_width(const char *str);
 
 float file_font_pointsize(void);
-void file_change_dir(bContext *C, int checkdir);
 int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
 int autocomplete_directory(struct bContext *C, char *str, void *arg_v);
 int autocomplete_file(struct bContext *C, char *str, void *arg_v);
index ba6f91e8301d92c2a1df487d8bdf962f556c6f01..a0e312e72efc810cb7ab6d8660a975967b420782 100644 (file)
@@ -31,6 +31,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 #include "BLI_fileops_types.h"
+#include "BLI_linklist.h"
 
 #include "BLO_readfile.h"
 
@@ -197,7 +198,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
                                        BLI_add_slash(params->dir);
                                }
 
-                               file_change_dir(C, 0);
+                               ED_file_change_dir(C, false);
                                retval = FILE_SELECT_DIR;
                        }
                }
@@ -453,6 +454,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
 
 /* ---------- BOOKMARKS ----------- */
 
+/* Note we could get rid of this one, but it's used by some addon so... Does not hurt keeping it around for now. */
 static int bookmark_select_exec(bContext *C, wmOperator *op)
 {
        SpaceFile *sfile = CTX_wm_space_file(C);
@@ -464,7 +466,7 @@ static int bookmark_select_exec(bContext *C, wmOperator *op)
                RNA_string_get(op->ptr, "dir", entry);
                BLI_strncpy(params->dir, entry, sizeof(params->dir));
                BLI_cleanup_dir(G.main->name, params->dir);
-               file_change_dir(C, 1);
+               ED_file_change_dir(C, true);
 
                WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
        }
@@ -494,17 +496,18 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
        ScrArea *sa = CTX_wm_area(C);
        SpaceFile *sfile = CTX_wm_space_file(C);
-       struct FSMenu *fsmenu = fsmenu_get();
+       struct FSMenu *fsmenu = ED_fsmenu_get();
        struct FileSelectParams *params = ED_fileselect_get_params(sfile);
 
        if (params->dir[0] != '\0') {
                char name[FILE_MAX];
        
-               fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, FS_INSERT_SAVE);
+               fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, FS_INSERT_SAVE);
                BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
                fsmenu_write_file(fsmenu, name);
        }
 
+       ED_area_tag_refresh(sa);
        ED_area_tag_redraw(sa);
        return OPERATOR_FINISHED;
 }
@@ -524,17 +527,27 @@ void FILE_OT_bookmark_add(wmOperatorType *ot)
 static int bookmark_delete_exec(bContext *C, wmOperator *op)
 {
        ScrArea *sa = CTX_wm_area(C);
-       struct FSMenu *fsmenu = fsmenu_get();
-       int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
-       
-       if (RNA_struct_find_property(op->ptr, "index")) {
-               int index = RNA_int_get(op->ptr, "index");
+       SpaceFile *sfile = CTX_wm_space_file(C);
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+       int nentries = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+
+       PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index");
+
+       if (prop) {
+               int index;
+               if (RNA_property_is_set(op->ptr, prop)) {
+                       index = RNA_property_int_get(op->ptr, prop);
+               }
+               else {  /* if index unset, use active bookmark... */
+                       index = sfile->bookmarknr;
+               }
                if ((index > -1) && (index < nentries)) {
                        char name[FILE_MAX];
                        
                        fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
                        BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
                        fsmenu_write_file(fsmenu, name);
+                       ED_area_tag_refresh(sa);
                        ED_area_tag_redraw(sa);
                }
        }
@@ -560,19 +573,99 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot)
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 }
 
+enum {
+       FILE_BOOKMARK_MOVE_TOP = -2,
+       FILE_BOOKMARK_MOVE_UP = -1,
+       FILE_BOOKMARK_MOVE_DOWN = 1,
+       FILE_BOOKMARK_MOVE_BOTTOM = 2,
+};
+
+static int bookmark_move_exec(bContext *C, wmOperator *op)
+{
+       ScrArea *sa = CTX_wm_area(C);
+       SpaceFile *sfile = CTX_wm_space_file(C);
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+       struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS);
+       const struct FSMenuEntry *fsmentry_org = fsmentry;
+
+       char fname[FILE_MAX];
+
+       const int direction = RNA_enum_get(op->ptr, "direction");
+       const int totitems = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+       const int act_index = sfile->bookmarknr;
+       int new_index;
+
+       switch (direction) {
+               case FILE_BOOKMARK_MOVE_TOP:
+                       new_index = 0;
+                       break;
+               case FILE_BOOKMARK_MOVE_BOTTOM:
+                       new_index = totitems - 1;
+                       break;
+               case FILE_BOOKMARK_MOVE_UP:
+               case FILE_BOOKMARK_MOVE_DOWN:
+               default:
+                       new_index = (totitems + act_index + direction) % totitems;
+                       break;
+       }
+
+       if (new_index == act_index) {
+               return OPERATOR_CANCELLED;
+       }
+
+       BLI_linklist_move_item((LinkNode **)&fsmentry, act_index, new_index);
+       if (fsmentry != fsmentry_org) {
+               ED_fsmenu_set_category(fsmenu, FS_CATEGORY_BOOKMARKS, fsmentry);
+       }
+
+       /* Need to update active bookmark number. */
+       sfile->bookmarknr = new_index;
+
+       BLI_make_file_string("/", fname, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+       fsmenu_write_file(fsmenu, fname);
+
+       ED_area_tag_redraw(sa);
+       return OPERATOR_FINISHED;
+}
+
+void FILE_OT_bookmark_move(wmOperatorType *ot)
+{
+       static EnumPropertyItem slot_move[] = {
+           {FILE_BOOKMARK_MOVE_TOP, "TOP", 0, "Top", "Top of the list"},
+               {FILE_BOOKMARK_MOVE_UP, "UP", 0, "Up", ""},
+               {FILE_BOOKMARK_MOVE_DOWN, "DOWN", 0, "Down", ""},
+               {FILE_BOOKMARK_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"},
+               { 0, NULL, 0, NULL, NULL }
+       };
+
+       /* identifiers */
+       ot->name = "Move Bookmark";
+       ot->idname = "FILE_OT_bookmark_move";
+       ot->description = "Move the active bookmark up/down in the list";
+
+       /* api callbacks */
+       ot->poll = ED_operator_file_active;
+       ot->exec = bookmark_move_exec;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER;  /* No undo! */
+
+       RNA_def_enum(ot->srna, "direction", slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
 static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
 {
        ScrArea *sa = CTX_wm_area(C);
        char name[FILE_MAX];
-       struct FSMenu *fsmenu = fsmenu_get();
+       struct FSMenu *fsmenu = ED_fsmenu_get();
        
-       while (fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
+       while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
                fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0);
        }
        BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
        fsmenu_write_file(fsmenu, name);
        ED_area_tag_redraw(sa);
-               
+
        return OPERATOR_FINISHED;
 }
 
@@ -847,11 +940,13 @@ int file_exec(bContext *C, wmOperator *exec_op)
                file_sfile_to_operator(op, sfile, filepath);
 
                if (BLI_exists(sfile->params->dir)) {
-                       fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST);
+                       fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL,
+                                           FS_INSERT_SAVE | FS_INSERT_FIRST);
                }
 
-               BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
-               fsmenu_write_file(fsmenu_get(), filepath);
+               BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
+                                    BLENDER_BOOKMARK_FILE);
+               fsmenu_write_file(ED_fsmenu_get(), filepath);
                WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC);
 
        }
@@ -890,14 +985,14 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
                        if (sfile->params->type == FILE_LOADLIB) {
                                char tdir[FILE_MAX], tgroup[FILE_MAX];
                                if (BLO_is_a_library(sfile->params->dir, tdir, tgroup)) {
-                                       file_change_dir(C, 0);
+                                       ED_file_change_dir(C, false);
                                }
                                else {
-                                       file_change_dir(C, 1);
+                                       ED_file_change_dir(C, true);
                                }
                        }
                        else {
-                               file_change_dir(C, 1);
+                               ED_file_change_dir(C, true);
                        }
                        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
                }
@@ -925,7 +1020,7 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
 {
        wmWindowManager *wm = CTX_wm_manager(C);
        SpaceFile *sfile = CTX_wm_space_file(C);
-       struct FSMenu *fsmenu = fsmenu_get();
+       struct FSMenu *fsmenu = ED_fsmenu_get();
 
        ED_fileselect_clear(wm, sfile);
 
@@ -962,7 +1057,7 @@ int file_previous_exec(bContext *C, wmOperator *UNUSED(unused))
                folderlist_popdir(sfile->folders_prev, sfile->params->dir);
                folderlist_pushdir(sfile->folders_next, sfile->params->dir);
 
-               file_change_dir(C, 1);
+               ED_file_change_dir(C, true);
        }
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
 
@@ -994,7 +1089,7 @@ int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
                // update folders_prev so we can check for it in folderlist_clear_next()
                folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
 
-               file_change_dir(C, 1);
+               ED_file_change_dir(C, true);
        }
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
 
@@ -1184,7 +1279,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
 
        if (RNA_boolean_get(op->ptr, "open")) {
                BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir));
-               file_change_dir(C, 1);
+               ED_file_change_dir(C, true);
        }
 
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1289,7 +1384,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
 
                if (BLI_exists(sfile->params->dir)) {
                        /* if directory exists, enter it immediately */
-                       file_change_dir(C, 1);
+                       ED_file_change_dir(C, true);
 
                        /* don't do for now because it selects entire text instead of
                         * placing cursor at the end */
@@ -1358,7 +1453,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
                                BLI_cleanup_dir(G.main->name, filepath);
                                BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
                                sfile->params->file[0] = '\0';
-                               file_change_dir(C, 1);
+                               ED_file_change_dir(C, true);
                                UI_textbutton_activate_but(C, but);
                                WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
                        }
@@ -1369,7 +1464,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
                                        BLI_cleanup_dir(G.main->name, filepath);
                                        BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
                                        sfile->params->file[0] = '\0';
-                                       file_change_dir(C, 0);
+                                       ED_file_change_dir(C, false);
                                        UI_textbutton_activate_but(C, but);
                                        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
                                }
@@ -1417,37 +1512,37 @@ void FILE_OT_hidedot(struct wmOperatorType *ot)
        ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
 }
 
-ARegion *file_buttons_region(ScrArea *sa)
+ARegion *file_tools_region(ScrArea *sa)
 {
        ARegion *ar, *arnew;
-       
-       for (ar = sa->regionbase.first; ar; ar = ar->next)
-               if (ar->regiontype == RGN_TYPE_CHANNELS)
-                       return ar;
+
+       if ((ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS)) != NULL)
+               return ar;
 
        /* add subdiv level; after header */
-       for (ar = sa->regionbase.first; ar; ar = ar->next)
-               if (ar->regiontype == RGN_TYPE_HEADER)
-                       break;
+       ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
        
        /* is error! */
-       if (ar == NULL) return NULL;
-       
-       arnew = MEM_callocN(sizeof(ARegion), "buttons for file panels");
+       if (ar == NULL)
+               return NULL;
        
+       arnew = MEM_callocN(sizeof(ARegion), "tools for file");
        BLI_insertlinkafter(&sa->regionbase, ar, arnew);
-       arnew->regiontype = RGN_TYPE_CHANNELS;
+       arnew->regiontype = RGN_TYPE_TOOLS;
        arnew->alignment = RGN_ALIGN_LEFT;
-       
-       arnew->flag = RGN_FLAG_HIDDEN;
-       
+
+       ar = MEM_callocN(sizeof(ARegion), "tool props for file");
+       BLI_insertlinkafter(&sa->regionbase, arnew, ar);
+       ar->regiontype = RGN_TYPE_TOOL_PROPS;
+       ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
+
        return arnew;
 }
 
 static int file_bookmark_toggle_exec(bContext *C, wmOperator *UNUSED(unused))
 {
        ScrArea *sa = CTX_wm_area(C);
-       ARegion *ar = file_buttons_region(sa);
+       ARegion *ar = file_tools_region(sa);
        
        if (ar)
                ED_region_toggle_hidden(C, ar);
index c224da721fa8bd71e0a33b65f61da5386ae99630..3da83aa602819a68a09642a4b572ed97967398b0 100644 (file)
@@ -44,6 +44,8 @@
 
 #include "RNA_access.h"
 
+#include "ED_fileselect.h"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 
 
 #include <string.h>
 
-static void file_panel_cb(bContext *C, void *arg_entry, void *UNUSED(arg_v))
-{
-       wmOperatorType *ot = WM_operatortype_find("FILE_OT_select_bookmark", false);
-       PointerRNA ptr;
-       const char *entry = (char *)arg_entry;
-
-       WM_operator_properties_create_ptr(&ptr, ot);
-       RNA_string_set(&ptr, "dir", entry);
-       WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_REGION_WIN, &ptr);
-       WM_operator_properties_free(&ptr);
-}
-
-static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, short *nr, int icon, int allow_delete)
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-       uiBlock *block;
-       uiBut *but;
-       uiLayout *box, *col;
-       struct FSMenu *fsmenu = fsmenu_get();
-       int i, nentries = fsmenu_get_nentries(fsmenu, category);
-
-       /* reset each time */
-       *nr = -1;
-
-       /* hide if no entries */
-       if (nentries == 0)
-               return;
-
-       /* layout */
-       uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT);
-       block = uiLayoutGetBlock(pa->layout);
-       box = uiLayoutBox(pa->layout);
-       col = uiLayoutColumn(box, true);
-
-       for (i = 0; i < nentries; ++i) {
-               char dir[FILE_MAX];
-               char temp[FILE_MAX];
-               uiLayout *layout = uiLayoutRow(col, false);
-               char *entry;
-               
-               entry = fsmenu_get_entry(fsmenu, category, i);
-               
-               /* set this list item as active if we have a match */
-               if (sfile->params) {
-                       if (BLI_path_cmp(sfile->params->dir, entry) == 0) {
-                               *nr = i;
-                       }
-               }
-
-               /* create nice bookmark name, shows last directory in the full path currently */
-               BLI_strncpy(temp, entry, FILE_MAX);
-               BLI_add_slash(temp);
-               BLI_getlastdir(temp, dir, FILE_MAX);
-               BLI_del_slash(dir);
-
-               if (dir[0] == 0)
-                       BLI_strncpy(dir, entry, FILE_MAX);
-
-               /* create list item */
-               but = uiDefIconTextButS(block, UI_BTYPE_LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry);
-               UI_but_func_set(but, file_panel_cb, entry, NULL);
-               UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
-               UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT);
-
-               /* create delete button */
-               if (allow_delete && fsmenu_can_save(fsmenu, category, i)) {
-                       UI_block_emboss_set(block, UI_EMBOSS_NONE);
-                       uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i);
-                       UI_block_emboss_set(block, UI_EMBOSS);
-               }
-       }
-}
-
-static void file_panel_system(const bContext *C, Panel *pa)
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-
-       if (sfile)
-               file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0);
-}
-
-static int file_panel_system_bookmarks_poll(const bContext *C, PanelType *UNUSED(pt))
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-       return (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS));
-}
-
-static void file_panel_system_bookmarks(const bContext *C, Panel *pa)
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-
-       if (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS)) {
-               file_panel_category(C, pa, FS_CATEGORY_SYSTEM_BOOKMARKS, &sfile->systemnr, ICON_BOOKMARKS, 0);
-       }
-
-}
-
-static void file_panel_bookmarks(const bContext *C, Panel *pa)
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-       uiLayout *row;
-
-       if (sfile) {
-               row = uiLayoutRow(pa->layout, false);
-               uiItemO(row, IFACE_("Add"), ICON_ZOOMIN, "file.bookmark_add");
-               uiItemL(row, NULL, ICON_NONE);
-
-               file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, &sfile->bookmarknr, ICON_BOOKMARKS, 1);
-       }
-}
-
-static int file_panel_recent_poll(const bContext *C, PanelType *UNUSED(pt))
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-       return (sfile && !(U.uiflag & USER_HIDE_RECENT));
-}
-
-static void file_panel_recent(const bContext *C, Panel *pa)
-{
-       SpaceFile *sfile = CTX_wm_space_file(C);
-       uiLayout *row;
-
-       if (sfile) {
-               if (!(U.uiflag & USER_HIDE_RECENT)) {
-                       row = uiLayoutRow(pa->layout, false);
-                       uiItemO(row, IFACE_("Reset"), ICON_X, "file.reset_recent");
-                       uiItemL(row, NULL, ICON_NONE);
-
-                       file_panel_category(C, pa, FS_CATEGORY_RECENT, &sfile->recentnr, ICON_FILE_FOLDER, 0);
-               }
-       }
-}
-
-
 static int file_panel_operator_poll(const bContext *C, PanelType *UNUSED(pt))
 {
        SpaceFile *sfile = CTX_wm_space_file(C);
@@ -217,7 +85,7 @@ static void file_panel_operator(const bContext *C, Panel *pa)
        SpaceFile *sfile = CTX_wm_space_file(C);
        wmOperator *op = sfile->op;
        // int empty = 1, flag;
-       
+
        UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
 
        uiLayoutOperatorButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_LAYOUT_OP_SHOW_EMPTY);
@@ -229,36 +97,6 @@ void file_panels_register(ARegionType *art)
 {
        PanelType *pt;
 
-       pt = MEM_callocN(sizeof(PanelType), "spacetype file system directories");
-       strcpy(pt->idname, "FILE_PT_system");
-       strcpy(pt->label, N_("System"));
-       strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
-       pt->draw = file_panel_system;
-       BLI_addtail(&art->paneltypes, pt);
-
-       pt = MEM_callocN(sizeof(PanelType), "spacetype file system bookmarks");
-       strcpy(pt->idname, "FILE_PT_system_bookmarks");
-       strcpy(pt->label, N_("System Bookmarks"));
-       strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
-       pt->draw = file_panel_system_bookmarks;
-       pt->poll = file_panel_system_bookmarks_poll;
-       BLI_addtail(&art->paneltypes, pt);
-
-       pt = MEM_callocN(sizeof(PanelType), "spacetype file bookmarks");
-       strcpy(pt->idname, "FILE_PT_bookmarks");
-       strcpy(pt->label, N_("Bookmarks"));
-       strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
-       pt->draw = file_panel_bookmarks;
-       BLI_addtail(&art->paneltypes, pt);
-
-       pt = MEM_callocN(sizeof(PanelType), "spacetype file recent directories");
-       strcpy(pt->idname, "FILE_PT_recent");
-       strcpy(pt->label, N_("Recent"));
-       strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
-       pt->draw = file_panel_recent;
-       pt->poll = file_panel_recent_poll;
-       BLI_addtail(&art->paneltypes, pt);
-
        pt = MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
        strcpy(pt->idname, "FILE_PT_operator");
        strcpy(pt->label, N_("Operator"));
index c452f2e1ff4ea551880558aad51bfd5a1e8f5cc8..317573fe2524d9c3a5d32861a5ffa3d9138a5dc4 100644 (file)
@@ -597,7 +597,7 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar)
        return sfile->layout;
 }
 
-void file_change_dir(bContext *C, int checkdir)
+void ED_file_change_dir(bContext *C, const bool checkdir)
 {
        wmWindowManager *wm = CTX_wm_manager(C);
        SpaceFile *sfile = CTX_wm_space_file(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;
+}
index 831ec138474329c388054e54638dc1ac99ec17f8..fa925310c2bc909e5f49d92f37340fd69b5fce15 100644 (file)
 /* XXX could become UserPref */
 #define FSMENU_RECENT_MAX 10
 
-typedef enum FSMenuCategory {
-       FS_CATEGORY_SYSTEM,
-       FS_CATEGORY_SYSTEM_BOOKMARKS,
-       FS_CATEGORY_BOOKMARKS,
-       FS_CATEGORY_RECENT
-} FSMenuCategory;
-
-typedef enum FSMenuInsert {
-       FS_INSERT_SORTED = (1 << 0),
-       FS_INSERT_SAVE   = (1 << 1),
-       FS_INSERT_FIRST  = (1 << 2),   /* moves the item to the front of the list when its not already there */
-       FS_APPEND_LAST   = (1 << 3)   /* just append to preseve delivered order */
-} FSMenuInsert;
+enum FSMenuCategory;
+enum FSMenuInsert;
 
 struct FSMenu;
-
-struct FSMenu *fsmenu_get(void);
-
-/** Returns the number of entries in the Fileselect Menu */
-int     fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category);
-
-/** Returns the fsmenu entry at \a index (or NULL if a bad index)
- * or a separator.
- */
-char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+struct FSMenuEntry;
 
 /** Inserts a new fsmenu entry with the given \a path.
  * Duplicate entries are not added.
  * \param flag Options for inserting the entry.
  */
-void    fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const FSMenuInsert flag);
+void    fsmenu_insert_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *path, const char *name, const enum FSMenuInsert flag);
 
 /** Return whether the entry was created by the user and can be saved and deleted */
-short   fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+short   fsmenu_can_save(struct FSMenu *fsmenu, enum FSMenuCategory category, int index);
 
 /** Removes the fsmenu entry at the given \a index. */
-void    fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+void    fsmenu_remove_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, int index);
 
 /** saves the 'bookmarks' to the specified file */
 void    fsmenu_write_file(struct FSMenu *fsmenu, const char *filename);
@@ -90,5 +70,8 @@ void    fsmenu_free(void);
 /** Refresh system directory menu */
 void    fsmenu_refresh_system_category(struct FSMenu *fsmenu);
 
+/** Get active index based on given directory. */
+int     fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir);
+
 #endif
 
index f0555933146bd320e65edad7802d1467ea19d79a..6612d5ee9376b1897f63f9a1991c621160051a95 100644 (file)
@@ -71,7 +71,7 @@ static SpaceLink *file_new(const bContext *UNUSED(C))
 {
        ARegion *ar;
        SpaceFile *sfile;
-       
+
        sfile = MEM_callocN(sizeof(SpaceFile), "initfile");
        sfile->spacetype = SPACE_FILE;
 
@@ -81,12 +81,18 @@ static SpaceLink *file_new(const bContext *UNUSED(C))
        ar->regiontype = RGN_TYPE_HEADER;
        ar->alignment = RGN_ALIGN_TOP;
 
-       /* channel list region */
-       ar = MEM_callocN(sizeof(ARegion), "channel area for file");
+       /* Tools region */
+       ar = MEM_callocN(sizeof(ARegion), "tools area for file");
        BLI_addtail(&sfile->regionbase, ar);
-       ar->regiontype = RGN_TYPE_CHANNELS;
+       ar->regiontype = RGN_TYPE_TOOLS;
        ar->alignment = RGN_ALIGN_LEFT;
 
+       /* Tool props (aka operator) region */
+       ar = MEM_callocN(sizeof(ARegion), "tool props area for file");
+       BLI_addtail(&sfile->regionbase, ar);
+       ar->regiontype = RGN_TYPE_TOOL_PROPS;
+       ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
+
        /* ui list region */
        ar = MEM_callocN(sizeof(ARegion), "ui area for file");
        BLI_addtail(&sfile->regionbase, ar);
@@ -149,7 +155,7 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
        SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
 
        /* refresh system directory list */
-       fsmenu_refresh_system_category(fsmenu_get());
+       fsmenu_refresh_system_category(ED_fsmenu_get());
 
        if (sfile->layout) sfile->layout->dirty = true;
 }
@@ -187,11 +193,12 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
        return (SpaceLink *)sfilen;
 }
 
-static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
+static void file_refresh(const bContext *C, ScrArea *sa)
 {
        wmWindowManager *wm = CTX_wm_manager(C);
        SpaceFile *sfile = CTX_wm_space_file(C);
        FileSelectParams *params = ED_fileselect_get_params(sfile);
+       struct FSMenu *fsmenu = ED_fsmenu_get();
 
        if (!sfile->folders_prev) {
                sfile->folders_prev = folderlist_new();
@@ -208,6 +215,12 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
                                                 params->filter_glob,
                                                 params->filter_search);
 
+       /* Update the active indices of bookmarks & co. */
+       sfile->systemnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM, params->dir);
+       sfile->system_bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, params->dir);
+       sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir);
+       sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
+
        if (filelist_empty(sfile->files)) {
                thumbnails_stop(wm, sfile->files);
                filelist_readdir(sfile->files);
@@ -246,6 +259,14 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
        if (sfile->layout) {
                sfile->layout->dirty = true;
        }
+
+       if (BKE_area_find_region_type(sa, RGN_TYPE_TOOLS) == NULL) {
+               /* Create TOOLS/TOOL_PROPS regions. */
+               file_tools_region(sa);
+
+               ED_area_initialize(wm, CTX_wm_window(C), sa);
+               ED_area_tag_redraw(sa);
+       }
 }
 
 static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
@@ -382,6 +403,7 @@ static void file_operatortypes(void)
        WM_operatortype_append(FILE_OT_bookmark_toggle);
        WM_operatortype_append(FILE_OT_bookmark_add);
        WM_operatortype_append(FILE_OT_bookmark_delete);
+       WM_operatortype_append(FILE_OT_bookmark_move);
        WM_operatortype_append(FILE_OT_reset_recent);
        WM_operatortype_append(FILE_OT_hidedot);
        WM_operatortype_append(FILE_OT_filenum);
@@ -473,7 +495,7 @@ static void file_keymap(struct wmKeyConfig *keyconf)
 }
 
 
-static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
+static void file_tools_area_init(wmWindowManager *wm, ARegion *ar)
 {
        wmKeyMap *keymap;
 
@@ -485,12 +507,12 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
        WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
 }
 
-static void file_channel_area_draw(const bContext *C, ARegion *ar)
+static void file_tools_area_draw(const bContext *C, ARegion *ar)
 {
        ED_region_panels(C, ar, 1, NULL, -1);
 }
 
-static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void file_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
 {
 #if 0
        /* context changes */
@@ -616,12 +638,24 @@ void ED_spacetype_file(void)
 
        /* regions: channels (directories) */
        art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
-       art->regionid = RGN_TYPE_CHANNELS;
+       art->regionid = RGN_TYPE_TOOLS;
        art->prefsizex = 240;
+       art->prefsizey = 60;
+       art->keymapflag = ED_KEYMAP_UI;
+       art->listener = file_tools_area_listener;
+       art->init = file_tools_area_init;
+       art->draw = file_tools_area_draw;
+       BLI_addhead(&st->regiontypes, art);
+
+       /* regions: tool properties */
+       art = MEM_callocN(sizeof(ARegionType), "spacetype file operator region");
+       art->regionid = RGN_TYPE_TOOL_PROPS;
+       art->prefsizex = 0;
+       art->prefsizey = 240;
        art->keymapflag = ED_KEYMAP_UI;
-       art->listener = file_channel_area_listener;
-       art->init = file_channel_area_init;
-       art->draw = file_channel_area_draw;
+       art->listener = file_tools_area_listener;
+       art->init = file_tools_area_init;
+       art->draw = file_tools_area_draw;
        BLI_addhead(&st->regiontypes, art);
        file_panels_register(art);
 
@@ -655,12 +689,12 @@ void ED_file_read_bookmarks(void)
        
        fsmenu_free();
 
-       fsmenu_read_system(fsmenu_get(), true);
+       fsmenu_read_system(ED_fsmenu_get(), true);
 
        if (cfgdir) {
                char name[FILE_MAX];
                BLI_make_file_string("/", name, cfgdir, BLENDER_BOOKMARK_FILE);
-               fsmenu_read_bookmarks(fsmenu_get(), name);
+               fsmenu_read_bookmarks(ED_fsmenu_get(), name);
        }
 }
 
index 165f6113b6d2b308d367e5db91d4e459b088774b..e530841789bff5d7161b005c12cf215ef13e3a63 100644 (file)
@@ -638,9 +638,18 @@ typedef struct SpaceFile {
        struct FileLayout *layout;
        
        short recentnr, bookmarknr;
-       short systemnr, pad2;
+       short systemnr, system_bookmarknr;
 } SpaceFile;
 
+/* FSMenuEntry's without paths indicate seperators */
+typedef struct FSMenuEntry {
+       struct FSMenuEntry *next;
+
+       char *path;
+       char name[256];  /* FILE_MAXFILE */
+       short save;
+       short pad[3];
+} FSMenuEntry;
 
 /* FileSelectParams.display */
 enum FileDisplayTypeE {
index a62a06f161330cd2f2a264662a2340b707ec3a0b..577f27f564e1a9e0c3ab544e4b41d74ce8a41de6 100644 (file)
@@ -240,6 +240,7 @@ extern StructRNA RNA_FModifierNoise;
 extern StructRNA RNA_FModifierPython;
 extern StructRNA RNA_FModifierStepped;
 extern StructRNA RNA_FieldSettings;
+extern StructRNA RNA_FileBrowserFSMenuEntry;
 extern StructRNA RNA_FileSelectParams;
 extern StructRNA RNA_FloatProperty;
 extern StructRNA RNA_FloorConstraint;
index 382ed358e120d236468b350285e8ea271a5024b3..fc2b2d72ac9f8156f240f3546283e0beb040a793 100644 (file)
@@ -56,6 +56,8 @@
 #include "RE_engine.h"
 #include "RE_pipeline.h"
 
+#include "ED_fileselect.h"
+
 #include "RNA_enum_types.h"
 
 
@@ -204,6 +206,7 @@ static EnumPropertyItem buttons_texture_context_items[] = {
 #include "BKE_icons.h"
 
 #include "ED_buttons.h"
+#include "ED_fileselect.h"
 #include "ED_image.h"
 #include "ED_node.h"
 #include "ED_screen.h"
@@ -1368,6 +1371,271 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU
        ED_area_tag_refresh(sa);
 }
 
+/* File browser. */
+
+static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value)
+{
+       char *path = ED_fsmenu_entry_get_path(ptr->data);
+
+       strcpy(value, path ? path : "");
+}
+
+static int rna_FileBrowser_FSMenuEntry_path_length(PointerRNA *ptr)
+{
+       char *path = ED_fsmenu_entry_get_path(ptr->data);
+
+       return (int)(path ? strlen(path) : 0);
+}
+
+static void rna_FileBrowser_FSMenuEntry_path_set(PointerRNA *ptr, const char *value)
+{
+       FSMenuEntry *fsm = ptr->data;
+
+       /* Note: this will write to file immediately.
+        * Not nice (and to be fixed ultimately), but acceptable in this case for now. */
+       ED_fsmenu_entry_set_path(fsm, value);
+}
+
+static void rna_FileBrowser_FSMenuEntry_name_get(PointerRNA *ptr, char *value)
+{
+       strcpy(value, ED_fsmenu_entry_get_name(ptr->data));
+}
+
+static int rna_FileBrowser_FSMenuEntry_name_length(PointerRNA *ptr)
+{
+       return (int)strlen(ED_fsmenu_entry_get_name(ptr->data));
+}
+
+static void rna_FileBrowser_FSMenuEntry_name_set(PointerRNA *ptr, const char *value)
+{
+       FSMenuEntry *fsm = ptr->data;
+
+       /* Note: this will write to file immediately.
+        * Not nice (and to be fixed ultimately), but acceptable in this case for now. */
+       ED_fsmenu_entry_set_name(fsm, value);
+}
+
+static int rna_FileBrowser_FSMenuEntry_name_get_editable(PointerRNA *ptr)
+{
+       FSMenuEntry *fsm = ptr->data;
+
+       return fsm->save;
+}
+
+static void rna_FileBrowser_FSMenu_next(CollectionPropertyIterator *iter)
+{
+       ListBaseIterator *internal = &iter->internal.listbase;
+
+       if (internal->skip) {
+               do {
+                       internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next);
+                       iter->valid = (internal->link != NULL);
+               } while (iter->valid && internal->skip(iter, internal->link));
+       }
+       else {
+               internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next);
+               iter->valid = (internal->link != NULL);
+       }
+}
+
+static void rna_FileBrowser_FSMenu_begin(CollectionPropertyIterator *iter, FSMenuCategory category)
+{
+       ListBaseIterator *internal = &iter->internal.listbase;
+
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+       struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, category);
+
+       internal->link = (fsmentry) ? (Link *)fsmentry : NULL;
+       internal->skip = NULL;
+
+       iter->valid = (internal->link != NULL);
+}
+
+static PointerRNA rna_FileBrowser_FSMenu_get(CollectionPropertyIterator *iter)
+{
+       ListBaseIterator *internal = &iter->internal.listbase;
+       PointerRNA r_ptr;
+
+       RNA_pointer_create(NULL, &RNA_FileBrowserFSMenuEntry, internal->link, &r_ptr);
+
+       return r_ptr;
+}
+
+static void rna_FileBrowser_FSMenu_end(CollectionPropertyIterator *UNUSED(iter))
+{
+}
+
+static void rna_FileBrowser_FSMenuSystem_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+       rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM);
+}
+
+static int rna_FileBrowser_FSMenuSystem_data_length(PointerRNA *UNUSED(ptr))
+{
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+
+       return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+       rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuSystemBookmark_data_length(PointerRNA *UNUSED(ptr))
+{
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+
+       return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+       rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuBookmark_data_length(PointerRNA *UNUSED(ptr))
+{
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+
+       return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuRecent_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+       rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_RECENT);
+}
+
+static int rna_FileBrowser_FSMenuRecent_data_length(PointerRNA *UNUSED(ptr))
+{
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+
+       return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_RECENT);
+}
+
+static int rna_FileBrowser_FSMenu_active_get(PointerRNA *ptr, const FSMenuCategory category)
+{
+       SpaceFile *sf = ptr->data;
+       int actnr = -1;
+
+       switch (category) {
+               case FS_CATEGORY_SYSTEM:
+                       actnr = sf->systemnr;
+                       break;
+               case FS_CATEGORY_SYSTEM_BOOKMARKS:
+                       actnr = sf->system_bookmarknr;
+                       break;
+               case FS_CATEGORY_BOOKMARKS:
+                       actnr = sf->bookmarknr;
+                       break;
+               case FS_CATEGORY_RECENT:
+                       actnr = sf->recentnr;
+                       break;
+       }
+
+       return actnr;
+}
+
+static void rna_FileBrowser_FSMenu_active_set(PointerRNA *ptr, int value, const FSMenuCategory category)
+{
+       SpaceFile *sf = ptr->data;
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+       FSMenuEntry *fsm = ED_fsmenu_get_entry(fsmenu, category, value);
+
+       if (fsm && sf->params) {
+               switch (category) {
+                       case FS_CATEGORY_SYSTEM:
+                               sf->systemnr = value;
+                               break;
+                       case FS_CATEGORY_SYSTEM_BOOKMARKS:
+                               sf->system_bookmarknr = value;
+                               break;
+                       case FS_CATEGORY_BOOKMARKS:
+                               sf->bookmarknr = value;
+                               break;
+                       case FS_CATEGORY_RECENT:
+                               sf->recentnr = value;
+                               break;
+               }
+
+               BLI_strncpy(sf->params->dir, fsm->path, sizeof(sf->params->dir));
+       }
+}
+
+static void rna_FileBrowser_FSMenu_active_range(
+        PointerRNA *UNUSED(ptr), int *min, int *max, int *softmin, int *softmax, const FSMenuCategory category)
+{
+       struct FSMenu *fsmenu = ED_fsmenu_get();
+
+       *min = *softmin = -1;
+       *max = *softmax = ED_fsmenu_get_nentries(fsmenu, category) - 1;
+}
+
+static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *UNUSED(ptr))
+{
+       ED_file_change_dir(C, true);
+}
+
+static int rna_FileBrowser_FSMenuSystem_active_get(PointerRNA *ptr)
+{
+       return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystem_active_set(PointerRNA *ptr, int value)
+{
+       rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystem_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+       rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM);
+}
+
+static int rna_FileBrowser_FSMenuSystemBookmark_active_get(PointerRNA *ptr)
+{
+       return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_active_set(PointerRNA *ptr, int value)
+{
+       rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+       rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuBookmark_active_get(PointerRNA *ptr)
+{
+       return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_active_set(PointerRNA *ptr, int value)
+{
+       rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+       rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuRecent_active_get(PointerRNA *ptr)
+{
+       return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_RECENT);
+}
+
+static void rna_FileBrowser_FSMenuRecent_active_set(PointerRNA *ptr, int value)
+{
+       rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_RECENT);
+}
+
+static void rna_FileBrowser_FSMenuRecent_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+       rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_RECENT);
+}
+
 #else
 
 static EnumPropertyItem dt_uv_items[] = {
@@ -3332,6 +3600,37 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
 }
 
+static void rna_def_filemenu_entry(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "FileBrowserFSMenuEntry", NULL);
+       RNA_def_struct_sdna(srna, "FSMenuEntry");
+       RNA_def_struct_ui_text(srna, "File Select Parameters", "File Select Parameters");
+
+       prop = RNA_def_property(srna, "path", PROP_STRING, PROP_FILEPATH);
+       RNA_def_property_string_sdna(prop, NULL, "path");
+       RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_path_get",
+                                           "rna_FileBrowser_FSMenuEntry_path_length",
+                                           "rna_FileBrowser_FSMenuEntry_path_set");
+       RNA_def_property_ui_text(prop, "Path", "");
+
+       prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "name");
+       RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_name_get",
+                                           "rna_FileBrowser_FSMenuEntry_name_length",
+                                           "rna_FileBrowser_FSMenuEntry_name_set");
+       RNA_def_property_editable_func(prop, "rna_FileBrowser_FSMenuEntry_name_get_editable");
+       RNA_def_property_ui_text(prop, "Name", "");
+       RNA_def_struct_name_property(srna, prop);
+
+       prop = RNA_def_property(srna, "use_save", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "save", 1);
+       RNA_def_property_ui_text(prop, "Save", "Whether this path is saved in bookmarks, or generated from OS");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+}
+
 static void rna_def_space_filebrowser(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -3354,6 +3653,67 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
        prop = RNA_def_property(srna, "operator", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "op");
        RNA_def_property_ui_text(prop, "Active Operator", "");
+
+       /* bookmarks, recent files etc. */
+       prop = RNA_def_collection(srna, "system_folders", "FileBrowserFSMenuEntry", "System Folders",
+                                 "System's folders (usually root, available hard drives, etc)");
+       RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystem_data_begin", "rna_FileBrowser_FSMenu_next",
+                                         "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+                                         "rna_FileBrowser_FSMenuSystem_data_length", NULL, NULL, NULL);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       prop = RNA_def_int(srna, "system_folders_active", -1, -1, INT_MAX, "Active System Folder",
+                          "Index of active system folder (-1 if none)", -1, INT_MAX);
+       RNA_def_property_int_sdna(prop, NULL, "systemnr");
+       RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystem_active_get",
+                                  "rna_FileBrowser_FSMenuSystem_active_set", "rna_FileBrowser_FSMenuSystem_active_range");
+       RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+       prop = RNA_def_collection(srna, "system_bookmarks", "FileBrowserFSMenuEntry", "System Bookmarks",
+                                 "System's bookmarks");
+       RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_data_begin", "rna_FileBrowser_FSMenu_next",
+                                         "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+                                         "rna_FileBrowser_FSMenuSystemBookmark_data_length", NULL, NULL, NULL);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       prop = RNA_def_int(srna, "system_bookmarks_active", -1, -1, INT_MAX, "Active System Bookmark",
+                          "Index of active system bookmark (-1 if none)", -1, INT_MAX);
+       RNA_def_property_int_sdna(prop, NULL, "system_bookmarknr");
+       RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_active_get",
+                                  "rna_FileBrowser_FSMenuSystemBookmark_active_set", "rna_FileBrowser_FSMenuSystemBookmark_active_range");
+       RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+       prop = RNA_def_collection(srna, "bookmarks", "FileBrowserFSMenuEntry", "Bookmarks",
+                                 "User's bookmarks");
+       RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuBookmark_data_begin", "rna_FileBrowser_FSMenu_next",
+                                         "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+                                         "rna_FileBrowser_FSMenuBookmark_data_length", NULL, NULL, NULL);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       prop = RNA_def_int(srna, "bookmarks_active", -1, -1, INT_MAX, "Active Bookmark",
+                          "Index of active bookmark (-1 if none)", -1, INT_MAX);
+       RNA_def_property_int_sdna(prop, NULL, "bookmarknr");
+       RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuBookmark_active_get",
+                                  "rna_FileBrowser_FSMenuBookmark_active_set", "rna_FileBrowser_FSMenuBookmark_active_range");
+       RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+       prop = RNA_def_collection(srna, "recent_folders", "FileBrowserFSMenuEntry", "Recent Folders",
+                                 "");
+       RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuRecent_data_begin", "rna_FileBrowser_FSMenu_next",
+                                         "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+                                         "rna_FileBrowser_FSMenuRecent_data_length", NULL, NULL, NULL);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       prop = RNA_def_int(srna, "recent_folders_active", -1, -1, INT_MAX, "Active Recent Folder",
+                          "Index of active recent folder (-1 if none)", -1, INT_MAX);
+       RNA_def_property_int_sdna(prop, NULL, "recentnr");
+       RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuRecent_active_get",
+                                  "rna_FileBrowser_FSMenuRecent_active_set", "rna_FileBrowser_FSMenuRecent_active_range");
+       RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
 }
 
 static void rna_def_space_info(BlenderRNA *brna)
@@ -3957,6 +4317,7 @@ void RNA_def_space(BlenderRNA *brna)
        rna_def_space_sequencer(brna);
        rna_def_space_text(brna);
        rna_def_fileselect_params(brna);
+       rna_def_filemenu_entry(brna);
        rna_def_space_filebrowser(brna);
        rna_def_space_outliner(brna);
        rna_def_background_image(brna);
index d8c26b92706b87d696563b411229aed705ef5bd2..e4319632797c35c5b1b2fb0bf48f78a62266e2b6 100644 (file)
@@ -355,7 +355,16 @@ void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) RET_NONE
 void ED_render_engine_changed(struct Main *bmain) RET_NONE
 
 void ED_file_read_bookmarks(void) RET_NONE
+void ED_file_change_dir(struct bContext *C, const bool checkdir) RET_NONE
 void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain) RET_NONE
+struct FSMenu *ED_fsmenu_get(void) RET_NULL
+struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) RET_NULL
+int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) RET_ZERO
+struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) RET_NULL
+char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) RET_NULL
+void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *name) RET_NONE
+char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL
+void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE
 
 struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob) RET_NULL
 void PE_current_changed(struct Scene *scene, struct Object *ob) RET_NONE