diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_filebrowser.py | 125 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 30 | ||||
-rw-r--r-- | source/blender/editors/include/ED_fileselect.h | 35 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 177 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_panels.c | 168 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/fsmenu.c | 207 | ||||
-rw-r--r-- | source/blender/editors/space_file/fsmenu.h | 35 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 64 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 11 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 361 | ||||
-rw-r--r-- | source/blenderplayer/bad_level_call_stubs/stubs.c | 9 |
17 files changed, 930 insertions, 305 deletions
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 6fe50c7eeb5..cda3dfe499d 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -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__) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 2c53a247f6d..610a63cb954 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -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 diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 4ca1a44d64e..572566df6a2 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -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); + } + } + } + } + } + } } diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index f2a6ce0b129..b81ea55cca8 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -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__ */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 83b22bb1a8a..4225b4bbd6e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -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); } /** diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 57611930e99..9fe6ed73205 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -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; diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 7147353b3f1..31d479b4617 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -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); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index ba6f91e8301..a0e312e72ef 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -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); diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index c224da721fa..3da83aa6028 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -44,6 +44,8 @@ #include "RNA_access.h" +#include "ED_fileselect.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -55,140 +57,6 @@ #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")); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index c452f2e1ff4..317573fe252 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -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); diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 05dfdf66ab6..8d4384acba6 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -40,6 +40,12 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BKE_appdir.h" + +#include "DNA_space_types.h" + +#include "ED_fileselect.h" + #ifdef WIN32 # include <windows.h> /* need to include windows.h so _WIN32_IE is defined */ # ifndef _WIN32_IE @@ -63,15 +69,6 @@ /* FSMENU HANDLING */ -/* FSMenuEntry's without paths indicate seperators */ -typedef struct _FSMenuEntry FSMenuEntry; -struct _FSMenuEntry { - FSMenuEntry *next; - - char *path; - short save; -}; - typedef struct FSMenu { FSMenuEntry *fsmenu_system; FSMenuEntry *fsmenu_system_bookmarks; @@ -81,7 +78,7 @@ typedef struct FSMenu { static FSMenu *g_fsmenu = NULL; -FSMenu *fsmenu_get(void) +FSMenu *ED_fsmenu_get(void) { if (!g_fsmenu) { g_fsmenu = MEM_callocN(sizeof(struct FSMenu), "fsmenu"); @@ -89,7 +86,7 @@ FSMenu *fsmenu_get(void) return g_fsmenu; } -static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) +struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_head = NULL; @@ -110,7 +107,7 @@ static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory ca return fsm_head; } -static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) +void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) { switch (category) { case FS_CATEGORY_SYSTEM: @@ -128,47 +125,115 @@ static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, } } -int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) +int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_iter; int count = 0; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { count++; } return count; } -char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx) +FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { - idx--; + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && index; fsm_iter = fsm_iter->next) { + index--; + } + + return fsm_iter; +} + +char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) +{ + return fsentry->path; +} + +void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path) +{ + if ((!fsentry->path || !path || !STREQ(path, fsentry->path)) && (fsentry->path != path)) { + char tmp_name[FILE_MAXFILE]; + + MEM_SAFE_FREE(fsentry->path); + + fsentry->path = (path && path[0]) ? BLI_strdup(path) : NULL; + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } +} + +static void fsmenu_entry_generate_name(struct FSMenuEntry *fsentry, char *name, size_t name_size) +{ + char temp[FILE_MAX]; + + BLI_strncpy(temp, fsentry->path, FILE_MAX); + BLI_add_slash(temp); + BLI_getlastdir(temp, name, name_size); + BLI_del_slash(name); + if (!name[0]) { + name[0] = '/'; + name[1] = '\0'; } +} - return fsm_iter ? fsm_iter->path : NULL; +char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) +{ + if (fsentry->name[0]) { + return fsentry->name; + } + else { + /* Here we abuse fsm_iter->name, keeping first char NULL. */ + char *name = fsentry->name + 1; + size_t name_size = sizeof(fsentry->name) - 1; + + fsmenu_entry_generate_name(fsentry, name, name_size); + return name; + } +} + +void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) +{ + if (!STREQ(name, fsentry->name)) { + char tmp_name[FILE_MAXFILE]; + size_t tmp_name_size = sizeof(tmp_name); + + fsmenu_entry_generate_name(fsentry, tmp_name, tmp_name_size); + if (!name[0] || STREQ(tmp_name, name)) { + /* reset name to default behavior. */ + fsentry->name[0] = '\0'; + } + else { + BLI_strncpy(fsentry->name, name, sizeof(fsentry->name)); + } + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } } short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { idx--; } return fsm_iter ? fsm_iter->save : 0; } -void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, FSMenuInsert flag) +void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const char *name, FSMenuInsert flag) { FSMenuEntry *fsm_prev; FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); fsm_prev = fsm_head; /* this is odd and not really correct? */ for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) { @@ -179,7 +244,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c if (fsm_iter != fsm_head) { fsm_prev->next = fsm_iter->next; fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } return; @@ -201,11 +266,17 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c fsm_iter = MEM_mallocN(sizeof(*fsm_iter), "fsme"); fsm_iter->path = BLI_strdup(path); fsm_iter->save = (flag & FS_INSERT_SAVE) != 0; + if (name && name[0]) { + BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name)); + } + else { + fsm_iter->name[0] = '\0'; + } if (fsm_prev) { if (flag & FS_INSERT_FIRST) { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } else { fsm_iter->next = fsm_prev->next; @@ -214,7 +285,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c } else { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } @@ -224,7 +295,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) idx--; @@ -241,7 +312,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx } else { fsm_head = fsm_iter->next; - fsmenu_set_category(fsmenu, category, fsm_head); + ED_fsmenu_set_category(fsmenu, category, fsm_head); } /* free entry */ MEM_freeN(fsm_iter->path); @@ -253,20 +324,29 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) { FSMenuEntry *fsm_iter = NULL; + char fsm_name[FILE_MAX]; int nwritten = 0; FILE *fp = BLI_fopen(filename, "w"); if (!fp) return; - + fprintf(fp, "[Bookmarks]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } fprintf(fp, "[Recent]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } @@ -276,12 +356,15 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) { char line[FILE_MAXDIR]; + char name[FILE_MAXFILE]; FSMenuCategory category = FS_CATEGORY_BOOKMARKS; FILE *fp; fp = BLI_fopen(filename, "r"); if (!fp) return; + name[0] = '\0'; + while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */ if (STREQLEN(line, "[Bookmarks]", 11)) { category = FS_CATEGORY_BOOKMARKS; @@ -289,6 +372,15 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) else if (STREQLEN(line, "[Recent]", 8)) { category = FS_CATEGORY_RECENT; } + else if (line[0] == '!') { + int len = strlen(line); + if (len > 0) { + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + BLI_strncpy(name, line + 1, sizeof(name)); + } + } else { int len = strlen(line); if (len > 0) { @@ -302,9 +394,11 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) if (BLI_exists(line)) #endif { - fsmenu_insert_entry(fsmenu, category, line, FS_INSERT_SAVE); + fsmenu_insert_entry(fsmenu, category, line, name, FS_INSERT_SAVE); } } + /* always reset name. */ + name[0] = '\0'; } } fclose(fp); @@ -329,16 +423,16 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) tmps[2] = '\\'; tmps[3] = 0; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, NULL, FS_INSERT_SORTED); } } /* Adding Desktop and My Documents */ if (read_bookmarks) { SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else @@ -361,7 +455,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) FSRefMakePath(&dir, path, FILE_MAX); if (!STREQ((char *)path, "/home") && !STREQ((char *)path, "/net")) { /* /net and /home are meaningless on OSX, home folders are stored in /Users */ - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, NULL, FS_INSERT_SORTED); } } @@ -371,26 +465,26 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) home = getenv("HOME"); if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Documents/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Pictures/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Music/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Movies/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else /* OSX 10.6+ */ @@ -410,7 +504,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) continue; CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED); } CFRelease(volEnum); @@ -447,7 +541,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Exclude "all my files" as it makes no sense in blender fileselector */ /* Exclude "airdrop" if wlan not active as it would show "" ) */ if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_APPEND_LAST); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST); } CFRelease(pathString); @@ -466,10 +560,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } @@ -494,10 +588,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) len = strlen(mnt->mnt_dir); if (len && mnt->mnt_dir[len - 1] != '/') { BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, NULL, FS_INSERT_SORTED); } else { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, FS_INSERT_SORTED); } found = 1; @@ -510,7 +604,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* fallback */ if (!found) - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, FS_INSERT_SORTED); } } #endif @@ -520,7 +614,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) { - FSMenuEntry *fsm_iter = fsmenu_get_category(fsmenu, category); + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); while (fsm_iter) { FSMenuEntry *fsm_next = fsm_iter->next; @@ -537,10 +631,10 @@ static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) void fsmenu_refresh_system_category(struct FSMenu *fsmenu) { fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); /* Add all entries to system category */ fsmenu_read_system(fsmenu, true); @@ -559,3 +653,16 @@ void fsmenu_free(void) g_fsmenu = NULL; } +int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir) +{ + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); + int i; + + for (i = 0; fsm_iter; fsm_iter = fsm_iter->next, i++) { + if (BLI_path_cmp(dir, fsm_iter->path) == 0) { + return i; + } + } + + return -1; +} diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h index 831ec138474..fa925310c2b 100644 --- a/source/blender/editors/space_file/fsmenu.h +++ b/source/blender/editors/space_file/fsmenu.h @@ -37,43 +37,23 @@ /* 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 diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f0555933146..6612d5ee937 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -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); } } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 165f6113b6d..e530841789b 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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 { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index a62a06f1613..577f27f564e 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 382ed358e12..fc2b2d72ac9 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -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); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index d8c26b92706..e4319632797 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -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 |