svn merge -r 30566:30717 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / editors / space_file / file_ops.c
index ed098d2d44e954d282e9e5b174898b63dc75aefd..2a50b505c57c8e7f6b840ca8a95a10550876e266 100644 (file)
@@ -333,7 +333,7 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
 void FILE_OT_select_all_toggle(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select/Deselect all files";
+       ot->name= "Select/Deselect All Files";
        ot->description= "Select/deselect all files";
        ot->idname= "FILE_OT_select_all_toggle";
        
@@ -391,7 +391,7 @@ static int bookmark_add_exec(bContext *C, wmOperator *op)
                char name[FILE_MAX];
        
                fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, 0, 1);
-               BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+               BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
                fsmenu_write_file(fsmenu, name);
        }
 
@@ -423,7 +423,7 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op)
                        char name[FILE_MAX];
                        
                        fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
-                       BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+                       BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
                        fsmenu_write_file(fsmenu, name);
                        ED_area_tag_redraw(sa);
                }
@@ -545,7 +545,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
 int file_exec(bContext *C, wmOperator *exec_op)
 {
        SpaceFile *sfile= CTX_wm_space_file(C);
-       char name[FILE_MAX];
+       char filepath[FILE_MAX];
        
        if(sfile->op) {
                wmOperator *op= sfile->op;
@@ -567,16 +567,23 @@ int file_exec(bContext *C, wmOperator *exec_op)
                }
                
                sfile->op = NULL;
-               RNA_string_set(op->ptr, "filename", sfile->params->file);
-               BLI_strncpy(name, sfile->params->dir, sizeof(name));
-               RNA_string_set(op->ptr, "directory", name);
-               strcat(name, sfile->params->file); // XXX unsafe
 
-               if(RNA_struct_find_property(op->ptr, "relative_path"))
-                       if(RNA_boolean_get(op->ptr, "relative_path"))
-                               BLI_path_rel(name, G.sce);
+               BLI_join_dirfile(filepath, sfile->params->dir, sfile->params->file);
+               if(RNA_struct_find_property(op->ptr, "relative_path")) {
+                       if(RNA_boolean_get(op->ptr, "relative_path")) {
+                               BLI_path_rel(filepath, G.sce);
+                       }
+               }
 
-               RNA_string_set(op->ptr, "path", name);
+               if(RNA_struct_find_property(op->ptr, "filename")) {
+                       RNA_string_set(op->ptr, "filename", sfile->params->file);
+               }
+               if(RNA_struct_find_property(op->ptr, "directory")) {
+                       RNA_string_set(op->ptr, "directory", sfile->params->dir);
+               }
+               if(RNA_struct_find_property(op->ptr, "filepath")) {
+                       RNA_string_set(op->ptr, "filepath", filepath);
+               }
                
                /* some ops have multiple files to select */
                {
@@ -612,8 +619,8 @@ int file_exec(bContext *C, wmOperator *exec_op)
                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);
+               BLI_make_file_string(G.sce, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+               fsmenu_write_file(fsmenu_get(), filepath);
                WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC);
 
                ED_fileselect_clear(C, sfile);
@@ -745,6 +752,116 @@ int file_next_exec(bContext *C, wmOperator *unused)
        return OPERATOR_FINISHED;
 }
 
+
+/* only meant for timer usage */
+static int file_smoothscroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ScrArea *sa = CTX_wm_area(C);
+       SpaceFile *sfile= CTX_wm_space_file(C);
+       ARegion *ar, *oldar= CTX_wm_region(C);
+       int numfiles, offset;
+       int edit_idx = 0;
+       int numfiles_layout;
+       int i;
+
+       /* escape if not our timer */
+       if(sfile->smoothscroll_timer==NULL || sfile->smoothscroll_timer!=event->customdata)
+               return OPERATOR_PASS_THROUGH;
+       
+       numfiles = filelist_numfiles(sfile->files);
+
+       /* check if we are editing a name */
+       for (i=0; i < numfiles; ++i)
+       {
+               struct direntry *file = filelist_file(sfile->files, i); 
+               if (file->flags & EDITING) {
+                       edit_idx=i;
+                       break;
+               }
+       }
+
+       /* if we are not editing, we are done */
+       if (0==edit_idx) {
+               WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
+               sfile->smoothscroll_timer=NULL;
+               return OPERATOR_PASS_THROUGH;
+       }
+
+       /* we need the correct area for scrolling */
+       ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+       if (!ar || ar->regiontype != RGN_TYPE_WINDOW) {
+               WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
+               sfile->smoothscroll_timer=NULL;
+               return OPERATOR_PASS_THROUGH;
+       }
+
+       offset = ED_fileselect_layout_offset(sfile->layout, 0, ar->v2d.cur.xmin, -ar->v2d.cur.ymax);
+       if (offset<0) offset=0;
+
+       /* scroll offset is the first file in the row/column we are editing in */
+       if (sfile->scroll_offset == 0) {
+               if (sfile->layout->flag & FILE_LAYOUT_HOR) {
+                       sfile->scroll_offset = (edit_idx/sfile->layout->rows)*sfile->layout->rows;
+                       if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows;
+               } else {
+                       sfile->scroll_offset = (edit_idx/sfile->layout->columns)*sfile->layout->columns;
+                       if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns;
+               }
+       }
+       
+       numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar);
+       
+       /* check if we have reached our final scroll position */
+       if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) {
+               WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
+               sfile->smoothscroll_timer=NULL;
+               return OPERATOR_FINISHED;
+       }
+
+       /* temporarily set context to the main window region, 
+        * so the scroll operators work */
+       CTX_wm_region_set(C, ar);
+       
+       /* scroll one step in the desired direction */
+       if (sfile->scroll_offset < offset) {
+               if (sfile->layout->flag & FILE_LAYOUT_HOR) {
+                       WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL);
+               } else {
+                       WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL);
+               }
+               
+       } else {
+               if (sfile->layout->flag & FILE_LAYOUT_HOR) {
+                       WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL);
+               } else {
+                       WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL);
+               }
+       }
+       
+       ED_region_tag_redraw(CTX_wm_region(C));
+       
+       /* and restore context */
+       CTX_wm_region_set(C, oldar);
+       
+       return OPERATOR_FINISHED;
+}
+
+
+void FILE_OT_smoothscroll(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Smooth Scroll";
+       ot->idname= "FILE_OT_smoothscroll";
+       ot->description="Smooth scroll to make editable file visible.";
+       
+       /* api callbacks */
+       ot->invoke= file_smoothscroll_invoke;
+       
+       ot->poll= ED_operator_file_active;
+}
+
+
 /* create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created.
    The actual name is returned in 'name', 'folder' contains the complete path, including the new folder name.
 */
@@ -794,6 +911,12 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
 
        /* now remember file to jump into editing */
        BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE);
+
+       /* set timer to smoothly view newly generated file */
+       sfile->smoothscroll_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/1000.0);        /* max 30 frs/sec */
+       sfile->scroll_offset=0;
+
+       /* reload dir to make sure we're seeing what's in the directory */
        ED_fileselect_clear(C, sfile);
        WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL);
 
@@ -822,7 +945,7 @@ int file_directory_exec(bContext *C, wmOperator *unused)
                if ( sfile->params->dir[0] == '~' ) {
                        char tmpstr[sizeof(sfile->params->dir)-1];
                        strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr));
-                       BLI_join_dirfile(sfile->params->dir, BLI_gethome(), tmpstr);
+                       BLI_join_dirfile(sfile->params->dir, BLI_getDefaultDocumentFolder(), tmpstr);
                }
 
 #ifdef WIN32