|
Blender
V2.59
|
00001 /* 00002 * $Id: file_ops.c 39046 2011-08-05 06:06:15Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Andrea Weikert (c) 2008 Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include "BKE_context.h" 00035 #include "BKE_screen.h" 00036 #include "BKE_global.h" 00037 #include "BKE_report.h" 00038 #include "BKE_main.h" 00039 00040 #include "BLI_blenlib.h" 00041 #include "BLI_utildefines.h" 00042 #include "BLI_storage_types.h" 00043 #ifdef WIN32 00044 #include "BLI_winstuff.h" 00045 #endif 00046 00047 #include "ED_screen.h" 00048 #include "ED_fileselect.h" 00049 00050 #include "MEM_guardedalloc.h" 00051 00052 #include "RNA_access.h" 00053 #include "RNA_define.h" 00054 00055 #include "UI_view2d.h" 00056 00057 #include "WM_api.h" 00058 #include "WM_types.h" 00059 00060 #include "file_intern.h" 00061 #include "filelist.h" 00062 #include "fsmenu.h" 00063 00064 #include <stdlib.h> 00065 #include <string.h> 00066 #include <stdio.h> 00067 #include <ctype.h> 00068 00069 /* for events */ 00070 #define NOTACTIVEFILE 0 00071 #define ACTIVATE 1 00072 #define INACTIVATE 2 00073 00074 /* ---------- FILE SELECTION ------------ */ 00075 static FileSelection find_file_mouse_rect(SpaceFile *sfile, struct ARegion* ar, const rcti* rect) 00076 { 00077 FileSelection sel; 00078 float fxmin,fymin,fxmax, fymax; 00079 00080 View2D* v2d = &ar->v2d; 00081 rcti rect_view; 00082 00083 UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin, &fxmin, &fymin); 00084 UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax, &fxmax, &fymax); 00085 00086 BLI_init_rcti(&rect_view, (int)(v2d->tot.xmin + fxmin), (int)(v2d->tot.xmin + fxmax), (int)(v2d->tot.ymax - fymin), (int)(v2d->tot.ymax - fymax)); 00087 00088 sel = ED_fileselect_layout_offset_rect(sfile->layout, &rect_view); 00089 00090 return sel; 00091 } 00092 00093 static void file_deselect_all(SpaceFile* sfile, unsigned int flag) 00094 { 00095 FileSelection sel; 00096 sel.first = 0; 00097 sel.last = filelist_numfiles(sfile->files)-1; 00098 00099 filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL); 00100 } 00101 00102 typedef enum FileSelect { 00103 FILE_SELECT_NOTHING = 0, 00104 FILE_SELECT_DIR = 1, 00105 FILE_SELECT_FILE = 2 00106 } FileSelect; 00107 00108 static void clamp_to_filelist(int numfiles, FileSelection* sel) 00109 { 00110 /* border select before the first file */ 00111 if ( (sel->first < 0) && (sel->last >=0 ) ) { 00112 sel->first = 0; 00113 } 00114 /* don't select if everything is outside filelist */ 00115 if ( (sel->first >= numfiles) && ((sel->last < 0) || (sel->last >= numfiles)) ) { 00116 sel->first = -1; 00117 sel->last = -1; 00118 } 00119 00120 /* fix if last file invalid */ 00121 if ( (sel->first > 0) && (sel->last < 0) ) 00122 sel->last = numfiles-1; 00123 00124 /* clamp */ 00125 if ( (sel->first >= numfiles) ) { 00126 sel->first = numfiles-1; 00127 } 00128 if ( (sel->last >= numfiles) ) { 00129 sel->last = numfiles-1; 00130 } 00131 } 00132 00133 static FileSelection file_selection_get(bContext* C, const rcti* rect, short fill) 00134 { 00135 ARegion *ar= CTX_wm_region(C); 00136 SpaceFile *sfile= CTX_wm_space_file(C); 00137 int numfiles = filelist_numfiles(sfile->files); 00138 FileSelection sel; 00139 00140 sel = find_file_mouse_rect(sfile, ar, rect); 00141 if ( !((sel.first == -1) && (sel.last == -1)) ) { 00142 clamp_to_filelist(numfiles, &sel); 00143 } 00144 00145 00146 /* if desired, fill the selection up from the last selected file to the current one */ 00147 if (fill && (sel.last >= 0) && (sel.last < numfiles) ) { 00148 int f= sel.last; 00149 while (f >= 0) { 00150 if ( filelist_is_selected(sfile->files, f, CHECK_ALL) ) 00151 break; 00152 f--; 00153 } 00154 if (f >= 0) { 00155 sel.first = f+1; 00156 } 00157 } 00158 return sel; 00159 } 00160 00161 static FileSelect file_select_do(bContext* C, int selected_idx) 00162 { 00163 FileSelect retval = FILE_SELECT_NOTHING; 00164 SpaceFile *sfile= CTX_wm_space_file(C); 00165 FileSelectParams *params = ED_fileselect_get_params(sfile); 00166 int numfiles = filelist_numfiles(sfile->files); 00167 00168 /* make the selected file active */ 00169 if ( (selected_idx >= 0) && (selected_idx < numfiles)) { 00170 struct direntry* file = filelist_file(sfile->files, selected_idx); 00171 params->active_file = selected_idx; 00172 00173 if(file && S_ISDIR(file->type)) { 00174 /* the path is too long and we are not going up! */ 00175 if (strcmp(file->relname, "..") && strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) 00176 { 00177 // XXX error("Path too long, cannot enter this directory"); 00178 } else { 00179 if (strcmp(file->relname, "..")==0) { 00180 /* avoids /../../ */ 00181 BLI_parent_dir(params->dir); 00182 } else { 00183 BLI_cleanup_dir(G.main->name, params->dir); 00184 strcat(params->dir, file->relname); 00185 BLI_add_slash(params->dir); 00186 } 00187 00188 file_change_dir(C, 0); 00189 retval = FILE_SELECT_DIR; 00190 } 00191 } 00192 else if (file) 00193 { 00194 if (file->relname) { 00195 BLI_strncpy(params->file, file->relname, FILE_MAXFILE); 00196 } 00197 retval = FILE_SELECT_FILE; 00198 } 00199 } 00200 return retval; 00201 } 00202 00203 00204 static FileSelect file_select(bContext* C, const rcti* rect, FileSelType select, short fill) 00205 { 00206 SpaceFile *sfile= CTX_wm_space_file(C); 00207 FileSelect retval = FILE_SELECT_NOTHING; 00208 FileSelection sel= file_selection_get(C, rect, fill); /* get the selection */ 00209 const FileCheckType check_type= (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL; 00210 00211 /* flag the files as selected in the filelist */ 00212 filelist_select(sfile->files, &sel, select, SELECTED_FILE, check_type); 00213 00214 /* Don't act on multiple selected files */ 00215 if (sel.first != sel.last) select = 0; 00216 00217 /* Do we have a valid selection and are we actually selecting */ 00218 if ( (sel.last >= 0) && ((select == FILE_SEL_ADD) || (select == FILE_SEL_TOGGLE)) ) 00219 { 00220 /* Check last selection, if selected, act on the file or dir */ 00221 if (filelist_is_selected(sfile->files, sel.last, check_type)) { 00222 retval = file_select_do(C, sel.last); 00223 } 00224 } 00225 00226 /* update operator for name change event */ 00227 file_draw_check_cb(C, NULL, NULL); 00228 00229 return retval; 00230 } 00231 00232 static int file_border_select_modal(bContext *C, wmOperator *op, wmEvent *event) 00233 { 00234 ARegion *ar= CTX_wm_region(C); 00235 SpaceFile *sfile= CTX_wm_space_file(C); 00236 FileSelectParams *params = ED_fileselect_get_params(sfile); 00237 FileSelection sel; 00238 rcti rect; 00239 00240 int result; 00241 00242 result= WM_border_select_modal(C, op, event); 00243 00244 if(result==OPERATOR_RUNNING_MODAL) { 00245 00246 rect.xmin= RNA_int_get(op->ptr, "xmin"); 00247 rect.ymin= RNA_int_get(op->ptr, "ymin"); 00248 rect.xmax= RNA_int_get(op->ptr, "xmax"); 00249 rect.ymax= RNA_int_get(op->ptr, "ymax"); 00250 00251 BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); 00252 00253 sel = file_selection_get(C, &rect, 0); 00254 if ( (sel.first != params->sel_first) || (sel.last != params->sel_last) ) { 00255 file_deselect_all(sfile, HILITED_FILE); 00256 filelist_select(sfile->files, &sel, FILE_SEL_ADD, HILITED_FILE, CHECK_ALL); 00257 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 00258 } 00259 params->sel_first = sel.first; params->sel_last = sel.last; 00260 00261 }else { 00262 params->active_file = -1; 00263 params->sel_first = params->sel_last = -1; 00264 file_deselect_all(sfile, HILITED_FILE); 00265 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 00266 } 00267 00268 return result; 00269 } 00270 00271 static int file_border_select_exec(bContext *C, wmOperator *op) 00272 { 00273 ARegion *ar= CTX_wm_region(C); 00274 rcti rect; 00275 FileSelect ret; 00276 00277 short select= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); 00278 rect.xmin= RNA_int_get(op->ptr, "xmin"); 00279 rect.ymin= RNA_int_get(op->ptr, "ymin"); 00280 rect.xmax= RNA_int_get(op->ptr, "xmax"); 00281 rect.ymax= RNA_int_get(op->ptr, "ymax"); 00282 00283 BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); 00284 00285 ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, 0); 00286 if (FILE_SELECT_DIR == ret) { 00287 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00288 } else if (FILE_SELECT_FILE == ret) { 00289 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 00290 } 00291 return OPERATOR_FINISHED; 00292 } 00293 00294 void FILE_OT_select_border(wmOperatorType *ot) 00295 { 00296 /* identifiers */ 00297 ot->name= "Activate/Select File"; 00298 ot->description= "Activate/select the file(s) contained in the border"; 00299 ot->idname= "FILE_OT_select_border"; 00300 00301 /* api callbacks */ 00302 ot->invoke= WM_border_select_invoke; 00303 ot->exec= file_border_select_exec; 00304 ot->modal= file_border_select_modal; 00305 ot->poll= ED_operator_file_active; 00306 ot->cancel= WM_border_select_cancel; 00307 00308 /* rna */ 00309 WM_operator_properties_gesture_border(ot, 0); 00310 } 00311 00312 static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) 00313 { 00314 ARegion *ar= CTX_wm_region(C); 00315 SpaceFile *sfile= CTX_wm_space_file(C); 00316 FileSelect ret; 00317 rcti rect; 00318 int extend = RNA_boolean_get(op->ptr, "extend"); 00319 int fill = RNA_boolean_get(op->ptr, "fill"); 00320 00321 if(ar->regiontype != RGN_TYPE_WINDOW) 00322 return OPERATOR_CANCELLED; 00323 00324 rect.xmin = rect.xmax = event->mval[0]; 00325 rect.ymin = rect.ymax = event->mval[1]; 00326 00327 if(!BLI_in_rcti(&ar->v2d.mask, rect.xmin, rect.ymin)) 00328 return OPERATOR_CANCELLED; 00329 00330 /* single select, deselect all selected first */ 00331 if (!extend) file_deselect_all(sfile, SELECTED_FILE); 00332 00333 ret = file_select(C, &rect, extend ? FILE_SEL_TOGGLE : FILE_SEL_ADD, fill); 00334 if (FILE_SELECT_DIR == ret) 00335 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00336 else if (FILE_SELECT_FILE == ret) 00337 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 00338 00339 WM_event_add_mousemove(C); /* for directory changes */ 00340 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 00341 00342 return OPERATOR_FINISHED; 00343 } 00344 00345 void FILE_OT_select(wmOperatorType *ot) 00346 { 00347 /* identifiers */ 00348 ot->name= "Activate/Select File"; 00349 ot->description= "Activate/select file"; 00350 ot->idname= "FILE_OT_select"; 00351 00352 /* api callbacks */ 00353 ot->invoke= file_select_invoke; 00354 ot->poll= ED_operator_file_active; 00355 00356 /* rna */ 00357 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); 00358 RNA_def_boolean(ot->srna, "fill", 0, "Fill", "Select everything beginning with the last selection."); 00359 } 00360 00361 static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op)) 00362 { 00363 ScrArea *sa= CTX_wm_area(C); 00364 SpaceFile *sfile= CTX_wm_space_file(C); 00365 FileSelection sel; 00366 int numfiles = filelist_numfiles(sfile->files); 00367 int i; 00368 int is_selected = 0; 00369 00370 sel.first = 0; 00371 sel.last = numfiles-1; 00372 00373 /* Is any file selected ? */ 00374 for ( i=0; i < numfiles; ++i) { 00375 if (filelist_is_selected(sfile->files, i, CHECK_ALL)) { 00376 is_selected = 1; 00377 break; 00378 } 00379 } 00380 /* select all only if previously no file was selected */ 00381 if (is_selected) { 00382 filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, SELECTED_FILE, CHECK_ALL); 00383 } 00384 else { 00385 const FileCheckType check_type= (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES; 00386 filelist_select(sfile->files, &sel, FILE_SEL_ADD, SELECTED_FILE, check_type); 00387 } 00388 ED_area_tag_redraw(sa); 00389 return OPERATOR_FINISHED; 00390 } 00391 00392 void FILE_OT_select_all_toggle(wmOperatorType *ot) 00393 { 00394 /* identifiers */ 00395 ot->name= "Select/Deselect All Files"; 00396 ot->description= "Select/deselect all files"; 00397 ot->idname= "FILE_OT_select_all_toggle"; 00398 00399 /* api callbacks */ 00400 ot->exec= file_select_all_exec; 00401 ot->poll= ED_operator_file_active; 00402 00403 /* rna */ 00404 00405 00406 } 00407 00408 /* ---------- BOOKMARKS ----------- */ 00409 00410 static int bookmark_select_exec(bContext *C, wmOperator *op) 00411 { 00412 SpaceFile *sfile= CTX_wm_space_file(C); 00413 00414 if(RNA_struct_find_property(op->ptr, "dir")) { 00415 char entry[256]; 00416 FileSelectParams* params = sfile->params; 00417 00418 RNA_string_get(op->ptr, "dir", entry); 00419 BLI_strncpy(params->dir, entry, sizeof(params->dir)); 00420 BLI_cleanup_dir(G.main->name, params->dir); 00421 file_change_dir(C, 1); 00422 00423 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00424 } 00425 00426 return OPERATOR_FINISHED; 00427 } 00428 00429 void FILE_OT_select_bookmark(wmOperatorType *ot) 00430 { 00431 /* identifiers */ 00432 ot->name= "Select Directory"; 00433 ot->description= "Select a bookmarked directory"; 00434 ot->idname= "FILE_OT_select_bookmark"; 00435 00436 /* api callbacks */ 00437 ot->exec= bookmark_select_exec; 00438 ot->poll= ED_operator_file_active; 00439 00440 RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); 00441 } 00442 00443 static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) 00444 { 00445 ScrArea *sa= CTX_wm_area(C); 00446 SpaceFile *sfile= CTX_wm_space_file(C); 00447 struct FSMenu* fsmenu = fsmenu_get(); 00448 struct FileSelectParams* params= ED_fileselect_get_params(sfile); 00449 00450 if (params->dir[0] != '\0') { 00451 char name[FILE_MAX]; 00452 00453 fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, 0, 1); 00454 BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); 00455 fsmenu_write_file(fsmenu, name); 00456 } 00457 00458 ED_area_tag_redraw(sa); 00459 return OPERATOR_FINISHED; 00460 } 00461 00462 void FILE_OT_bookmark_add(wmOperatorType *ot) 00463 { 00464 /* identifiers */ 00465 ot->name= "Add Bookmark"; 00466 ot->description= "Add a bookmark for the selected/active directory"; 00467 ot->idname= "FILE_OT_bookmark_add"; 00468 00469 /* api callbacks */ 00470 ot->exec= bookmark_add_exec; 00471 ot->poll= ED_operator_file_active; 00472 } 00473 00474 static int bookmark_delete_exec(bContext *C, wmOperator *op) 00475 { 00476 ScrArea *sa= CTX_wm_area(C); 00477 struct FSMenu* fsmenu = fsmenu_get(); 00478 int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); 00479 00480 if(RNA_struct_find_property(op->ptr, "index")) { 00481 int index = RNA_int_get(op->ptr, "index"); 00482 if ( (index >-1) && (index < nentries)) { 00483 char name[FILE_MAX]; 00484 00485 fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); 00486 BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); 00487 fsmenu_write_file(fsmenu, name); 00488 ED_area_tag_redraw(sa); 00489 } 00490 } 00491 00492 return OPERATOR_FINISHED; 00493 } 00494 00495 void FILE_OT_delete_bookmark(wmOperatorType *ot) 00496 { 00497 /* identifiers */ 00498 ot->name= "Delete Bookmark"; 00499 ot->description= "Delete selected bookmark"; 00500 ot->idname= "FILE_OT_delete_bookmark"; 00501 00502 /* api callbacks */ 00503 ot->exec= bookmark_delete_exec; 00504 ot->poll= ED_operator_file_active; 00505 00506 RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); 00507 } 00508 00509 int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my) 00510 { 00511 View2D* v2d = &ar->v2d; 00512 FileSelectParams* params; 00513 int numfiles, origfile; 00514 00515 if(sfile==NULL || sfile->files==NULL) return 0; 00516 00517 numfiles = filelist_numfiles(sfile->files); 00518 params = ED_fileselect_get_params(sfile); 00519 00520 origfile= params->active_file; 00521 00522 mx -= ar->winrct.xmin; 00523 my -= ar->winrct.ymin; 00524 00525 if(BLI_in_rcti(&ar->v2d.mask, mx, my)) { 00526 float fx, fy; 00527 int active_file; 00528 00529 UI_view2d_region_to_view(v2d, mx, my, &fx, &fy); 00530 00531 active_file = ED_fileselect_layout_offset(sfile->layout, (int)(v2d->tot.xmin + fx), (int)(v2d->tot.ymax - fy)); 00532 00533 if((active_file >= 0) && (active_file < numfiles)) 00534 params->active_file=active_file; 00535 else 00536 params->active_file= -1; 00537 } 00538 else 00539 params->active_file= -1; 00540 00541 return (params->active_file != origfile); 00542 } 00543 00544 static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) 00545 { 00546 ARegion *ar= CTX_wm_region(C); 00547 SpaceFile *sfile= CTX_wm_space_file(C); 00548 00549 if(!file_hilight_set(sfile, ar, event->x, event->y)) 00550 return OPERATOR_CANCELLED; 00551 00552 ED_area_tag_redraw(CTX_wm_area(C)); 00553 00554 return OPERATOR_FINISHED; 00555 } 00556 00557 void FILE_OT_highlight(struct wmOperatorType *ot) 00558 { 00559 /* identifiers */ 00560 ot->name= "Highlight File"; 00561 ot->description= "Highlight selected file(s)"; 00562 ot->idname= "FILE_OT_highlight"; 00563 00564 /* api callbacks */ 00565 ot->invoke= file_highlight_invoke; 00566 ot->poll= ED_operator_file_active; 00567 } 00568 00569 int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused)) 00570 { 00571 SpaceFile *sfile= CTX_wm_space_file(C); 00572 wmOperator *op = sfile->op; 00573 00574 sfile->op = NULL; 00575 00576 WM_event_fileselect_event(C, op, EVT_FILESELECT_CANCEL); 00577 00578 return OPERATOR_FINISHED; 00579 } 00580 00581 static int file_operator_poll(bContext *C) 00582 { 00583 int poll = ED_operator_file_active(C); 00584 SpaceFile *sfile= CTX_wm_space_file(C); 00585 00586 if (!sfile || !sfile->op) poll= 0; 00587 00588 return poll; 00589 } 00590 00591 void FILE_OT_cancel(struct wmOperatorType *ot) 00592 { 00593 /* identifiers */ 00594 ot->name= "Cancel File Load"; 00595 ot->description= "Cancel loading of selected file"; 00596 ot->idname= "FILE_OT_cancel"; 00597 00598 /* api callbacks */ 00599 ot->exec= file_cancel_exec; 00600 ot->poll= file_operator_poll; 00601 } 00602 00603 00604 void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath) 00605 { 00606 BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); /* XXX, not real length */ 00607 if(RNA_struct_find_property(op->ptr, "relative_path")) { 00608 if(RNA_boolean_get(op->ptr, "relative_path")) { 00609 BLI_path_rel(filepath, G.main->name); 00610 } 00611 } 00612 00613 if(RNA_struct_find_property(op->ptr, "filename")) { 00614 RNA_string_set(op->ptr, "filename", sfile->params->file); 00615 } 00616 if(RNA_struct_find_property(op->ptr, "directory")) { 00617 RNA_string_set(op->ptr, "directory", sfile->params->dir); 00618 } 00619 if(RNA_struct_find_property(op->ptr, "filepath")) { 00620 RNA_string_set(op->ptr, "filepath", filepath); 00621 } 00622 00623 /* some ops have multiple files to select */ 00624 { 00625 PointerRNA itemptr; 00626 int i, numfiles = filelist_numfiles(sfile->files); 00627 00628 if(RNA_struct_find_property(op->ptr, "files")) { 00629 for (i=0; i<numfiles; i++) { 00630 if (filelist_is_selected(sfile->files, i, CHECK_FILES)) { 00631 struct direntry *file= filelist_file(sfile->files, i); 00632 RNA_collection_add(op->ptr, "files", &itemptr); 00633 RNA_string_set(&itemptr, "name", file->relname); 00634 } 00635 } 00636 } 00637 00638 if(RNA_struct_find_property(op->ptr, "dirs")) { 00639 for (i=0; i<numfiles; i++) { 00640 if (filelist_is_selected(sfile->files, i, CHECK_DIRS)) { 00641 struct direntry *file= filelist_file(sfile->files, i); 00642 RNA_collection_add(op->ptr, "dirs", &itemptr); 00643 RNA_string_set(&itemptr, "name", file->relname); 00644 } 00645 } 00646 } 00647 00648 00649 } 00650 } 00651 00652 void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op) 00653 { 00654 int change= FALSE; 00655 if(RNA_struct_find_property(op->ptr, "filename")) { 00656 RNA_string_get(op->ptr, "filename", sfile->params->file); 00657 change= TRUE; 00658 } 00659 if(RNA_struct_find_property(op->ptr, "directory")) { 00660 RNA_string_get(op->ptr, "directory", sfile->params->dir); 00661 change= TRUE; 00662 } 00663 00664 /* If neither of the above are set, split the filepath back */ 00665 if(RNA_struct_find_property(op->ptr, "filepath")) { 00666 if(change==FALSE) { 00667 char filepath[FILE_MAX]; 00668 RNA_string_get(op->ptr, "filepath", filepath); 00669 BLI_split_dirfile(filepath, sfile->params->dir, sfile->params->file); 00670 } 00671 } 00672 00673 /* XXX, files and dirs updates missing, not really so important though */ 00674 } 00675 00676 void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)) 00677 { 00678 SpaceFile *sfile= CTX_wm_space_file(C); 00679 wmOperator *op= sfile->op; 00680 if(op) { /* fail on reload */ 00681 if(op->type->check) { 00682 char filepath[FILE_MAX]; 00683 file_sfile_to_operator(op, sfile, filepath); 00684 00685 /* redraw */ 00686 if(op->type->check(C, op)) { 00687 file_operator_to_sfile(sfile, op); 00688 00689 /* redraw, else the changed settings wont get updated */ 00690 ED_area_tag_redraw(CTX_wm_area(C)); 00691 } 00692 } 00693 } 00694 } 00695 00696 int file_draw_check_exists(SpaceFile *sfile) 00697 { 00698 if(sfile->op) { /* fails on reload */ 00699 if(RNA_struct_find_property(sfile->op->ptr, "check_existing")) { 00700 if(RNA_boolean_get(sfile->op->ptr, "check_existing")) { 00701 char filepath[FILE_MAX]; 00702 BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file); 00703 if(BLI_exists(filepath) && !BLI_is_dir(filepath)) { 00704 return TRUE; 00705 } 00706 } 00707 } 00708 } 00709 00710 return FALSE; 00711 } 00712 00713 /* sends events now, so things get handled on windowqueue level */ 00714 int file_exec(bContext *C, wmOperator *exec_op) 00715 { 00716 SpaceFile *sfile= CTX_wm_space_file(C); 00717 char filepath[FILE_MAX]; 00718 00719 if(sfile->op) { 00720 wmOperator *op= sfile->op; 00721 00722 /* when used as a macro, for doubleclick, 00723 to prevent closing when doubleclicking on .. item */ 00724 if (RNA_boolean_get(exec_op->ptr, "need_active")) { 00725 int i, active=0; 00726 00727 for (i=0; i<filelist_numfiles(sfile->files); i++) { 00728 if(filelist_is_selected(sfile->files, i, CHECK_ALL)) { 00729 active=1; 00730 break; 00731 } 00732 } 00733 if (active == 0) 00734 return OPERATOR_CANCELLED; 00735 } 00736 00737 sfile->op = NULL; 00738 00739 file_sfile_to_operator(op, sfile, filepath); 00740 00741 fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir,0, 1); 00742 BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); 00743 fsmenu_write_file(fsmenu_get(), filepath); 00744 WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC); 00745 00746 } 00747 00748 return OPERATOR_FINISHED; 00749 } 00750 00751 void FILE_OT_execute(struct wmOperatorType *ot) 00752 { 00753 /* identifiers */ 00754 ot->name= "Execute File Window"; 00755 ot->description= "Execute selected file"; 00756 ot->idname= "FILE_OT_execute"; 00757 00758 /* api callbacks */ 00759 ot->exec= file_exec; 00760 ot->poll= file_operator_poll; 00761 00762 RNA_def_boolean(ot->srna, "need_active", 0, "Need Active", "Only execute if there's an active selected file in the file list."); 00763 } 00764 00765 00766 int file_parent_exec(bContext *C, wmOperator *UNUSED(unused)) 00767 { 00768 SpaceFile *sfile= CTX_wm_space_file(C); 00769 00770 if(sfile->params) { 00771 if (BLI_has_parent(sfile->params->dir)) { 00772 BLI_parent_dir(sfile->params->dir); 00773 BLI_cleanup_dir(G.main->name, sfile->params->dir); 00774 file_change_dir(C, 0); 00775 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00776 } 00777 } 00778 00779 return OPERATOR_FINISHED; 00780 00781 } 00782 00783 00784 void FILE_OT_parent(struct wmOperatorType *ot) 00785 { 00786 /* identifiers */ 00787 ot->name= "Parent File"; 00788 ot->description= "Move to parent directory"; 00789 ot->idname= "FILE_OT_parent"; 00790 00791 /* api callbacks */ 00792 ot->exec= file_parent_exec; 00793 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 00794 } 00795 00796 00797 static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused)) 00798 { 00799 SpaceFile *sfile= CTX_wm_space_file(C); 00800 00801 ED_fileselect_clear(C, sfile); 00802 00803 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00804 00805 return OPERATOR_FINISHED; 00806 00807 } 00808 00809 void FILE_OT_previous(struct wmOperatorType *ot) 00810 { 00811 /* identifiers */ 00812 ot->name= "Previous Folder"; 00813 ot->description= "Move to previous folder"; 00814 ot->idname= "FILE_OT_previous"; 00815 00816 /* api callbacks */ 00817 ot->exec= file_previous_exec; 00818 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 00819 } 00820 00821 int file_previous_exec(bContext *C, wmOperator *UNUSED(unused)) 00822 { 00823 SpaceFile *sfile= CTX_wm_space_file(C); 00824 00825 if(sfile->params) { 00826 if (!sfile->folders_next) 00827 sfile->folders_next = folderlist_new(); 00828 00829 folderlist_pushdir(sfile->folders_next, sfile->params->dir); 00830 folderlist_popdir(sfile->folders_prev, sfile->params->dir); 00831 folderlist_pushdir(sfile->folders_next, sfile->params->dir); 00832 00833 file_change_dir(C, 1); 00834 } 00835 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00836 00837 return OPERATOR_FINISHED; 00838 } 00839 00840 void FILE_OT_next(struct wmOperatorType *ot) 00841 { 00842 /* identifiers */ 00843 ot->name= "Next Folder"; 00844 ot->description= "Move to next folder"; 00845 ot->idname= "FILE_OT_next"; 00846 00847 /* api callbacks */ 00848 ot->exec= file_next_exec; 00849 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 00850 } 00851 00852 int file_next_exec(bContext *C, wmOperator *UNUSED(unused)) 00853 { 00854 SpaceFile *sfile= CTX_wm_space_file(C); 00855 if(sfile->params) { 00856 if (!sfile->folders_next) 00857 sfile->folders_next = folderlist_new(); 00858 00859 folderlist_pushdir(sfile->folders_prev, sfile->params->dir); 00860 folderlist_popdir(sfile->folders_next, sfile->params->dir); 00861 00862 // update folders_prev so we can check for it in folderlist_clear_next() 00863 folderlist_pushdir(sfile->folders_prev, sfile->params->dir); 00864 00865 file_change_dir(C, 1); 00866 } 00867 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 00868 00869 return OPERATOR_FINISHED; 00870 } 00871 00872 00873 /* only meant for timer usage */ 00874 static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) 00875 { 00876 ScrArea *sa = CTX_wm_area(C); 00877 SpaceFile *sfile= CTX_wm_space_file(C); 00878 ARegion *ar, *oldar= CTX_wm_region(C); 00879 int offset; 00880 int numfiles, numfiles_layout; 00881 int edit_idx = 0; 00882 int i; 00883 00884 /* escape if not our timer */ 00885 if(sfile->smoothscroll_timer==NULL || sfile->smoothscroll_timer!=event->customdata) 00886 return OPERATOR_PASS_THROUGH; 00887 00888 numfiles = filelist_numfiles(sfile->files); 00889 00890 /* check if we are editing a name */ 00891 for (i=0; i < numfiles; ++i) 00892 { 00893 if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) { 00894 edit_idx=i; 00895 break; 00896 } 00897 } 00898 00899 /* if we are not editing, we are done */ 00900 if (0==edit_idx) { 00901 WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); 00902 sfile->smoothscroll_timer=NULL; 00903 return OPERATOR_PASS_THROUGH; 00904 } 00905 00906 /* we need the correct area for scrolling */ 00907 ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00908 if (!ar || ar->regiontype != RGN_TYPE_WINDOW) { 00909 WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); 00910 sfile->smoothscroll_timer=NULL; 00911 return OPERATOR_PASS_THROUGH; 00912 } 00913 00914 offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); 00915 if (offset<0) offset=0; 00916 00917 /* scroll offset is the first file in the row/column we are editing in */ 00918 if (sfile->scroll_offset == 0) { 00919 if (sfile->layout->flag & FILE_LAYOUT_HOR) { 00920 sfile->scroll_offset = (edit_idx/sfile->layout->rows)*sfile->layout->rows; 00921 if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows; 00922 } else { 00923 sfile->scroll_offset = (edit_idx/sfile->layout->columns)*sfile->layout->columns; 00924 if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns; 00925 } 00926 } 00927 00928 numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); 00929 00930 /* check if we have reached our final scroll position */ 00931 if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { 00932 WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); 00933 sfile->smoothscroll_timer=NULL; 00934 return OPERATOR_FINISHED; 00935 } 00936 00937 /* temporarily set context to the main window region, 00938 * so the scroll operators work */ 00939 CTX_wm_region_set(C, ar); 00940 00941 /* scroll one step in the desired direction */ 00942 if (sfile->scroll_offset < offset) { 00943 if (sfile->layout->flag & FILE_LAYOUT_HOR) { 00944 WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL); 00945 } else { 00946 WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL); 00947 } 00948 00949 } else { 00950 if (sfile->layout->flag & FILE_LAYOUT_HOR) { 00951 WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL); 00952 } else { 00953 WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL); 00954 } 00955 } 00956 00957 ED_region_tag_redraw(CTX_wm_region(C)); 00958 00959 /* and restore context */ 00960 CTX_wm_region_set(C, oldar); 00961 00962 return OPERATOR_FINISHED; 00963 } 00964 00965 00966 void FILE_OT_smoothscroll(wmOperatorType *ot) 00967 { 00968 00969 /* identifiers */ 00970 ot->name= "Smooth Scroll"; 00971 ot->idname= "FILE_OT_smoothscroll"; 00972 ot->description="Smooth scroll to make editable file visible."; 00973 00974 /* api callbacks */ 00975 ot->invoke= file_smoothscroll_invoke; 00976 00977 ot->poll= ED_operator_file_active; 00978 } 00979 00980 00981 /* create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created. 00982 The actual name is returned in 'name', 'folder' contains the complete path, including the new folder name. 00983 */ 00984 static int new_folder_path(const char* parent, char *folder, char *name) 00985 { 00986 int i = 1; 00987 int len = 0; 00988 00989 BLI_strncpy(name, "New Folder", FILE_MAXFILE); 00990 BLI_join_dirfile(folder, FILE_MAX, parent, name); /* XXX, not real length */ 00991 /* check whether folder with the name already exists, in this case 00992 add number to the name. Check length of generated name to avoid 00993 crazy case of huge number of folders each named 'New Folder (x)' */ 00994 while (BLI_exists(folder) && (len<FILE_MAXFILE)) { 00995 len = BLI_snprintf(name, FILE_MAXFILE, "New Folder(%d)", i); 00996 BLI_join_dirfile(folder, FILE_MAX, parent, name); /* XXX, not real length */ 00997 i++; 00998 } 00999 01000 return (len<FILE_MAXFILE); 01001 } 01002 01003 int file_directory_new_exec(bContext *C, wmOperator *op) 01004 { 01005 char name[FILE_MAXFILE]; 01006 char path[FILE_MAX]; 01007 int generate_name= 1; 01008 01009 SpaceFile *sfile= CTX_wm_space_file(C); 01010 01011 if(!sfile->params) { 01012 BKE_report(op->reports,RPT_WARNING, "No parent directory given."); 01013 return OPERATOR_CANCELLED; 01014 } 01015 01016 path[0] = '\0'; 01017 01018 if(RNA_struct_find_property(op->ptr, "directory")) { 01019 RNA_string_get(op->ptr, "directory", path); 01020 if (path[0] != '\0') generate_name= 0; 01021 } 01022 01023 if (generate_name) { 01024 /* create a new, non-existing folder name */ 01025 if (!new_folder_path(sfile->params->dir, path, name)) { 01026 BKE_report(op->reports,RPT_ERROR, "Couldn't create new folder name."); 01027 return OPERATOR_CANCELLED; 01028 } 01029 } 01030 01031 /* create the file */ 01032 BLI_recurdir_fileops(path); 01033 01034 if (!BLI_exists(path)) { 01035 BKE_report(op->reports,RPT_ERROR, "Couldn't create new folder."); 01036 return OPERATOR_CANCELLED; 01037 } 01038 01039 /* now remember file to jump into editing */ 01040 BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); 01041 01042 /* set timer to smoothly view newly generated file */ 01043 sfile->smoothscroll_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/1000.0); /* max 30 frs/sec */ 01044 sfile->scroll_offset=0; 01045 01046 /* reload dir to make sure we're seeing what's in the directory */ 01047 ED_fileselect_clear(C, sfile); 01048 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 01049 01050 return OPERATOR_FINISHED; 01051 } 01052 01053 01054 void FILE_OT_directory_new(struct wmOperatorType *ot) 01055 { 01056 /* identifiers */ 01057 ot->name= "Create New Directory"; 01058 ot->description= "Create a new directory"; 01059 ot->idname= "FILE_OT_directory_new"; 01060 01061 /* api callbacks */ 01062 ot->invoke= WM_operator_confirm; 01063 ot->exec= file_directory_new_exec; 01064 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01065 01066 RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); 01067 01068 } 01069 01070 01071 static void file_expand_directory(bContext *C) 01072 { 01073 SpaceFile *sfile= CTX_wm_space_file(C); 01074 01075 if(sfile->params) { 01076 if ( sfile->params->dir[0] == '~' ) { 01077 char tmpstr[sizeof(sfile->params->dir)-1]; 01078 BLI_strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr)); 01079 BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr); 01080 } 01081 01082 #ifdef WIN32 01083 if (sfile->params->dir[0] == '\0') { 01084 get_default_root(sfile->params->dir); 01085 } 01086 /* change "C:" --> "C:\", [#28102] */ 01087 else if ( (isalpha(sfile->params->dir[0]) && 01088 (sfile->params->dir[1] == ':')) && 01089 (sfile->params->dir[2] == '\0') 01090 01091 ) { 01092 sfile->params->dir[2]= '\\'; 01093 sfile->params->dir[3]= '\0'; 01094 } 01095 #endif 01096 } 01097 } 01098 01099 static int file_directory_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01100 { 01101 SpaceFile *sfile= CTX_wm_space_file(C); 01102 01103 if(sfile->params) { 01104 file_expand_directory(C); 01105 01106 if (!BLI_exists(sfile->params->dir)) { 01107 return WM_operator_confirm_message(C, op, "Create new directory?"); 01108 } 01109 01110 return file_directory_exec(C, op); 01111 } 01112 01113 return OPERATOR_CANCELLED; 01114 } 01115 01116 01117 01118 int file_directory_exec(bContext *C, wmOperator *UNUSED(unused)) 01119 { 01120 SpaceFile *sfile= CTX_wm_space_file(C); 01121 01122 if(sfile->params) { 01123 file_expand_directory(C); 01124 01125 if (!BLI_exists(sfile->params->dir)) { 01126 BLI_recurdir_fileops(sfile->params->dir); 01127 } 01128 01129 /* special case, user may have pasted a fulepath into the directory */ 01130 if(BLI_exists(sfile->params->dir) && BLI_is_dir(sfile->params->dir) == 0) { 01131 char path[sizeof(sfile->params->dir)]; 01132 BLI_strncpy(path, sfile->params->dir, sizeof(path)); 01133 BLI_split_dirfile(path, sfile->params->dir, sfile->params->file); 01134 } 01135 01136 BLI_cleanup_dir(G.main->name, sfile->params->dir); 01137 BLI_add_slash(sfile->params->dir); 01138 file_change_dir(C, 1); 01139 01140 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 01141 } 01142 01143 01144 return OPERATOR_FINISHED; 01145 } 01146 01147 int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) 01148 { 01149 SpaceFile *sfile= CTX_wm_space_file(C); 01150 01151 if(sfile->params) { 01152 if (file_select_match(sfile, sfile->params->file)) 01153 { 01154 sfile->params->file[0] = '\0'; 01155 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); 01156 } 01157 } 01158 01159 return OPERATOR_FINISHED; 01160 } 01161 01162 void FILE_OT_directory(struct wmOperatorType *ot) 01163 { 01164 /* identifiers */ 01165 ot->name= "Enter Directory Name"; 01166 ot->description= "Enter a directory name"; 01167 ot->idname= "FILE_OT_directory"; 01168 01169 /* api callbacks */ 01170 ot->invoke= file_directory_invoke; 01171 ot->exec= file_directory_exec; 01172 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01173 } 01174 01175 void FILE_OT_refresh(struct wmOperatorType *ot) 01176 { 01177 /* identifiers */ 01178 ot->name= "Refresh Filelist"; 01179 ot->description= "Refresh the file list"; 01180 ot->idname= "FILE_OT_refresh"; 01181 01182 /* api callbacks */ 01183 ot->exec= file_refresh_exec; 01184 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01185 } 01186 01187 static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused)) 01188 { 01189 SpaceFile *sfile= CTX_wm_space_file(C); 01190 01191 if(sfile->params) { 01192 sfile->params->flag ^= FILE_HIDE_DOT; 01193 ED_fileselect_clear(C, sfile); 01194 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 01195 } 01196 01197 return OPERATOR_FINISHED; 01198 } 01199 01200 01201 void FILE_OT_hidedot(struct wmOperatorType *ot) 01202 { 01203 /* identifiers */ 01204 ot->name= "Toggle Hide Dot Files"; 01205 ot->description= "Toggle hide hidden dot files"; 01206 ot->idname= "FILE_OT_hidedot"; 01207 01208 /* api callbacks */ 01209 ot->exec= file_hidedot_exec; 01210 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01211 } 01212 01213 struct ARegion *file_buttons_region(struct ScrArea *sa) 01214 { 01215 ARegion *ar, *arnew; 01216 01217 for(ar= sa->regionbase.first; ar; ar= ar->next) 01218 if(ar->regiontype==RGN_TYPE_CHANNELS) 01219 return ar; 01220 01221 /* add subdiv level; after header */ 01222 for(ar= sa->regionbase.first; ar; ar= ar->next) 01223 if(ar->regiontype==RGN_TYPE_HEADER) 01224 break; 01225 01226 /* is error! */ 01227 if(ar==NULL) return NULL; 01228 01229 arnew= MEM_callocN(sizeof(ARegion), "buttons for file panels"); 01230 01231 BLI_insertlinkafter(&sa->regionbase, ar, arnew); 01232 arnew->regiontype= RGN_TYPE_CHANNELS; 01233 arnew->alignment= RGN_ALIGN_LEFT; 01234 01235 arnew->flag = RGN_FLAG_HIDDEN; 01236 01237 return arnew; 01238 } 01239 01240 static int file_bookmark_toggle_exec(bContext *C, wmOperator *UNUSED(unused)) 01241 { 01242 ScrArea *sa= CTX_wm_area(C); 01243 ARegion *ar= file_buttons_region(sa); 01244 01245 if(ar) 01246 ED_region_toggle_hidden(C, ar); 01247 01248 return OPERATOR_FINISHED; 01249 } 01250 01251 void FILE_OT_bookmark_toggle(struct wmOperatorType *ot) 01252 { 01253 /* identifiers */ 01254 ot->name= "Toggle Bookmarks"; 01255 ot->description= "Toggle bookmarks display"; 01256 ot->idname= "FILE_OT_bookmark_toggle"; 01257 01258 /* api callbacks */ 01259 ot->exec= file_bookmark_toggle_exec; 01260 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01261 } 01262 01263 01264 static int file_filenum_exec(bContext *C, wmOperator *op) 01265 { 01266 SpaceFile *sfile= CTX_wm_space_file(C); 01267 ScrArea *sa= CTX_wm_area(C); 01268 01269 int inc = RNA_int_get(op->ptr, "increment"); 01270 if(sfile->params && (inc != 0)) { 01271 BLI_newname(sfile->params->file, inc); 01272 ED_area_tag_redraw(sa); 01273 file_draw_check_cb(C, NULL, NULL); 01274 // WM_event_add_notifier(C, NC_WINDOW, NULL); 01275 } 01276 01277 return OPERATOR_FINISHED; 01278 01279 } 01280 01281 void FILE_OT_filenum(struct wmOperatorType *ot) 01282 { 01283 /* identifiers */ 01284 ot->name= "Increment Number in Filename"; 01285 ot->description= "Increment number in filename"; 01286 ot->idname= "FILE_OT_filenum"; 01287 01288 /* api callbacks */ 01289 ot->exec= file_filenum_exec; 01290 ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ 01291 01292 /* props */ 01293 RNA_def_int(ot->srna, "increment", 1, -100, 100, "Increment", "", -100,100); 01294 } 01295 01296 static int file_rename_exec(bContext *C, wmOperator *UNUSED(op)) 01297 { 01298 ScrArea *sa= CTX_wm_area(C); 01299 SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); 01300 01301 if(sfile->params) { 01302 int idx = sfile->params->active_file; 01303 int numfiles = filelist_numfiles(sfile->files); 01304 if ( (0<=idx) && (idx<numfiles) ) { 01305 struct direntry *file= filelist_file(sfile->files, idx); 01306 filelist_select_file(sfile->files, idx, FILE_SEL_ADD, EDITING_FILE, CHECK_ALL); 01307 BLI_strncpy(sfile->params->renameedit, file->relname, FILE_MAXFILE); 01308 sfile->params->renamefile[0]= '\0'; 01309 } 01310 ED_area_tag_redraw(sa); 01311 } 01312 01313 return OPERATOR_FINISHED; 01314 01315 } 01316 01317 static int file_rename_poll(bContext *C) 01318 { 01319 int poll = ED_operator_file_active(C); 01320 SpaceFile *sfile= CTX_wm_space_file(C); 01321 01322 if (sfile && sfile->params) { 01323 if (sfile->params->active_file < 0) { 01324 poll= 0; 01325 } else { 01326 char dir[FILE_MAX], group[FILE_MAX]; 01327 if (filelist_islibrary(sfile->files, dir, group)) poll= 0; 01328 } 01329 } 01330 else 01331 poll= 0; 01332 return poll; 01333 } 01334 01335 void FILE_OT_rename(struct wmOperatorType *ot) 01336 { 01337 /* identifiers */ 01338 ot->name= "Rename File or Directory"; 01339 ot->description= "Rename file or file directory"; 01340 ot->idname= "FILE_OT_rename"; 01341 01342 /* api callbacks */ 01343 ot->exec= file_rename_exec; 01344 ot->poll= file_rename_poll; 01345 01346 } 01347 01348 static int file_delete_poll(bContext *C) 01349 { 01350 int poll = ED_operator_file_active(C); 01351 SpaceFile *sfile= CTX_wm_space_file(C); 01352 struct direntry* file; 01353 01354 if (sfile && sfile->params) { 01355 if (sfile->params->active_file < 0) { 01356 poll= 0; 01357 } else { 01358 char dir[FILE_MAX], group[FILE_MAX]; 01359 if (filelist_islibrary(sfile->files, dir, group)) poll= 0; 01360 file = filelist_file(sfile->files, sfile->params->active_file); 01361 if (file && S_ISDIR(file->type)) poll= 0; 01362 } 01363 } 01364 else 01365 poll= 0; 01366 01367 return poll; 01368 } 01369 01370 int file_delete_exec(bContext *C, wmOperator *UNUSED(op)) 01371 { 01372 char str[FILE_MAX]; 01373 SpaceFile *sfile= CTX_wm_space_file(C); 01374 struct direntry* file; 01375 01376 01377 file = filelist_file(sfile->files, sfile->params->active_file); 01378 BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relname); 01379 BLI_delete(str, 0, 0); 01380 ED_fileselect_clear(C, sfile); 01381 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); 01382 01383 return OPERATOR_FINISHED; 01384 01385 } 01386 01387 void FILE_OT_delete(struct wmOperatorType *ot) 01388 { 01389 /* identifiers */ 01390 ot->name= "Delete File"; 01391 ot->description= "Delete selected file"; 01392 ot->idname= "FILE_OT_delete"; 01393 01394 /* api callbacks */ 01395 ot->invoke= WM_operator_confirm; 01396 ot->exec= file_delete_exec; 01397 ot->poll= file_delete_poll; /* <- important, handler is on window level */ 01398 } 01399 01400 01401 void ED_operatormacros_file(void) 01402 { 01403 // wmOperatorType *ot; 01404 // wmOperatorTypeMacro *otmacro; 01405 01406 /* future macros */ 01407 }