/** * $Id: * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The Original Code is Copyright (C) 2008 Blender Foundation. * All rights reserved. * * * Contributor(s): Andrea Weikert (c) 2008 Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" #include "BLI_blenlib.h" #include "BLI_storage_types.h" #ifdef WIN32 #include "BLI_winstuff.h" #endif #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "ED_space_api.h" #include "ED_screen.h" #include "ED_fileselect.h" #include "MEM_guardedalloc.h" #include "RNA_access.h" #include "RNA_define.h" #include "UI_interface.h" #include "UI_view2d.h" #include "WM_api.h" #include "WM_types.h" #include "file_intern.h" #include "filelist.h" #include "fsmenu.h" #include #include #include /* for events */ #define NOTACTIVE 0 #define ACTIVATE 1 #define INACTIVATE 2 /* ---------- FILE SELECTION ------------ */ static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short y, short clamp) { float fx,fy; int active_file = -1; int numfiles = filelist_numfiles(sfile->files); View2D* v2d = &ar->v2d; UI_view2d_region_to_view(v2d, x, y, &fx, &fy); active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy); if(active_file < 0) { if(clamp) active_file= 0; else active_file= -1; } else if(active_file >= numfiles) { if(clamp) active_file= numfiles-1; else active_file= -1; } return active_file; } static void file_deselect_all(SpaceFile* sfile) { int numfiles = filelist_numfiles(sfile->files); int i; for ( i=0; i < numfiles; ++i) { struct direntry* file = filelist_file(sfile->files, i); if (file && (file->flags & ACTIVE)) { file->flags &= ~ACTIVE; } } } static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short val) { int first_file = -1; int last_file = -1; int act_file; short selecting = (val == LEFTMOUSE); FileSelectParams *params = ED_fileselect_get_params(sfile); // FileLayout *layout = ED_fileselect_get_layout(sfile, ar); int numfiles = filelist_numfiles(sfile->files); params->selstate = NOTACTIVE; first_file = find_file_mouse(sfile, ar, rect->xmin, rect->ymax, 1); last_file = find_file_mouse(sfile, ar, rect->xmax, rect->ymin, 1); /* select all valid files between first and last indicated */ if ( (first_file >= 0) && (first_file < numfiles) && (last_file >= 0) && (last_file < numfiles) ) { for (act_file = first_file; act_file <= last_file; act_file++) { struct direntry* file = filelist_file(sfile->files, act_file); if (selecting) file->flags |= ACTIVE; else file->flags &= ~ACTIVE; } } /* make the last file active */ if (selecting && (last_file >= 0 && last_file < numfiles)) { struct direntry* file = filelist_file(sfile->files, last_file); params->active_file = last_file; if(file && S_ISDIR(file->type)) { /* the path is too long! */ if (strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) { // XXX error("Path too long, cannot enter this directory"); } else { 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) { if (file->relname) { BLI_strncpy(params->file, file->relname, FILE_MAXFILE); /* XXX if(event==MIDDLEMOUSE && filelist_gettype(sfile->files)) imasel_execute(sfile); */ } } /* XXX if(BIF_filelist_gettype(sfile->files)==FILE_MAIN) { active_imasel_object(sfile); } */ } } static int file_border_select_exec(bContext *C, wmOperator *op) { ARegion *ar= CTX_wm_region(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); short val; rcti rect; val= RNA_int_get(op->ptr, "event_type"); rect.xmin= RNA_int_get(op->ptr, "xmin"); rect.ymin= RNA_int_get(op->ptr, "ymin"); rect.xmax= RNA_int_get(op->ptr, "xmax"); rect.ymax= RNA_int_get(op->ptr, "ymax"); BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); file_select(sfile, ar, &rect, val ); WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; } void FILE_OT_select_border(wmOperatorType *ot) { /* identifiers */ ot->name= "Activate/Select File"; ot->idname= "FILE_OT_select_border"; /* api callbacks */ ot->invoke= WM_border_select_invoke; ot->exec= file_border_select_exec; ot->modal= WM_border_select_modal; /* rna */ RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); ot->poll= ED_operator_file_active; } static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { ARegion *ar= CTX_wm_region(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); short val; rcti rect; rect.xmin = rect.xmax = event->x - ar->winrct.xmin; rect.ymin = rect.ymax = event->y - ar->winrct.ymin; val = event->val; if (BLI_in_rcti(&ar->v2d.mask, rect.xmin, rect.ymin)) { /* single select, deselect all selected first */ file_deselect_all(sfile); file_select(sfile, ar, &rect, val ); WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); } return OPERATOR_FINISHED; } void FILE_OT_select(wmOperatorType *ot) { /* identifiers */ ot->name= "Activate/Select File"; ot->idname= "FILE_OT_select"; /* api callbacks */ ot->invoke= file_select_invoke; /* rna */ ot->poll= ED_operator_file_active; } static int file_select_all_invoke(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa= CTX_wm_area(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); int numfiles = filelist_numfiles(sfile->files); int i; int select = 1; /* if any file is selected, deselect all first */ for ( i=0; i < numfiles; ++i) { struct direntry* file = filelist_file(sfile->files, i); if (file && (file->flags & ACTIVE)) { file->flags &= ~ACTIVE; select = 0; ED_area_tag_redraw(sa); } } /* select all only if previously no file was selected */ if (select) { for ( i=0; i < numfiles; ++i) { struct direntry* file = filelist_file(sfile->files, i); if(file && !S_ISDIR(file->type)) { file->flags |= ACTIVE; ED_area_tag_redraw(sa); } } } return OPERATOR_FINISHED; } void FILE_OT_select_all_toggle(wmOperatorType *ot) { /* identifiers */ ot->name= "Select/Deselect all files"; ot->idname= "FILE_OT_select_all_toggle"; /* api callbacks */ ot->invoke= file_select_all_invoke; /* rna */ ot->poll= ED_operator_file_active; } /* ---------- BOOKMARKS ----------- */ static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); 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 OPERATOR_FINISHED; } void FILE_OT_select_bookmark(wmOperatorType *ot) { /* identifiers */ ot->name= "Select Directory"; ot->idname= "FILE_OT_select_bookmark"; /* api callbacks */ ot->invoke= bookmark_select_invoke; ot->poll= ED_operator_file_active; RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); } static int bookmark_add_invoke(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa= CTX_wm_area(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); struct FSMenu* fsmenu = 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, 0, 1); BLI_make_file_string("/", name, BLI_gethome(), ".Bfs"); fsmenu_write_file(fsmenu, name); } ED_area_tag_redraw(sa); return OPERATOR_FINISHED; } void FILE_OT_add_bookmark(wmOperatorType *ot) { /* identifiers */ ot->name= "Add Bookmark"; ot->idname= "FILE_OT_add_bookmark"; /* api callbacks */ 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); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); if (sfile->files) { filelist_loadimage_timer(sfile->files); if (filelist_changed(sfile->files)) { ED_area_tag_redraw(sa); } } return OPERATOR_FINISHED; } void FILE_OT_loadimages(wmOperatorType *ot) { /* identifiers */ ot->name= "Load Images"; ot->idname= "FILE_OT_loadimages"; /* api callbacks */ ot->invoke= loadimages_invoke; ot->poll= ED_operator_file_active; } int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my) { FileSelectParams* params; int numfiles, actfile; if(sfile==NULL || sfile->files==NULL) return 0; numfiles = filelist_numfiles(sfile->files); params = ED_fileselect_get_params(sfile); actfile = find_file_mouse(sfile, ar, mx , my, 0); if (params && (actfile >= 0) && (actfile < numfiles) ) { params->active_file=actfile; return 1; } params->active_file= -1; return 0; } static int file_highlight_invoke(bContext *C, wmOperator *op, wmEvent *event) { ARegion *ar= CTX_wm_region(C); SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); if( file_hilight_set(sfile, ar, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) { ED_area_tag_redraw(CTX_wm_area(C)); } return OPERATOR_FINISHED; } void FILE_OT_highlight(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Highlight File"; ot->idname= "FILE_OT_highlight"; /* api callbacks */ ot->invoke= file_highlight_invoke; ot->poll= ED_operator_file_active; } 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; return OPERATOR_FINISHED; } void FILE_OT_cancel(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Cancel File Load"; ot->idname= "FILE_OT_cancel"; /* api callbacks */ ot->exec= file_cancel_exec; ot->poll= ED_operator_file_active; } /* sends events now, so things get handled on windowqueue level */ int file_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); char name[FILE_MAX]; if(sfile->op) { wmOperator *op= sfile->op; sfile->op = NULL; BLI_strncpy(name, sfile->params->dir, sizeof(name)); strcat(name, sfile->params->file); RNA_string_set(op->ptr, "filename", name); /* some ops have multiple files to select */ { PointerRNA itemptr; int i, numfiles = filelist_numfiles(sfile->files); struct direntry *file; if(RNA_struct_find_property(op->ptr, "files")) { for (i=0; ifiles, i); if(file->flags & ACTIVE) { if ((file->type & S_IFDIR)==0) { RNA_collection_add(op->ptr, "files", &itemptr); RNA_string_set(&itemptr, "name", file->relname); } } } } if(RNA_struct_find_property(op->ptr, "dirs")) { for (i=0; ifiles, i); if(file->flags & ACTIVE) { if ((file->type & S_IFDIR)) { RNA_collection_add(op->ptr, "dirs", &itemptr); RNA_string_set(&itemptr, "name", file->relname); } } } } } 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); WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC); } return OPERATOR_FINISHED; } void FILE_OT_exec(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Execute File Window"; ot->idname= "FILE_OT_exec"; /* api callbacks */ ot->exec= file_exec; ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ } int file_parent_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); if(sfile->params) { if (BLI_has_parent(sfile->params->dir)) { BLI_parent_dir(sfile->params->dir); file_change_dir(sfile); WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); } } return OPERATOR_FINISHED; } void FILE_OT_parent(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Parent File"; ot->idname= "FILE_OT_parent"; /* api callbacks */ ot->exec= file_parent_exec; ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ } 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) { 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_add_slash(sfile->params->dir); file_change_dir(sfile); WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); } 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; } void FILE_OT_refresh(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Refresh Filelist"; ot->idname= "FILE_OT_refresh"; /* api callbacks */ ot->exec= file_refresh_exec; 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, *arnew; for(ar= sa->regionbase.first; ar; ar= ar->next) if(ar->regiontype==RGN_TYPE_CHANNELS) return ar; /* 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) { ScrArea *sa= CTX_wm_area(C); ARegion *ar= file_buttons_region(sa); if(ar) { ar->flag ^= RGN_FLAG_HIDDEN; ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); ED_area_tag_redraw(sa); } return OPERATOR_FINISHED; } void FILE_OT_bookmark_toggle(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Bookmarks"; ot->idname= "FILE_OT_bookmark_toggle"; /* api callbacks */ 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 */ }