== file browser ==
authorAndrea Weikert <elubie@gmx.net>
Sun, 20 Mar 2011 10:22:51 +0000 (10:22 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sun, 20 Mar 2011 10:22:51 +0000 (10:22 +0000)
Patch from Alexander Kuznetsov: Toggle selection rather than just extending.

Implements behaviour that unintendedly was available with previously using macro operator for selection. This was removed and now the functionality is properly implemented.

Patch accepted with minor changes:
1. Used enum rather than #defines and added value for removing from selection (deselect)
2. Moved if (select) outside file_select_do and improved check for whether last file in selection is actually selected. (Necessary since toggle can deselect and toggle select should still make file active)
3. Additionally fixed check in file_select_invoke to be consistent with border select.

source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h

index 21880a6b0c614dbafcb59c6a8fe7f00e72848078..f36bb6f030d884fef2b5d2be1cbee48e35ea78d3 100644 (file)
@@ -162,7 +162,7 @@ static FileSelection file_selection_get(bContext* C, const rcti* rect, short fil
        return sel;
 }
 
-static FileSelect file_select_do(bContext* C, short select, int selected_idx)
+static FileSelect file_select_do(bContext* C, int selected_idx)
 {
        FileSelect retval = FILE_SELECT_NOTHING;
        SpaceFile *sfile= CTX_wm_space_file(C);
@@ -170,7 +170,7 @@ static FileSelect file_select_do(bContext* C, short select, int selected_idx)
        int numfiles = filelist_numfiles(sfile->files);
 
        /* make the selected file active */
-       if (select && (selected_idx >= 0) && (selected_idx < numfiles)) {
+       if ( (selected_idx >= 0) && (selected_idx < numfiles)) {
                struct direntry* file = filelist_file(sfile->files, selected_idx);
                params->active_file = selected_idx;
 
@@ -205,11 +205,12 @@ static FileSelect file_select_do(bContext* C, short select, int selected_idx)
 }
 
 
-static FileSelect file_select(bContext* C, const rcti* rect, short select, short fill)
+static FileSelect file_select(bContext* C, const rcti* rect, FileSelType select, short fill)
 {
        SpaceFile *sfile= CTX_wm_space_file(C);
        FileSelect retval = FILE_SELECT_NOTHING;
        FileSelection sel= file_selection_get(C, rect, fill); /* get the selection */
+       struct direntry *file;
        
        /* flag the files as selected in the filelist */
        filelist_select(sfile->files, &sel, select, ACTIVEFILE);
@@ -217,8 +218,12 @@ static FileSelect file_select(bContext* C, const rcti* rect, short select, short
        /* Don't act on multiple selected files */
        if (sel.first != sel.last) select = 0;
 
-       retval = file_select_do(C, select, sel.last);
-       
+       /* Check last selection, if selected, act on the file or dir */
+       file = filelist_file(sfile->files, sel.last);
+       if (file->flags & ACTIVEFILE) {
+               retval = file_select_do(C, sel.last);
+       }
+
        /* update operator for name change event */
        file_draw_check_cb(C, NULL, NULL);
        
@@ -249,7 +254,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
                sel = file_selection_get(C, &rect, 0);
                if ( (sel.first != params->sel_first) || (sel.last != params->sel_last) ) {
                        file_deselect_all(sfile, HILITED_FILE);
-                       filelist_select(sfile->files, &sel, 1, HILITED_FILE);
+                       filelist_select(sfile->files, &sel, FILE_SEL_ADD, HILITED_FILE);
                        WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL);
                }
                params->sel_first = sel.first; params->sel_last = sel.last;
@@ -278,7 +283,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
 
        BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect);
 
-       ret = file_select(C, &rect, select, 0);
+       ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, 0);
        if (FILE_SELECT_DIR == ret) {
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL);
        } else if (FILE_SELECT_FILE == ret) {
@@ -308,6 +313,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        ARegion *ar= CTX_wm_region(C);
        SpaceFile *sfile= CTX_wm_space_file(C);
+       FileSelect ret;
        rcti rect;
        int extend = RNA_boolean_get(op->ptr, "extend");
        int fill = RNA_boolean_get(op->ptr, "fill");
@@ -324,9 +330,10 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
        /* single select, deselect all selected first */
        if (!extend) file_deselect_all(sfile, ACTIVEFILE);
 
-       if (FILE_SELECT_DIR == file_select(C, &rect, 1, fill))
+       ret = file_select(C, &rect, extend ? FILE_SEL_TOGGLE : FILE_SEL_ADD, fill);
+       if (FILE_SELECT_DIR == ret)
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL);
-       else
+       else if (FILE_SELECT_FILE == ret)
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL);
 
        WM_event_add_mousemove(C); /* for directory changes */
index 5fb64b2f2bc70bd7d5efb041d8db06faca87cc5d..3c76b815a8040bc3c906ad8fc148a67f80eae790 100644 (file)
@@ -926,7 +926,7 @@ void filelist_swapselect(struct FileList* filelist)
        }
 }
 
-void filelist_select(struct FileList* filelist, FileSelection* sel, short select, unsigned int flag)
+void filelist_select(struct FileList* filelist, FileSelection* sel, FileSelType select, unsigned int flag)
 {
        /* select all valid files between first and last indicated */
        if ( (sel->first >= 0) && (sel->first < filelist->numfiltered) && (sel->last >= 0) && (sel->last < filelist->numfiltered) ) {
@@ -934,10 +934,17 @@ void filelist_select(struct FileList* filelist, FileSelection* sel, short select
                for (current_file = sel->first; current_file <= sel->last; current_file++) {    
                        struct direntry* file = filelist_file(filelist, current_file);
                        
-                       if (select) 
-                               file->flags |= flag;
-                       else
-                               file->flags &= ~flag;
+                       switch (select) {
+                               case FILE_SEL_REMOVE:
+                                       file->flags &= ~flag;
+                                       break;
+                               case FILE_SEL_ADD:
+                                       file->flags |= flag;
+                                       break;
+                               case FILE_SEL_TOGGLE:
+                                       file->flags ^= flag;
+                                       break;
+                       }
                }
        }
 }
index 399a8ff794370a8481fc1a2d1d9f7733b1a52e92..3e3b52ed17c29d8002cb88ca9929c8260864819b 100644 (file)
@@ -52,6 +52,11 @@ struct rcti;
 struct ReportList;
 struct FileSelection;
 
+typedef enum FileSelType {
+       FILE_SEL_REMOVE = 0,
+       FILE_SEL_ADD =  1,
+       FILE_SEL_TOGGLE  = 2
+} FileSelType;
 
 struct FileList *      filelist_new(short type);
 void                           filelist_init_icons(void);
@@ -63,7 +68,7 @@ int                                   filelist_numfiles(struct FileList* filelist);
 const char *           filelist_dir(struct FileList* filelist);
 void                           filelist_setdir(struct FileList* filelist, const char *dir);
 struct direntry *      filelist_file(struct FileList* filelist, int index);
-void                           filelist_select(struct FileList* filelist, FileSelection* sel, short select, unsigned int flag);
+void                           filelist_select(struct FileList* filelist, FileSelection* sel, FileSelType select, unsigned int flag);
 void                           filelist_hidedot(struct FileList* filelist, short hide);
 void                           filelist_setfilter(struct FileList* filelist, unsigned int filter);
 void                           filelist_setfilter_types(struct FileList* filelist, const char *filter_glob);