Merging trunk up to r39447.
[blender-staging.git] / source / blender / editors / space_sequencer / sequencer_add.c
index a138866956a8f205d357d275d7999d6ab9aadb6b..2fe16b3a85dbcb8bd6d5c188e34a25e87147035d 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/space_sequencer/sequencer_add.c
+ *  \ingroup spseq
+ */
+
+
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_storage_types.h"
+#include "BLI_utildefines.h"
 
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
-#include "DNA_ipo_types.h"
-#include "DNA_curve_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_view2d_types.h"
 #include "DNA_userdef_types.h"
-#include "DNA_sound_types.h"
 
 #include "BKE_context.h"
 #include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_library.h"
 #include "BKE_main.h"
-#include "BKE_plugin_types.h"
 #include "BKE_sequencer.h"
-#include "BKE_scene.h"
-#include "BKE_utildefines.h"
 #include "BKE_report.h"
 
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
-#include "RNA_access.h"
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
 
 /* for menu/popup icons etc etc*/
-#include "UI_interface.h"
-#include "UI_resources.h"
 
-#include "ED_anim_api.h"
-#include "ED_space_api.h"
-#include "ED_types.h"
 #include "ED_screen.h"
-#include "ED_util.h"
-#include "ED_fileselect.h"
 
-#include "UI_interface.h"
-#include "UI_resources.h"
 #include "UI_view2d.h"
 
 #include "BKE_sound.h"
-#include "AUD_C-API.h"
+
+#ifdef WITH_AUDASPACE
+#  include "AUD_C-API.h"
+#endif
 
 /* own include */
 #include "sequencer_intern.h"
 /* Generic functions, reused by add strip operators */
 
 /* avoid passing multiple args and be more verbose */
-#define SEQPROP_STARTFRAME     1<<0
-#define SEQPROP_ENDFRAME       1<<1
-#define SEQPROP_FILES          1<<2
+#define SEQPROP_STARTFRAME     (1<<0)
+#define SEQPROP_ENDFRAME       (1<<1)
+#define SEQPROP_NOPATHS                (1<<2)
+#define SEQPROP_NOCHAN         (1<<3)
+
+#define SELECT 1
 
 static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
 {
-       RNA_def_string(ot->srna, "name", "", MAX_ID_NAME-2, "Name", "Name of the new sequence strip");
-
        if(flag & SEQPROP_STARTFRAME)
-               RNA_def_int(ot->srna, "start_frame", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame of the sequence strip", INT_MIN, INT_MAX);
+               RNA_def_int(ot->srna, "frame_start", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame of the sequence strip", INT_MIN, INT_MAX);
        
        if(flag & SEQPROP_ENDFRAME)
-               RNA_def_int(ot->srna, "end_frame", 0, INT_MIN, INT_MAX, "End Frame", "End frame for the color strip", INT_MIN, INT_MAX); /* not useual since most strips have a fixed length */
+               RNA_def_int(ot->srna, "frame_end", 0, INT_MIN, INT_MAX, "End Frame", "End frame for the color strip", INT_MIN, INT_MAX); /* not useual since most strips have a fixed length */
        
        RNA_def_int(ot->srna, "channel", 1, 1, MAXSEQ, "Channel", "Channel to place this strip into", 1, MAXSEQ);
        
        RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection");
 
-       if(flag & SEQPROP_FILES)
-               RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
+       RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips");
+}
+
+static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, const char *identifier)
+{
+       if(RNA_struct_find_property(op->ptr, identifier)) {
+               Scene *scene= CTX_data_scene(C);
+               Sequence *last_seq= seq_active_get(scene);
+               if(last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) {
+                       char path[sizeof(last_seq->strip->dir)];
+                       BLI_strncpy(path, last_seq->strip->dir, sizeof(path));
+                       BLI_path_abs(path, G.main->name);
+                       RNA_string_set(op->ptr, identifier, path);
+               }
+       }
 }
 
 static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, wmEvent *event, int flag)
 {
-       ARegion *ar= CTX_wm_region(C);
        View2D *v2d= UI_view2d_fromcontext(C);
        
-       short mval[2];  
        float mval_v2d[2];
        
+       UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mval_v2d[0], &mval_v2d[1]);
 
-       mval[0]= event->x - ar->winrct.xmin;
-       mval[1]= event->y - ar->winrct.ymin;
-       
-       UI_view2d_region_to_view(v2d, mval[0], mval[1], &mval_v2d[0], &mval_v2d[1]);
-       
-       RNA_int_set(op->ptr, "channel", (int)mval_v2d[1]+0.5f);
-       RNA_int_set(op->ptr, "start_frame", (int)mval_v2d[0]);
-       
-       if ((flag & SEQPROP_ENDFRAME) && RNA_property_is_set(op->ptr, "end_frame")==0)
-               RNA_int_set(op->ptr, "end_frame", (int)mval_v2d[0] + 25); // XXX arbitary but ok for now.
+       /* effect strips dont need a channel initialized from the mouse */
+       if(!(flag & SEQPROP_NOCHAN)) {
+               RNA_int_set(op->ptr, "channel", (int)mval_v2d[1]+0.5f);
+       }
+
+       RNA_int_set(op->ptr, "frame_start", (int)mval_v2d[0]);
        
+       if ((flag & SEQPROP_ENDFRAME) && RNA_property_is_set(op->ptr, "frame_end")==0)
+               RNA_int_set(op->ptr, "frame_end", (int)mval_v2d[0] + 25); // XXX arbitary but ok for now.
+
+       if (!(flag & SEQPROP_NOPATHS)) {
+               sequencer_generic_invoke_path__internal(C, op, "filepath");
+               sequencer_generic_invoke_path__internal(C, op, "directory");
+       }
 }
 
 static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op)
 {
+       int relative= RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path");
+       int is_file= -1;
        memset(seq_load, 0, sizeof(SeqLoadInfo));
 
-       seq_load->start_frame=  RNA_int_get(op->ptr, "start_frame");
+       seq_load->start_frame=  RNA_int_get(op->ptr, "frame_start");
        seq_load->end_frame=    seq_load->start_frame; /* un-set */
 
        seq_load->channel=              RNA_int_get(op->ptr, "channel");
        seq_load->len=                  1; // images only, if endframe isnt set!
 
-       RNA_string_get(op->ptr, "name", seq_load->name+2);
+       if(RNA_struct_find_property(op->ptr, "filepath")) {
+               RNA_string_get(op->ptr, "filepath", seq_load->path); /* full path, file is set by the caller */
+               is_file= 1;
+       } else if (RNA_struct_find_property(op->ptr, "directory")) {
+               RNA_string_get(op->ptr, "directory", seq_load->path); /* full path, file is set by the caller */
+               is_file= 0;
+       }
 
-       RNA_string_get(op->ptr, "path", seq_load->path); /* full path, file is set by the caller */
+       if((is_file != -1) && relative)
+               BLI_path_rel(seq_load->path, G.main->name);
 
-       if (RNA_struct_find_property(op->ptr, "end_frame")) {
-               seq_load->end_frame = RNA_int_get(op->ptr, "end_frame");
+       
+       if (RNA_struct_find_property(op->ptr, "frame_end")) {
+               seq_load->end_frame = RNA_int_get(op->ptr, "frame_end");
        }
 
        if (RNA_struct_find_property(op->ptr, "replace_sel") && RNA_boolean_get(op->ptr, "replace_sel"))
@@ -172,6 +180,22 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op)
 
        /* always use this for ops */
        seq_load->flag |= SEQ_LOAD_FRAME_ADVANCE;
+
+
+       if(is_file==1) {
+               BLI_strncpy(seq_load->name, BLI_path_basename(seq_load->path), sizeof(seq_load->name));
+       }
+       else if(RNA_struct_find_property(op->ptr, "files")) {
+               /* used for image strip */
+               /* best guess, first images name */
+               RNA_BEGIN(op->ptr, itemptr, "files") {
+                       char *name= RNA_string_get_alloc(&itemptr, "name", NULL, 0);
+                       BLI_strncpy(seq_load->name, name, sizeof(seq_load->name));
+                       MEM_freeN(name);
+                       break;
+               }
+               RNA_END;
+       }
 }
 
 /* add scene operator */
@@ -184,11 +208,10 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
 
        Sequence *seq;  /* generic strip vars */
        Strip *strip;
-       StripElem *se;
        
        int start_frame, channel; /* operator props */
        
-       start_frame= RNA_int_get(op->ptr, "start_frame");
+       start_frame= RNA_int_get(op->ptr, "frame_start");
        channel= RNA_int_get(op->ptr, "channel");
        
        sce_seq= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
@@ -199,31 +222,37 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
        }
        
        seq = alloc_sequence(ed->seqbasep, start_frame, channel);
-       
        seq->type= SEQ_SCENE;
+       seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
+
        seq->scene= sce_seq;
+       seq->sfra= sce_seq->r.sfra;
        
        /* basic defaults */
        seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
        strip->len = seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
        strip->us= 1;
        
-       strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-       
-       if(RNA_property_is_set(op->ptr, "name"))
-               RNA_string_get(op->ptr, "name", seq->name+2);
-       else
-               strcpy(seq->name+2, sce_seq->id.name+2);
+       strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
        
+       strcpy(seq->name+2, sce_seq->id.name+2);
+       seqbase_unique_name_recursive(&ed->seqbase, seq);
+
+       seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + strip->len, 0);
+
        calc_sequence_disp(scene, seq);
        sort_seq(scene);
        
        if (RNA_boolean_get(op->ptr, "replace_sel")) {
                deselect_all_seq(scene);
-               active_seq_set(scene, seq);
+               seq_active_set(scene, seq);
                seq->flag |= SELECT;
        }
-       
+
+       if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+               if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+       }
+
        WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
        
        return OPERATOR_FINISHED;
@@ -237,6 +266,9 @@ static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, wmEvent
                return OPERATOR_CANCELLED;
        }
 
+       if(!RNA_property_is_set(op->ptr, "scene"))
+               return WM_enum_search_invoke(C, op, event);
+
        sequencer_generic_invoke_xy__internal(C, op, event, 0);
        return sequencer_add_scene_strip_exec(C, op);
        // needs a menu
@@ -275,6 +307,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
        SeqLoadInfo seq_load;
        Sequence *seq;
        int tot_files;
+       const short overlap= RNA_boolean_get(op->ptr, "overlap");
 
        seq_load_operator_info(&seq_load, op);
 
@@ -292,15 +325,23 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
 
                RNA_BEGIN(op->ptr, itemptr, "files") {
                        RNA_string_get(&itemptr, "name", file_only);
-                       BLI_join_dirfile(seq_load.path, dir_only, file_only);
+                       BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only);
 
                        seq= seq_load_func(C, ed->seqbasep, &seq_load);
+
+                       if(overlap == FALSE) {
+                               if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+                       }
                }
                RNA_END;
        }
        else {
                /* single file */
                seq= seq_load_func(C, ed->seqbasep, &seq_load);
+
+               if(overlap == FALSE) {
+                       if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+               }
        }
 
        if (seq_load.tot_success==0) {
@@ -309,7 +350,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
        }
 
        sort_seq(scene);
-       seq_update_muting(scene, ed);
+       seq_update_muting(ed);
 
        WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
 
@@ -325,13 +366,26 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
 
 static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+
        if(!ED_operator_sequencer_active(C)) {
                BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
                return OPERATOR_CANCELLED;
        }
 
+       /* This is for drag and drop */
+       if(RNA_collection_length(op->ptr, "files") || RNA_property_is_set(op->ptr, "filepath")) {
+               sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS);
+               return sequencer_add_movie_strip_exec(C, op);
+       }
+       
        sequencer_generic_invoke_xy__internal(C, op, event, 0);
-       return WM_operator_filesel(C, op, event);
+       
+       if(!RNA_property_is_set(op->ptr, "relative_path"))
+               RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+       
+       WM_event_add_fileselect(C, op);
+       return OPERATOR_RUNNING_MODAL;
+
        //return sequencer_add_movie_strip_exec(C, op);
 }
 
@@ -353,8 +407,8 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE);
-       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_FILES);
+       WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES);
+       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
 }
 
@@ -367,13 +421,26 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
 
 static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+
        if(!ED_operator_sequencer_active(C)) {
                BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
                return OPERATOR_CANCELLED;
        }
-
+       
+       /* This is for drag and drop */
+       if(RNA_collection_length(op->ptr, "files") || RNA_property_is_set(op->ptr, "filepath")) {
+               sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS);
+               return sequencer_add_sound_strip_exec(C, op);
+       }
+       
        sequencer_generic_invoke_xy__internal(C, op, event, 0);
-       return WM_operator_filesel(C, op, event);
+       
+       if(!RNA_property_is_set(op->ptr, "relative_path"))
+               RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+       
+       WM_event_add_fileselect(C, op);
+       return OPERATOR_RUNNING_MODAL;
+
        //return sequencer_add_sound_strip_exec(C, op);
 }
 
@@ -395,8 +462,8 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE);
-       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_FILES);
+       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES);
+       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory.");
 }
 
@@ -419,26 +486,26 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
        seq_load.len= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
 
        if(seq_load.len==0)
-               seq_load.len= 1;
+               return OPERATOR_CANCELLED;
 
        if(seq_load.flag & SEQ_LOAD_REPLACE_SEL)
                deselect_all_seq(scene);
 
-       
+
        /* main adding function */
        seq= sequencer_add_image_strip(C, ed->seqbasep, &seq_load);
        strip= seq->strip;
        se= strip->stripdata;
 
-       if(seq_load.len > 1) {
-               RNA_BEGIN(op->ptr, itemptr, "files") {
-                       RNA_string_get(&itemptr, "name", se->name);
-                       se++;
-               }
-               RNA_END;
+       RNA_BEGIN(op->ptr, itemptr, "files") {
+               char *filename= RNA_string_get_alloc(&itemptr, "name", NULL, 0);
+               BLI_strncpy(se->name, filename, sizeof(se->name));
+               MEM_freeN(filename);
+               se++;
        }
-       else {
-               BLI_split_dirfile(seq_load.path, NULL, se->name);
+       RNA_END;
+
+       if(seq_load.len == 1) {
                if(seq_load.start_frame < seq_load.end_frame) {
                        seq->endstill= seq_load.end_frame - seq_load.start_frame;
                }
@@ -450,7 +517,11 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
 
        /* last active name */
        strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR-1);
-       
+
+       if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+               if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+       }
+
        WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
 
        return OPERATOR_FINISHED;
@@ -458,14 +529,26 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
 
 static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+
        if(!ED_operator_sequencer_active(C)) {
                BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
                return OPERATOR_CANCELLED;
        }
 
+
+       /* drag drop has set the names */
+       if(RNA_collection_length(op->ptr, "files")) {
+               sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME|SEQPROP_NOPATHS);
+               return sequencer_add_image_strip_exec(C, op);
+       }
+       
        sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME);
-       return WM_operator_filesel(C, op, event);       
-       //return sequencer_add_image_strip_exec(C, op);
+       
+       if(!RNA_property_is_set(op->ptr, "relative_path"))
+               RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+
+       WM_event_add_fileselect(C, op);
+       return OPERATOR_RUNNING_MODAL;
 }
 
 
@@ -486,8 +569,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE);
-       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME|SEQPROP_FILES);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILES);
+       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME);
 }
 
 
@@ -499,21 +582,20 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
 
        Sequence *seq;  /* generic strip vars */
        Strip *strip;
-       StripElem *se;
        struct SeqEffectHandle sh;
 
        int start_frame, end_frame, channel, type; /* operator props */
        
        Sequence *seq1, *seq2, *seq3;
-       char *error_msg;
+       const char *error_msg;
 
-       start_frame= RNA_int_get(op->ptr, "start_frame");
-       end_frame= RNA_int_get(op->ptr, "end_frame");
+       start_frame= RNA_int_get(op->ptr, "frame_start");
+       end_frame= RNA_int_get(op->ptr, "frame_end");
        channel= RNA_int_get(op->ptr, "channel");
 
        type= RNA_enum_get(op->ptr, "type");
        
-       // XXX We need unique names and move to invoke
+       // XXX move to invoke
        if(!seq_effect_find_selected(scene, NULL, type, &seq1, &seq2, &seq3, &error_msg)) {
                BKE_report(op->reports, RPT_ERROR, error_msg);
                return OPERATOR_CANCELLED;
@@ -529,11 +611,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
        seq = alloc_sequence(ed->seqbasep, start_frame, channel);
        seq->type= type;
 
-       if(RNA_property_is_set(op->ptr, "name"))
-               RNA_string_get(op->ptr, "name", seq->name+2);
-       else
-               strcpy(seq->name+2, give_seqname(seq));
-
+       BLI_strncpy(seq->name+2, give_seqname(seq), sizeof(seq->name)-2);
        seqbase_unique_name_recursive(&ed->seqbase, seq);
 
        sh = get_sequence_effect(seq);
@@ -558,11 +636,11 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
        strip->len = seq->len;
        strip->us= 1;
        if(seq->len>0)
-               strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+               strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
 
        if (seq->type==SEQ_PLUGIN) {
                char path[FILE_MAX];
-               RNA_string_get(op->ptr, "path", path);
+               RNA_string_get(op->ptr, "filepath", path);
 
                sh.init_plugin(seq, path);
 
@@ -572,13 +650,30 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
                        BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", path);
                        return OPERATOR_CANCELLED;
                }
-       }
-       else if (seq->type==SEQ_COLOR) {
+       } else if (seq->type == SEQ_COLOR) {
                SolidColorVars *colvars= (SolidColorVars *)seq->effectdata;
                RNA_float_get_array(op->ptr, "color", colvars->col);
+               seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
+
+       } else if (seq->type == SEQ_ADJUSTMENT) {
+               seq->blend_mode= SEQ_CROSS;
        }
 
-       if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+       /* an unset channel is a special case where we automatically go above
+        * the other strips. */
+       if(!RNA_property_is_set(op->ptr, "channel")) {
+               if(seq->seq1) {
+                       int chan= MAX3( seq->seq1 ? seq->seq1->machine : 0,
+                                                       seq->seq2 ? seq->seq2->machine : 0,
+                                                       seq->seq3 ? seq->seq3->machine : 0);
+                       if(chan < MAXSEQ)
+                               seq->machine= chan;
+               }
+       }
+
+       if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+               if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+       }
 
        update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */
 
@@ -589,7 +684,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
 
        if (RNA_boolean_get(op->ptr, "replace_sel")) {
                deselect_all_seq(scene);
-               active_seq_set(scene, seq);
+               seq_active_set(scene, seq);
                seq->flag |= SELECT;
        }
 
@@ -602,14 +697,34 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
 /* add color */
 static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+       short is_type_set= RNA_property_is_set(op->ptr, "type");
+       int type= -1;
+       int prop_flag= SEQPROP_ENDFRAME;
+
        if(!ED_operator_sequencer_active(C)) {
                BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
                return OPERATOR_CANCELLED;
        }
 
-       sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME);
+       if(is_type_set) {
+               type= RNA_enum_get(op->ptr, "type");
+
+               /* when invoking an effect strip which uses inputs,
+                * skip initialzing the channel from the mouse.
+                * Instead leave the property unset so exec() initializes it to be
+                * above the strips its applied to. */
+               if(get_sequence_effect_num_inputs(type) != 0) {
+                       prop_flag |= SEQPROP_NOCHAN;
+               }
+       }
+
+       sequencer_generic_invoke_xy__internal(C, op, event, prop_flag);
+
+       if (is_type_set && type==SEQ_PLUGIN) {
+
+               if(!RNA_property_is_set(op->ptr, "relative_path"))
+                       RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
 
-       if (RNA_property_is_set(op->ptr, "type") && RNA_enum_get(op->ptr, "type")==SEQ_PLUGIN) {
                /* only plugins need the file selector */
                return WM_operator_filesel(C, op, event);
        }
@@ -634,7 +749,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE);
+       WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME);
        RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type");
        RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f);