diff options
Diffstat (limited to 'source/blender/editors/space_file/file_ops.c')
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 465 |
1 files changed, 376 insertions, 89 deletions
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 0c6cadc05c1..0d36bac7505 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -42,6 +42,8 @@ #include "ED_screen.h" #include "ED_fileselect.h" +#include "MEM_guardedalloc.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -135,25 +137,16 @@ static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short v params->active_file = last_file; if(file && S_ISDIR(file->type)) { - /* the path is too long and we are not going up! */ - if (strcmp(file->relname, ".") && - strcmp(file->relname, "..") && - strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) + /* the path is too long! */ + if (strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) { // XXX error("Path too long, cannot enter this directory"); } else { - if (strcmp(file->relname, "..")==0) { - /* avoids /../../ */ - BLI_parent_dir(params->dir); - } else { - strcat(params->dir, file->relname); - 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; + BLI_cleanup_dir(G.sce, params->dir); + strcat(params->dir, file->relname); + BLI_add_slash(params->dir); + params->file[0] = '\0'; + file_change_dir(sfile); } } else if (file) @@ -190,7 +183,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op) rect.xmax= RNA_int_get(op->ptr, "xmax"); rect.ymax= RNA_int_get(op->ptr, "ymax"); - BLI_isect_rctf(&(ar->v2d.mask), &rect, &rect); + BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); file_select(sfile, ar, &rect, val ); WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -234,7 +227,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) /* single select, deselect all selected first */ file_deselect_all(sfile); file_select(sfile, ar, &rect, val ); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); } return OPERATOR_FINISHED; } @@ -299,89 +292,104 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) /* ---------- BOOKMARKS ----------- */ -static int file_select_bookmark_category(SpaceFile* sfile, ARegion* ar, short x, short y, FSMenuCategory category) +static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { - struct FSMenu* fsmenu = fsmenu_get(); - int nentries = fsmenu_get_nentries(fsmenu, category); - int linestep = file_font_pointsize()*2.0f; - short xs, ys; - int i; - int selected = -1; + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - for (i=0; i < nentries; ++i) { - fsmenu_get_pos(fsmenu, category, i, &xs, &ys); - if ( (y<=ys) && (y>ys-linestep) ) { - fsmenu_select_entry(fsmenu, category, i); - selected = i; - break; - } + if(RNA_struct_find_property(op->ptr, "dir")) { + char entry[256]; + FileSelectParams* params = sfile->params; + + RNA_string_get(op->ptr, "dir", entry); + BLI_strncpy(params->dir, entry, sizeof(params->dir)); + BLI_cleanup_dir(G.sce, params->dir); + file_change_dir(sfile); + params->file[0] = '\0'; + + WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); } - return selected; + + return OPERATOR_FINISHED; } -static void file_select_bookmark(SpaceFile* sfile, ARegion* ar, short x, short y) +void FILE_OT_select_bookmark(wmOperatorType *ot) { - float fx, fy; - int selected; - FSMenuCategory category = FS_CATEGORY_SYSTEM; - - if (BLI_in_rcti(&ar->v2d.mask, x, y)) { - char *entry; + /* identifiers */ + ot->name= "Select Directory"; + ot->idname= "FILE_OT_select_bookmark"; + + /* api callbacks */ + ot->invoke= bookmark_select_invoke; + ot->poll= ED_operator_file_active; - UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy); - selected = file_select_bookmark_category(sfile, ar, fx, fy, FS_CATEGORY_SYSTEM); - if (selected<0) { - category = FS_CATEGORY_BOOKMARKS; - selected = file_select_bookmark_category(sfile, ar, fx, fy, category); - } - if (selected<0) { - category = FS_CATEGORY_RECENT; - selected = file_select_bookmark_category(sfile, ar, fx, fy, category); - } - - if (selected>=0) { - entry= fsmenu_get_entry(fsmenu_get(), category, selected); - /* which string */ - if (entry) { - FileSelectParams* params = sfile->params; - 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; - } - } - } + RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); } -static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int bookmark_add_invoke(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa= CTX_wm_area(C); - ARegion *ar= CTX_wm_region(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + struct FSMenu* fsmenu = fsmenu_get(); + struct FileSelectParams* params= ED_fileselect_get_params(sfile); - short x, y; - - x = event->x - ar->winrct.xmin; - y = event->y - ar->winrct.ymin; + if (params->dir[0] != '\0') { + char name[FILE_MAX]; + + fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, 0, 1); + BLI_make_file_string("/", name, BLI_gethome(), ".Bfs"); + fsmenu_write_file(fsmenu, name); + } - file_select_bookmark(sfile, ar, x, y); ED_area_tag_redraw(sa); return OPERATOR_FINISHED; } -void FILE_OT_select_bookmark(wmOperatorType *ot) +void FILE_OT_add_bookmark(wmOperatorType *ot) { /* identifiers */ - ot->name= "Select Directory"; - ot->idname= "FILE_OT_select_bookmark"; + ot->name= "Add Bookmark"; + ot->idname= "FILE_OT_add_bookmark"; /* api callbacks */ - ot->invoke= bookmark_select_invoke; + ot->invoke= bookmark_add_invoke; ot->poll= ED_operator_file_active; } +static int bookmark_delete_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + 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"); + if ( (index >-1) && (index < nentries)) { + char name[FILE_MAX]; + + fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); + BLI_make_file_string("/", name, BLI_gethome(), ".Bfs"); + fsmenu_write_file(fsmenu, name); + ED_area_tag_redraw(sa); + } + } + + return OPERATOR_FINISHED; +} + +void FILE_OT_delete_bookmark(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Bookmark"; + ot->idname= "FILE_OT_delete_bookmark"; + + /* api callbacks */ + ot->invoke= bookmark_delete_invoke; + ot->poll= ED_operator_file_active; + + RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); +} + + static int loadimages_invoke(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa= CTX_wm_area(C); @@ -455,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; @@ -517,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); @@ -543,13 +557,14 @@ int file_parent_exec(bContext *C, wmOperator *unused) SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); 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; + if (BLI_has_parent(sfile->params->dir)) { + BLI_parent_dir(sfile->params->dir); + BLI_cleanup_dir(G.sce, sfile->params->dir); + file_change_dir(sfile); + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + } } - ED_area_tag_redraw(CTX_wm_area(C)); - + return OPERATOR_FINISHED; } @@ -571,15 +586,168 @@ 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; +} + +int file_directory_new_exec(bContext *C, wmOperator *unused) +{ + char tmpstr[FILE_MAX]; + char tmpdir[FILE_MAXFILE]; + int i = 1; + + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + + if(sfile->params) { + + BLI_strncpy(tmpstr, sfile->params->dir, FILE_MAX); + BLI_join_dirfile(tmpstr, tmpstr, "New Folder"); + while (BLI_exists(tmpstr)) { + BLI_snprintf(tmpdir, FILE_MAXFILE, "New Folder(%d)", i++); + BLI_strncpy(tmpstr, sfile->params->dir, FILE_MAX); + BLI_join_dirfile(tmpstr, tmpstr, tmpdir); + } + BLI_recurdir_fileops(tmpstr); + if (!BLI_exists(tmpstr)) { + filelist_free(sfile->files); + filelist_parent(sfile->files); + BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX); + } + } + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + + return OPERATOR_FINISHED; +} + + +void FILE_OT_directory_new(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Create New Directory"; + ot->idname= "FILE_OT_directory_new"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= file_directory_new_exec; + ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ +} + +int file_directory_exec(bContext *C, wmOperator *unused) +{ + char tmpstr[FILE_MAX]; + + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + + if(sfile->params) { + + if ( sfile->params->dir[0] == '~' ) { + if (sfile->params->dir[1] == '\0') { + BLI_strncpy(sfile->params->dir, BLI_gethome(), sizeof(sfile->params->dir) ); + } else { + /* replace ~ with home */ + char homestr[FILE_MAX]; + char *d = &sfile->params->dir[1]; + + while ( (*d == '\\') || (*d == '/') ) + d++; + BLI_strncpy(homestr, BLI_gethome(), FILE_MAX); + BLI_add_slash(homestr); + BLI_join_dirfile(tmpstr, homestr, d); + BLI_strncpy(sfile->params->dir, tmpstr, sizeof(sfile->params->dir)); + } + } +#ifdef WIN32 + if (sfile->params->dir[0] == '\0') + get_default_root(sfile->params->dir); +#endif + BLI_cleanup_dir(G.sce, sfile->params->dir); + BLI_add_slash(sfile->params->dir); + file_change_dir(sfile); + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); } - ED_area_tag_redraw(CTX_wm_area(C)); + return OPERATOR_FINISHED; +} + +int file_filename_exec(bContext *C, wmOperator *unused) +{ + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + + if(sfile->params) { + if (file_select_match(sfile, sfile->params->file)) + { + sfile->params->file[0] = '\0'; + WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); + } + } + return OPERATOR_FINISHED; } @@ -594,14 +762,58 @@ void FILE_OT_refresh(struct wmOperatorType *ot) ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ } +int file_hidedot_exec(bContext *C, wmOperator *unused) +{ + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + + if(sfile->params) { + sfile->params->flag ^= FILE_HIDE_DOT; + filelist_free(sfile->files); + sfile->params->active_file = -1; + WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + } + + return OPERATOR_FINISHED; + +} + + +void FILE_OT_hidedot(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Hide Dot Files"; + ot->idname= "FILE_OT_hidedot"; + + /* api callbacks */ + ot->exec= file_hidedot_exec; + ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ +} + struct ARegion *file_buttons_region(struct ScrArea *sa) { - ARegion *ar; + ARegion *ar, *arnew; for(ar= sa->regionbase.first; ar; ar= ar->next) if(ar->regiontype==RGN_TYPE_CHANNELS) return ar; - return NULL; + + /* add subdiv level; after header */ + for(ar= sa->regionbase.first; ar; ar= ar->next) + if(ar->regiontype==RGN_TYPE_HEADER) + break; + + /* is error! */ + if(ar==NULL) return NULL; + + arnew= MEM_callocN(sizeof(ARegion), "buttons for file panels"); + + BLI_insertlinkafter(&sa->regionbase, ar, arnew); + arnew->regiontype= RGN_TYPE_CHANNELS; + arnew->alignment= RGN_ALIGN_LEFT; + + arnew->flag = RGN_FLAG_HIDDEN; + + return arnew; } int file_bookmark_toggle_exec(bContext *C, wmOperator *unused) @@ -629,3 +841,78 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot) ot->exec= file_bookmark_toggle_exec; ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ } + + +int file_filenum_exec(bContext *C, wmOperator *op) +{ + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + + int inc = RNA_int_get(op->ptr, "increment"); + if(sfile->params && (inc != 0)) { + BLI_newname(sfile->params->file, inc); + WM_event_add_notifier(C, NC_WINDOW, NULL); + } + + return OPERATOR_FINISHED; + +} + +void FILE_OT_filenum(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Increment Number in Filename"; + ot->idname= "FILE_OT_filenum"; + + /* api callbacks */ + ot->exec= file_filenum_exec; + ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ + + /* props */ + RNA_def_int(ot->srna, "increment", 1, 0, 100, "Increment", "", 0,100); +} + +int file_delete_poll(bContext *C) +{ + int poll = ED_operator_file_active(C); + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + struct direntry* file; + + if(!sfile->params ) poll= 0; + + if (sfile->params->active_file < 0) { + poll= 0; + } else { + file = filelist_file(sfile->files, sfile->params->active_file); + if (file && S_ISDIR(file->type)) poll= 0; + } + return poll; +} + +int file_delete_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); + struct direntry* file; + + + file = filelist_file(sfile->files, sfile->params->active_file); + BLI_make_file_string(G.sce, str, sfile->params->dir, file->relname); + BLI_delete(str, 0, 0); + WM_event_add_notifier(C, NC_FILE | ND_FILELIST, NULL); + + return OPERATOR_FINISHED; + +} + +void FILE_OT_delete(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete File"; + ot->idname= "FILE_OT_delete"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= file_delete_exec; + ot->poll= file_delete_poll; /* <- important, handler is on window level */ +} + |