diff options
-rw-r--r-- | release/ui/space_filebrowser.py | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 7 | ||||
-rw-r--r-- | source/blender/editors/include/ED_fileselect.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 85 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 88 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 6 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 38 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 30 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 7 |
11 files changed, 238 insertions, 39 deletions
diff --git a/release/ui/space_filebrowser.py b/release/ui/space_filebrowser.py index 820134d3e87..0c37e8c0816 100644 --- a/release/ui/space_filebrowser.py +++ b/release/ui/space_filebrowser.py @@ -17,11 +17,13 @@ class FILEBROWSER_HT_header(bpy.types.Header): row = layout.row() row.itemM("FILEBROWSER_MT_directory") row.itemM("FILEBROWSER_MT_bookmarks") - + row = layout.row(align=True) row.itemO("FILE_OT_parent", text="", icon='ICON_FILE_PARENT') row.itemO("FILE_OT_refresh", text="", icon='ICON_FILE_REFRESH') - + row.itemO("FILE_OT_previous", text="", icon='ICON_PREV_KEYFRAME') + row.itemO("FILE_OT_next", text="", icon='ICON_NEXT_KEYFRAME') + layout.itemR(params, "display", expand=True, text="") layout.itemR(params, "sort", expand=True, text="") diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 93de096e7b4..fd86c436558 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4472,13 +4472,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) SpaceFile *sfile= (SpaceFile *)sl; sfile->files= NULL; + sfile->folders_prev= NULL; + sfile->folders_next= NULL; sfile->params= NULL; sfile->op= NULL; - /* XXX needs checking - best solve in filesel itself - if(sfile->libfiledata) - BLO_blendhandle_close(sfile->libfiledata); - sfile->libfiledata= 0; - */ } else if(sl->spacetype==SPACE_IMASEL) { SpaceImaSel *simasel= (SpaceImaSel *)sl; diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 01882ecd9bc..1b8524eea33 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -69,7 +69,7 @@ typedef struct FileLayout struct FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile); -short ED_fileselect_set_params(struct SpaceFile *sfile, const char *title, const char *path, +short ED_fileselect_set_params(struct SpaceFile *sfile, const char *title, const char *dir, const char *path, short flag, short display, short filter, short sort); void ED_fileselect_reset_params(struct SpaceFile *sfile); diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 5a440be6962..2f3fae47abb 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -65,6 +65,8 @@ void FILE_OT_loadimages(struct wmOperatorType *ot); void FILE_OT_exec(struct wmOperatorType *ot); void FILE_OT_cancel(struct wmOperatorType *ot); void FILE_OT_parent(struct wmOperatorType *ot); +void FILE_OT_previous(struct wmOperatorType *ot); +void FILE_OT_next(struct wmOperatorType *ot); void FILE_OT_refresh(struct wmOperatorType *ot); void FILE_OT_bookmark_toggle(struct wmOperatorType *ot); void FILE_OT_filenum(struct wmOperatorType *ot); @@ -72,11 +74,14 @@ void FILE_OT_filenum(struct wmOperatorType *ot); int file_exec(bContext *C, struct wmOperator *unused); int file_cancel_exec(bContext *C, struct wmOperator *unused); int file_parent_exec(bContext *C, struct wmOperator *unused); +int file_previous_exec(bContext *C, struct wmOperator *unused); +int file_next_exec(bContext *C, struct wmOperator *unused); int file_hilight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my); /* filesel.c */ float file_string_width(const char* str); float file_font_pointsize(); +void file_change_dir(struct SpaceFile *sfile); /* file_panels.c */ void file_panels_register(struct ARegionType *art); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index fa377c06184..bb56ec94d7b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -146,9 +146,7 @@ static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short v strcat(params->dir,"/"); params->file[0] = '\0'; BLI_cleanup_dir(G.sce, params->dir); - filelist_setdir(sfile->files, params->dir); - filelist_free(sfile->files); - params->active_file = -1; + file_change_dir(sfile); } } else if (file) @@ -305,10 +303,8 @@ static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) RNA_string_get(op->ptr, "dir", entry); BLI_strncpy(params->dir, entry, sizeof(params->dir)); BLI_cleanup_dir(G.sce, params->dir); - filelist_free(sfile->files); - filelist_setdir(sfile->files, params->dir); - params->file[0] = '\0'; - params->active_file = -1; + file_change_dir(sfile); + params->file[0] = '\0'; WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); } @@ -467,7 +463,10 @@ void FILE_OT_highlight(struct wmOperatorType *ot) int file_cancel_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - + + folderlist_free(sfile->folders_prev); + folderlist_free(sfile->folders_next); + WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_CANCEL); sfile->op = NULL; @@ -529,6 +528,9 @@ int file_exec(bContext *C, wmOperator *unused) } } + folderlist_free(sfile->folders_prev); + folderlist_free(sfile->folders_next); + fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir,0, 1); BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs"); fsmenu_write_file(fsmenu_get(), name); @@ -556,9 +558,7 @@ int file_parent_exec(bContext *C, wmOperator *unused) if(sfile->params) { BLI_parent_dir(sfile->params->dir); - filelist_setdir(sfile->files, sfile->params->dir); - filelist_free(sfile->files); - sfile->params->active_file = -1; + file_change_dir(sfile); } WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); @@ -583,17 +583,74 @@ int file_refresh_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + file_change_dir(sfile); + + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + + return OPERATOR_FINISHED; + +} + +void FILE_OT_previous(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Previous Folder"; + ot->idname= "FILE_OT_previous"; + + /* api callbacks */ + ot->exec= file_previous_exec; + ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ +} + +int file_previous_exec(bContext *C, wmOperator *unused) +{ + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + if(sfile->params) { - filelist_setdir(sfile->files, sfile->params->dir); - filelist_free(sfile->files); - sfile->params->active_file = -1; + if (!sfile->folders_next) + sfile->folders_next = folderlist_new(); + + folderlist_pushdir(sfile->folders_next, sfile->params->dir); + folderlist_popdir(sfile->folders_prev, sfile->params->dir); + folderlist_pushdir(sfile->folders_next, sfile->params->dir); + + file_change_dir(sfile); } WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); return OPERATOR_FINISHED; +} +void FILE_OT_next(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Next Folder"; + ot->idname= "FILE_OT_next"; + + /* api callbacks */ + ot->exec= file_next_exec; + ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ } +int file_next_exec(bContext *C, wmOperator *unused) +{ + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + if(sfile->params) { + if (!sfile->folders_next) + sfile->folders_next = folderlist_new(); + + folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + folderlist_popdir(sfile->folders_next, sfile->params->dir); + + // update folder_prev so we can check for it in folderlist_clear_next() + folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + + file_change_dir(sfile); + } + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + + return OPERATOR_FINISHED; +} void FILE_OT_refresh(struct wmOperatorType *ot) { diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 573aed72728..ab5dac1a727 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -123,6 +123,12 @@ typedef struct FileList ListBase threads; } FileList; +typedef struct FolderList +{ + struct FolderList *next, *prev; + char *foldername; +} FolderList; + #define SPECIAL_IMG_SIZE 48 #define SPECIAL_IMG_ROWS 4 #define SPECIAL_IMG_COLS 4 @@ -354,6 +360,86 @@ void filelist_free_icons() } } +//-----------------FOLDERLIST (previous/next) --------------// +struct ListBase* folderlist_new() +{ + ListBase* p = MEM_callocN( sizeof(ListBase), "folderlist" ); + return p; +} + +void folderlist_popdir(struct ListBase* folderlist, const char *dir) +{ + const char *prev_dir; + struct FolderList *folder; + folder = folderlist->last; + + if(folder){ + // remove the current directory + MEM_freeN(folder->foldername); + BLI_freelinkN(folderlist, folder); + + folder = folderlist->last; + if(folder){ + prev_dir = folder->foldername; + BLI_strncpy(dir, prev_dir, FILE_MAXDIR); + } + } + // delete the folder next or use setdir directly before PREVIOUS OP +} + +void folderlist_pushdir(ListBase* folderlist, const char *dir) +{ + struct FolderList *folder, *previous_folder; + previous_folder = folderlist->last; + + // check if already exists + if(previous_folder){ + if(! strcmp(previous_folder->foldername, dir)){ + return; + } + } + + // create next folder element + folder = (FolderList*)MEM_mallocN(sizeof(FolderList),"FolderList"); + folder->foldername = (char*)MEM_mallocN(sizeof(char)*(strlen(dir)+1), "foldername"); + folder->foldername[0] = '\0'; + + BLI_strncpy(folder->foldername, dir, FILE_MAXDIR); + + // add it to the end of the list + BLI_addtail(folderlist, folder); +} + +int folderlist_clear_next(struct SpaceFile *sfile) +{ + struct FolderList *folder; + + // if there is no folder_next there is nothing we can clear + if (!sfile->folders_next) + return 0; + + // if previous_folder, next_folder or refresh_folder operators are executed it doesn't clear folder_next + folder = sfile->folders_prev->last; + if ((!folder) ||(!strcmp(folder->foldername, sfile->params->dir))) + return 0; + + // eventually clear flist->folders_next + return 1; +} + +void folderlist_free(ListBase* folderlist) +{ + FolderList *folder; + if (folderlist){ + for(folder= folderlist->last; folder; folder= folderlist->last) { + MEM_freeN(folder->foldername); + BLI_freelinkN(folderlist, folder); + } + } + folderlist= NULL; +} + +//------------------FILELIST------------------------// struct FileList* filelist_new() { FileList* p = MEM_callocN( sizeof(FileList), "filelist" ); @@ -375,7 +461,7 @@ void filelist_free(struct FileList* filelist) int i; if (!filelist) { - printf("Attemtping to delete empty filelist.\n"); + printf("Attempting to delete empty filelist.\n"); return; } diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index e929e028849..0f8db98b7ab 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -38,6 +38,7 @@ extern "C" { #endif struct FileList; +struct FolderList; struct direntry; struct BlendHandle; struct Scene; @@ -70,6 +71,11 @@ int filelist_empty(struct FileList* filelist); void filelist_parent(struct FileList* filelist); void filelist_setfiletypes(struct FileList* filelist, short has_quicktime); +struct ListBase * folderlist_new(); +void folderlist_free(struct ListBase* folderlist); +void folderlist_popdir(struct ListBase* folderlist, const char *dir); +void folderlist_pushdir(struct ListBase* folderlist, const char *dir); +int folderlist_clear_next(struct SpaceFile* sfile); #ifdef __cplusplus } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index ea42ad80fe6..c42c83eda98 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -84,12 +84,12 @@ FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile) { if (!sfile->params) { - ED_fileselect_set_params(sfile, "", "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORT_ALPHA); + ED_fileselect_set_params(sfile, "", NULL, "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORT_ALPHA); } return sfile->params; } -short ED_fileselect_set_params(SpaceFile *sfile, const char *title, const char *path, +short ED_fileselect_set_params(SpaceFile *sfile, const char *title, const char *last_dir, const char *path, short flag, short display, short filter, short sort) { char name[FILE_MAX], dir[FILE_MAX], file[FILE_MAX]; @@ -107,14 +107,19 @@ short ED_fileselect_set_params(SpaceFile *sfile, const char *title, const char * params->sort = sort; BLI_strncpy(params->title, title, sizeof(params->title)); - - BLI_strncpy(name, path, sizeof(name)); - BLI_convertstringcode(name, G.sce); - BLI_split_dirfile(name, dir, file); - BLI_strncpy(params->file, file, sizeof(params->file)); - BLI_strncpy(params->dir, dir, sizeof(params->dir)); - BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ + if(last_dir){ + BLI_strncpy(params->dir, last_dir, sizeof(params->dir)); + } + else { + BLI_strncpy(name, path, sizeof(name)); + BLI_convertstringcode(name, G.sce); + + BLI_split_dirfile(name, dir, file); + BLI_strncpy(params->file, file, sizeof(params->file)); + BLI_strncpy(params->dir, dir, sizeof(params->dir)); + BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ + } return 1; } @@ -279,3 +284,18 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar } return sfile->layout; } + +void file_change_dir(struct SpaceFile *sfile) +{ + if (sfile->params) { + filelist_setdir(sfile->files, sfile->params->dir); + + if(folderlist_clear_next(sfile)) + folderlist_free(sfile->folders_next); + + folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + + filelist_free(sfile->files); + sfile->params->active_file = -1; + } +} diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 9c30a0ed988..3167d2809c9 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -124,6 +124,18 @@ static void file_free(SpaceLink *sl) sfile->files= NULL; } + if(sfile->folders_prev) { + folderlist_free(sfile->folders_prev); + MEM_freeN(sfile->folders_prev); + sfile->folders_prev= NULL; + } + + if(sfile->folders_next) { + folderlist_free(sfile->folders_next); + MEM_freeN(sfile->folders_next); + sfile->folders_next= NULL; + } + if (sfile->params) { if(sfile->params->pupmenu) MEM_freeN(sfile->params->pupmenu); @@ -153,11 +165,15 @@ static SpaceLink *file_duplicate(SpaceLink *sl) sfilen->op = NULL; /* file window doesn't own operators */ sfilen->files = filelist_new(); - + if(sfileo->folders_prev) + sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev); + + if(sfileo->folders_next) + sfilen->folders_next = MEM_dupallocN(sfileo->folders_next); + if(sfileo->params) { sfilen->params= MEM_dupallocN(sfileo->params); - - filelist_setdir(sfilen->files, sfilen->params->dir); + file_change_dir(sfilen); } if (sfileo->layout) { sfilen->layout= MEM_dupallocN(sfileo->layout); @@ -170,9 +186,11 @@ static void file_refresh(const bContext *C, ScrArea *sa) SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); FileSelectParams *params = ED_fileselect_get_params(sfile); + if (!sfile->folders_prev) + sfile->folders_prev = folderlist_new(); if (!sfile->files) { sfile->files = filelist_new(); - filelist_setdir(sfile->files, params->dir); + file_change_dir(sfile); params->active_file = -1; // added this so it opens nicer (ton) } filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT); @@ -295,6 +313,8 @@ void file_operatortypes(void) WM_operatortype_append(FILE_OT_exec); WM_operatortype_append(FILE_OT_cancel); WM_operatortype_append(FILE_OT_parent); + WM_operatortype_append(FILE_OT_previous); + WM_operatortype_append(FILE_OT_next); WM_operatortype_append(FILE_OT_refresh); WM_operatortype_append(FILE_OT_bookmark_toggle); WM_operatortype_append(FILE_OT_add_bookmark); @@ -313,6 +333,8 @@ void file_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "FILE_OT_hidedot", HKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "FILE_OT_previous", BACKSPACEKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "FILE_OT_next", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0); /* keys for main area */ keymap= WM_keymap_listbase(wm, "FileMain", SPACE_FILE, 0); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 53dc5ed26e8..796da7e7f5d 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -217,6 +217,9 @@ typedef struct SpaceFile { struct FileList *files; /* holds the list of files to show */ + ListBase* folders_prev; /* holds the list of previous directories to show */ + ListBase* folders_next; /* holds the list of next directories (pushed from previous) to show */ + /* operator that is invoking fileselect op->exec() will be called on the 'Load' button. if operator provides op->cancel(), then this will be invoked diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e520067b9e5..b5d51ef650b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -780,7 +780,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa case EVT_FILESELECT_FULL_OPEN: { short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORT_ALPHA; - char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); + char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); if(event->val==EVT_FILESELECT_OPEN) ED_area_newspace(C, handler->op_area, SPACE_FILE); @@ -798,9 +798,11 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa filter = sfile->params->filter; display = sfile->params->display; sort = sfile->params->sort; + dir = sfile->params->dir; } - ED_fileselect_set_params(sfile, handler->op->type->name, path, flag, display, filter, sort); + ED_fileselect_set_params(sfile, handler->op->type->name, dir, path, flag, display, filter, sort); + dir = NULL; MEM_freeN(path); action= WM_HANDLER_BREAK; @@ -1501,4 +1503,3 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) break; } } - |