ff895c06d5792b98d3326608a06eab6d94c8cb79
[blender.git] / source / blender / editors / space_sequencer / sequencer_add.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2003-2009, Campbell Barton
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_sequencer/sequencer_add.c
27  *  \ingroup spseq
28  */
29
30
31 #include <stdlib.h>
32 #include <math.h>
33 #include <string.h>
34
35 #ifndef WIN32
36 #include <unistd.h>
37 #else
38 #include <io.h>
39 #endif
40 #include <sys/types.h>
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_math.h"
46 #include "BLI_utildefines.h"
47
48 #include "DNA_scene_types.h"
49 #include "DNA_mask_types.h"
50 #include "DNA_userdef_types.h"
51
52 #include "BKE_context.h"
53 #include "BKE_global.h"
54 #include "BKE_library.h"
55 #include "BKE_main.h"
56 #include "BKE_sequencer.h"
57 #include "BKE_movieclip.h"
58 #include "BKE_sequencer.h"
59 #include "BKE_mask.h"
60 #include "BKE_report.h"
61
62 #include "WM_api.h"
63 #include "WM_types.h"
64
65 #include "RNA_define.h"
66 #include "RNA_enum_types.h"
67
68 /* for menu/popup icons etc etc*/
69
70 #include "ED_screen.h"
71 #include "ED_sequencer.h"
72
73 #include "UI_view2d.h"
74
75 #include "BKE_sound.h"
76
77 #ifdef WITH_AUDASPACE
78 #  include "AUD_C-API.h"
79 #endif
80
81 /* own include */
82 #include "sequencer_intern.h"
83
84 /* Generic functions, reused by add strip operators */
85
86 /* avoid passing multiple args and be more verbose */
87 #define SEQPROP_STARTFRAME  (1 << 0)
88 #define SEQPROP_ENDFRAME    (1 << 1)
89 #define SEQPROP_NOPATHS     (1 << 2)
90 #define SEQPROP_NOCHAN      (1 << 3)
91
92 #define SELECT 1
93
94 static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
95 {
96         PropertyRNA *prop;
97
98         if (flag & SEQPROP_STARTFRAME)
99                 RNA_def_int(ot->srna, "frame_start", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame of the sequence strip", INT_MIN, INT_MAX);
100         
101         if (flag & SEQPROP_ENDFRAME)
102                 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 usual since most strips have a fixed length */
103         
104         RNA_def_int(ot->srna, "channel", 1, 1, MAXSEQ, "Channel", "Channel to place this strip into", 1, MAXSEQ);
105         
106         RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "Replace the current selection");
107
108         /* only for python scripts which import strips and place them after */
109         prop = RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips");
110         RNA_def_property_flag(prop, PROP_HIDDEN);
111 }
112
113 static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, const char *identifier)
114 {
115         if (RNA_struct_find_property(op->ptr, identifier)) {
116                 Scene *scene = CTX_data_scene(C);
117                 Sequence *last_seq = BKE_sequencer_active_get(scene);
118                 if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) {
119                         char path[sizeof(last_seq->strip->dir)];
120                         BLI_strncpy(path, last_seq->strip->dir, sizeof(path));
121                         BLI_path_abs(path, G.main->name);
122                         RNA_string_set(op->ptr, identifier, path);
123                 }
124         }
125 }
126
127 static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, wmEvent *event, int flag)
128 {
129         View2D *v2d = UI_view2d_fromcontext(C);
130         
131         float mval_v2d[2];
132         
133         UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mval_v2d[0], &mval_v2d[1]);
134
135         /* effect strips don't need a channel initialized from the mouse */
136         if (!(flag & SEQPROP_NOCHAN)) {
137                 RNA_int_set(op->ptr, "channel", (int)mval_v2d[1] + 0.5f);
138         }
139
140         RNA_int_set(op->ptr, "frame_start", (int)mval_v2d[0]);
141         
142         if ((flag & SEQPROP_ENDFRAME) && RNA_struct_property_is_set(op->ptr, "frame_end") == 0)
143                 RNA_int_set(op->ptr, "frame_end", (int)mval_v2d[0] + 25);  // XXX arbitary but ok for now.
144
145         if (!(flag & SEQPROP_NOPATHS)) {
146                 sequencer_generic_invoke_path__internal(C, op, "filepath");
147                 sequencer_generic_invoke_path__internal(C, op, "directory");
148         }
149 }
150
151 static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op)
152 {
153         int relative = RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path");
154         int is_file = -1;
155         memset(seq_load, 0, sizeof(SeqLoadInfo));
156
157         seq_load->start_frame =  RNA_int_get(op->ptr, "frame_start");
158         seq_load->end_frame =    seq_load->start_frame; /* un-set */
159
160         seq_load->channel =      RNA_int_get(op->ptr, "channel");
161         seq_load->len =          1; // images only, if endframe isn't set!
162
163         if (RNA_struct_find_property(op->ptr, "filepath")) {
164                 RNA_string_get(op->ptr, "filepath", seq_load->path); /* full path, file is set by the caller */
165                 is_file = 1;
166         }
167         else if (RNA_struct_find_property(op->ptr, "directory")) {
168                 RNA_string_get(op->ptr, "directory", seq_load->path); /* full path, file is set by the caller */
169                 is_file = 0;
170         }
171
172         if ((is_file != -1) && relative)
173                 BLI_path_rel(seq_load->path, G.main->name);
174
175         
176         if (RNA_struct_find_property(op->ptr, "frame_end")) {
177                 seq_load->end_frame = RNA_int_get(op->ptr, "frame_end");
178         }
179
180         if (RNA_struct_find_property(op->ptr, "replace_sel") && RNA_boolean_get(op->ptr, "replace_sel"))
181                 seq_load->flag |= SEQ_LOAD_REPLACE_SEL;
182
183         if (RNA_struct_find_property(op->ptr, "cache") && RNA_boolean_get(op->ptr, "cache"))
184                 seq_load->flag |= SEQ_LOAD_SOUND_CACHE;
185
186         if (RNA_struct_find_property(op->ptr, "sound") && RNA_boolean_get(op->ptr, "sound"))
187                 seq_load->flag |= SEQ_LOAD_MOVIE_SOUND;
188
189         /* always use this for ops */
190         seq_load->flag |= SEQ_LOAD_FRAME_ADVANCE;
191
192
193         if (is_file == 1) {
194                 BLI_strncpy(seq_load->name, BLI_path_basename(seq_load->path), sizeof(seq_load->name));
195         }
196         else if (RNA_struct_find_property(op->ptr, "files")) {
197                 /* used for image strip */
198                 /* best guess, first images name */
199                 RNA_BEGIN (op->ptr, itemptr, "files")
200                 {
201                         char *name = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
202                         BLI_strncpy(seq_load->name, name, sizeof(seq_load->name));
203                         MEM_freeN(name);
204                         break;
205                 }
206                 RNA_END;
207         }
208 }
209
210 /* add scene operator */
211 static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
212 {
213         Scene *scene = CTX_data_scene(C);
214         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
215         
216         Scene *sce_seq;
217
218         Sequence *seq;  /* generic strip vars */
219         Strip *strip;
220         
221         int start_frame, channel; /* operator props */
222         
223         start_frame = RNA_int_get(op->ptr, "frame_start");
224         channel = RNA_int_get(op->ptr, "channel");
225         
226         sce_seq = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
227         
228         if (sce_seq == NULL) {
229                 BKE_report(op->reports, RPT_ERROR, "Scene not found");
230                 return OPERATOR_CANCELLED;
231         }
232         
233         seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
234         seq->type = SEQ_TYPE_SCENE;
235         seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
236
237         seq->scene = sce_seq;
238         
239         /* basic defaults */
240         seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
241         seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
242         strip->us = 1;
243         
244         BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2);
245         BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
246
247         seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
248
249         BKE_sequence_calc_disp(scene, seq);
250         BKE_sequencer_sort(scene);
251         
252         if (RNA_boolean_get(op->ptr, "replace_sel")) {
253                 ED_sequencer_deselect_all(scene);
254                 BKE_sequencer_active_set(scene, seq);
255                 seq->flag |= SELECT;
256         }
257
258         if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
259                 if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
260         }
261
262         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
263         
264         return OPERATOR_FINISHED;
265 }
266
267
268 static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
269 {
270         if (!ED_operator_sequencer_active(C)) {
271                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
272                 return OPERATOR_CANCELLED;
273         }
274
275         if (!RNA_struct_property_is_set(op->ptr, "scene"))
276                 return WM_enum_search_invoke(C, op, event);
277
278         sequencer_generic_invoke_xy__internal(C, op, event, 0);
279         return sequencer_add_scene_strip_exec(C, op);
280         // needs a menu
281         // return WM_menu_invoke(C, op, event);
282 }
283
284
285 void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
286 {
287         PropertyRNA *prop;
288         
289         /* identifiers */
290         ot->name = "Add Scene Strip";
291         ot->idname = "SEQUENCER_OT_scene_strip_add";
292         ot->description = "Add a strip to the sequencer using a blender scene as a source";
293
294         /* api callbacks */
295         ot->invoke = sequencer_add_scene_strip_invoke;
296         ot->exec = sequencer_add_scene_strip_exec;
297
298         ot->poll = ED_operator_scene_editable;
299         
300         /* flags */
301         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
302         
303         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
304         prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
305         RNA_def_enum_funcs(prop, RNA_scene_itemf);
306         ot->prop = prop;
307 }
308
309 /* add movieclip operator */
310 static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
311 {
312         Scene *scene = CTX_data_scene(C);
313         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
314         
315         MovieClip *clip;
316
317         Sequence *seq;  /* generic strip vars */
318         Strip *strip;
319         
320         int start_frame, channel; /* operator props */
321         
322         start_frame = RNA_int_get(op->ptr, "frame_start");
323         channel = RNA_int_get(op->ptr, "channel");
324         
325         clip = BLI_findlink(&CTX_data_main(C)->movieclip, RNA_enum_get(op->ptr, "clip"));
326         
327         if (clip == NULL) {
328                 BKE_report(op->reports, RPT_ERROR, "MovieClip not found");
329                 return OPERATOR_CANCELLED;
330         }
331         
332         seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
333         seq->type = SEQ_TYPE_MOVIECLIP;
334         seq->blend_mode = SEQ_TYPE_CROSS;
335         seq->clip = clip;
336
337         if (seq->clip->id.us == 0)
338                 seq->clip->id.us = 1;
339
340         /* basic defaults */
341         seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
342         seq->len =  BKE_movieclip_get_duration(clip);
343         strip->us = 1;
344         
345         BLI_strncpy(seq->name + 2, clip->id.name + 2, sizeof(seq->name) - 2);
346         BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
347
348         BKE_sequence_calc_disp(scene, seq);
349         BKE_sequencer_sort(scene);
350         
351         if (RNA_boolean_get(op->ptr, "replace_sel")) {
352                 ED_sequencer_deselect_all(scene);
353                 BKE_sequencer_active_set(scene, seq);
354                 seq->flag |= SELECT;
355         }
356
357         if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
358                 if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
359         }
360
361         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
362         
363         return OPERATOR_FINISHED;
364 }
365
366 static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
367 {
368         if (!ED_operator_sequencer_active(C)) {
369                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
370                 return OPERATOR_CANCELLED;
371         }
372
373         if (!RNA_struct_property_is_set(op->ptr, "clip"))
374                 return WM_enum_search_invoke(C, op, event);
375
376         sequencer_generic_invoke_xy__internal(C, op, event, 0);
377         return sequencer_add_movieclip_strip_exec(C, op);
378         // needs a menu
379         // return WM_menu_invoke(C, op, event);
380 }
381
382 void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
383 {
384         PropertyRNA *prop;
385
386         /* identifiers */
387         ot->name = "Add MovieClip Strip";
388         ot->idname = "SEQUENCER_OT_movieclip_strip_add";
389         ot->description = "Add a movieclip strip to the sequencer";
390
391         /* api callbacks */
392         ot->invoke = sequencer_add_movieclip_strip_invoke;
393         ot->exec = sequencer_add_movieclip_strip_exec;
394
395         ot->poll = ED_operator_scene_editable;
396
397         /* flags */
398         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
399
400         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
401         prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", "");
402         RNA_def_enum_funcs(prop, RNA_movieclip_itemf);
403         ot->prop = prop;
404 }
405
406 static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
407 {
408         Scene *scene = CTX_data_scene(C);
409         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
410
411         Mask *mask;
412
413         Sequence *seq;  /* generic strip vars */
414         Strip *strip;
415
416         int start_frame, channel; /* operator props */
417
418         start_frame = RNA_int_get(op->ptr, "frame_start");
419         channel = RNA_int_get(op->ptr, "channel");
420
421         mask = BLI_findlink(&CTX_data_main(C)->mask, RNA_enum_get(op->ptr, "mask"));
422
423         if (mask == NULL) {
424                 BKE_report(op->reports, RPT_ERROR, "Mask not found");
425                 return OPERATOR_CANCELLED;
426         }
427
428         seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
429         seq->type = SEQ_TYPE_MASK;
430         seq->blend_mode = SEQ_TYPE_CROSS;
431         seq->mask = mask;
432
433         if (seq->mask->id.us == 0)
434                 seq->mask->id.us = 1;
435
436         /* basic defaults */
437         seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
438         seq->len = BKE_mask_get_duration(mask);
439         strip->us = 1;
440
441         BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2);
442         BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
443
444         BKE_sequence_calc_disp(scene, seq);
445         BKE_sequencer_sort(scene);
446
447         if (RNA_boolean_get(op->ptr, "replace_sel")) {
448                 ED_sequencer_deselect_all(scene);
449                 BKE_sequencer_active_set(scene, seq);
450                 seq->flag |= SELECT;
451         }
452
453         if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
454                 if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
455         }
456
457         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
458
459         return OPERATOR_FINISHED;
460 }
461
462 static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
463 {
464         if (!ED_operator_sequencer_active(C)) {
465                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
466                 return OPERATOR_CANCELLED;
467         }
468
469         if (!RNA_struct_property_is_set(op->ptr, "mask"))
470                 return WM_enum_search_invoke(C, op, event);
471
472         sequencer_generic_invoke_xy__internal(C, op, event, 0);
473         return sequencer_add_mask_strip_exec(C, op);
474         // needs a menu
475         // return WM_menu_invoke(C, op, event);
476 }
477
478
479 void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot)
480 {
481         PropertyRNA *prop;
482
483         /* identifiers */
484         ot->name = "Add Mask Strip";
485         ot->idname = "SEQUENCER_OT_mask_strip_add";
486         ot->description = "Add a mask strip to the sequencer";
487
488         /* api callbacks */
489         ot->invoke = sequencer_add_mask_strip_invoke;
490         ot->exec = sequencer_add_mask_strip_exec;
491
492         ot->poll = ED_operator_scene_editable;
493
494         /* flags */
495         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
496
497         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
498         prop = RNA_def_enum(ot->srna, "mask", DummyRNA_NULL_items, 0, "Mask", "");
499         RNA_def_enum_funcs(prop, RNA_mask_itemf);
500         ot->prop = prop;
501 }
502
503
504 static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func)
505 {
506         Scene *scene = CTX_data_scene(C); /* only for sound */
507         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
508         SeqLoadInfo seq_load;
509         Sequence *seq;
510         int tot_files;
511         const short overlap = RNA_boolean_get(op->ptr, "overlap");
512
513         seq_load_operator_info(&seq_load, op);
514
515         if (seq_load.flag & SEQ_LOAD_REPLACE_SEL)
516                 ED_sequencer_deselect_all(scene);
517
518         if (RNA_struct_property_is_set(op->ptr, "files"))
519                 tot_files = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
520         else
521                 tot_files = 0;
522
523         if (tot_files) {
524                 /* multiple files */
525                 char dir_only[FILE_MAX];
526                 char file_only[FILE_MAX];
527
528                 BLI_split_dir_part(seq_load.path, dir_only, sizeof(dir_only));
529
530                 RNA_BEGIN (op->ptr, itemptr, "files")
531                 {
532                         RNA_string_get(&itemptr, "name", file_only);
533                         BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only);
534
535                         seq = seq_load_func(C, ed->seqbasep, &seq_load);
536                         if (seq) {
537                                 if (overlap == FALSE) {
538                                         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
539                                 }
540                         }
541                 }
542                 RNA_END;
543         }
544         else {
545                 /* single file */
546                 seq = seq_load_func(C, ed->seqbasep, &seq_load);
547                 if (seq) {
548                         if (overlap == FALSE) {
549                                 if (BKE_sequence_test_overlap(ed->seqbasep, seq))
550                                         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
551                         }
552                 }
553         }
554
555         if (seq_load.tot_success == 0) {
556                 BKE_reportf(op->reports, RPT_ERROR, "File \"%s\" could not be loaded", seq_load.path);
557                 return OPERATOR_CANCELLED;
558         }
559
560         BKE_sequencer_sort(scene);
561         BKE_sequencer_update_muting(ed);
562
563         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
564
565         return OPERATOR_FINISHED;
566 }
567
568 /* add movie operator */
569 static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
570 {
571         return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_movie_strip);
572 }
573
574
575 static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
576 {
577
578         if (!ED_operator_sequencer_active(C)) {
579                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
580                 return OPERATOR_CANCELLED;
581         }
582
583         /* This is for drag and drop */
584         if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
585             RNA_struct_property_is_set(op->ptr, "filepath"))
586         {
587                 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS);
588                 return sequencer_add_movie_strip_exec(C, op);
589         }
590         
591         sequencer_generic_invoke_xy__internal(C, op, event, 0);
592         
593         WM_event_add_fileselect(C, op);
594         return OPERATOR_RUNNING_MODAL;
595
596         //return sequencer_add_movie_strip_exec(C, op);
597 }
598
599
600 void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
601 {
602         
603         /* identifiers */
604         ot->name = "Add Movie Strip";
605         ot->idname = "SEQUENCER_OT_movie_strip_add";
606         ot->description = "Add a movie strip to the sequencer";
607
608         /* api callbacks */
609         ot->invoke = sequencer_add_movie_strip_invoke;
610         ot->exec = sequencer_add_movie_strip_exec;
611
612         ot->poll = ED_operator_scene_editable;
613         
614         /* flags */
615         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
616         
617         WM_operator_properties_filesel(ot, FOLDERFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
618                                        WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
619         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
620         RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie");
621 }
622
623 /* add sound operator */
624
625 static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
626 {
627         return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_sound_strip);
628 }
629
630 static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
631 {
632
633         if (!ED_operator_sequencer_active(C)) {
634                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
635                 return OPERATOR_CANCELLED;
636         }
637         
638         /* This is for drag and drop */
639         if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
640             RNA_struct_property_is_set(op->ptr, "filepath"))
641         {
642                 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_NOPATHS);
643                 return sequencer_add_sound_strip_exec(C, op);
644         }
645         
646         sequencer_generic_invoke_xy__internal(C, op, event, 0);
647
648         WM_event_add_fileselect(C, op);
649         return OPERATOR_RUNNING_MODAL;
650
651         //return sequencer_add_sound_strip_exec(C, op);
652 }
653
654
655 void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
656 {
657         
658         /* identifiers */
659         ot->name = "Add Sound Strip";
660         ot->idname = "SEQUENCER_OT_sound_strip_add";
661         ot->description = "Add a sound strip to the sequencer";
662
663         /* api callbacks */
664         ot->invoke = sequencer_add_sound_strip_invoke;
665         ot->exec = sequencer_add_sound_strip_exec;
666
667         ot->poll = ED_operator_scene_editable;
668         
669         /* flags */
670         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
671         
672         WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE,
673                                        WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
674         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
675         RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory");
676 }
677
678 /* add image operator */
679 static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
680 {
681         /* cant use the generic function for this */
682
683         Scene *scene = CTX_data_scene(C); /* only for sound */
684         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
685         SeqLoadInfo seq_load;
686         Sequence *seq;
687
688         Strip *strip;
689         StripElem *se;
690
691         seq_load_operator_info(&seq_load, op);
692
693         /* images are unique in how they handle this - 1 per strip elem */
694         seq_load.len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
695
696         if (seq_load.len == 0)
697                 return OPERATOR_CANCELLED;
698
699         if (seq_load.flag & SEQ_LOAD_REPLACE_SEL)
700                 ED_sequencer_deselect_all(scene);
701
702
703         /* main adding function */
704         seq = BKE_sequencer_add_image_strip(C, ed->seqbasep, &seq_load);
705         strip = seq->strip;
706         se = strip->stripdata;
707
708         RNA_BEGIN (op->ptr, itemptr, "files")
709         {
710                 char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
711                 BLI_strncpy(se->name, filename, sizeof(se->name));
712                 MEM_freeN(filename);
713                 se++;
714         }
715         RNA_END;
716
717         if (seq_load.len == 1) {
718                 if (seq_load.start_frame < seq_load.end_frame) {
719                         seq->endstill = seq_load.end_frame - seq_load.start_frame;
720                 }
721         }
722         
723         BKE_sequence_calc_disp(scene, seq);
724
725         BKE_sequencer_sort(scene);
726
727         /* last active name */
728         strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR - 1);
729
730         if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
731                 if (BKE_sequence_test_overlap(ed->seqbasep, seq))
732                         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
733         }
734
735         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
736
737         return OPERATOR_FINISHED;
738 }
739
740 static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
741 {
742
743         if (!ED_operator_sequencer_active(C)) {
744                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
745                 return OPERATOR_CANCELLED;
746         }
747
748
749         /* drag drop has set the names */
750         if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
751                 sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME | SEQPROP_NOPATHS);
752                 return sequencer_add_image_strip_exec(C, op);
753         }
754         
755         sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME);
756
757         WM_event_add_fileselect(C, op);
758         return OPERATOR_RUNNING_MODAL;
759 }
760
761
762 void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
763 {
764         
765         /* identifiers */
766         ot->name = "Add Image Strip";
767         ot->idname = "SEQUENCER_OT_image_strip_add";
768         ot->description = "Add an image or image sequence to the sequencer";
769
770         /* api callbacks */
771         ot->invoke = sequencer_add_image_strip_invoke;
772         ot->exec = sequencer_add_image_strip_exec;
773
774         ot->poll = ED_operator_scene_editable;
775         
776         /* flags */
777         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
778         
779         WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE,
780                                        WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
781         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
782 }
783
784
785 /* add_effect_strip operator */
786 static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
787 {
788         Scene *scene = CTX_data_scene(C);
789         Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
790
791         Sequence *seq;  /* generic strip vars */
792         Strip *strip;
793         struct SeqEffectHandle sh;
794
795         int start_frame, end_frame, channel, type; /* operator props */
796         
797         Sequence *seq1, *seq2, *seq3;
798         const char *error_msg;
799
800         start_frame = RNA_int_get(op->ptr, "frame_start");
801         end_frame = RNA_int_get(op->ptr, "frame_end");
802         channel = RNA_int_get(op->ptr, "channel");
803
804         type = RNA_enum_get(op->ptr, "type");
805         
806         // XXX move to invoke
807         if (!seq_effect_find_selected(scene, NULL, type, &seq1, &seq2, &seq3, &error_msg)) {
808                 BKE_report(op->reports, RPT_ERROR, error_msg);
809                 return OPERATOR_CANCELLED;
810         }
811
812         /* If seq1 is NULL and no error was raised it means the seq is standalone
813          * (like color strips) and we need to check its start and end frames are valid */
814         if (seq1 == NULL && end_frame <= start_frame) {
815                 BKE_report(op->reports, RPT_ERROR, "Start and end frame are not set");
816                 return OPERATOR_CANCELLED;
817         }
818
819         seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
820         seq->type = type;
821
822         BLI_strncpy(seq->name + 2, BKE_sequence_give_name(seq), sizeof(seq->name) - 2);
823         BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
824
825         sh = BKE_sequence_get_effect(seq);
826
827         seq->seq1 = seq1;
828         seq->seq2 = seq2;
829         seq->seq3 = seq3;
830
831         sh.init(seq);
832
833         if (!seq1) { /* effect has no deps */
834                 seq->len = 1;
835                 BKE_sequence_tx_set_final_right(seq, end_frame);
836         }
837
838         seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
839
840         BKE_sequence_calc(scene, seq);
841         
842         /* basic defaults */
843         seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
844         strip->us = 1;
845
846         if (seq->type == SEQ_TYPE_COLOR) {
847                 SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
848                 RNA_float_get_array(op->ptr, "color", colvars->col);
849                 seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
850
851         }
852         else if (seq->type == SEQ_TYPE_ADJUSTMENT) {
853                 seq->blend_mode = SEQ_TYPE_CROSS;
854         }
855
856         /* an unset channel is a special case where we automatically go above
857          * the other strips. */
858         if (!RNA_struct_property_is_set(op->ptr, "channel")) {
859                 if (seq->seq1) {
860                         int chan = MAX3(seq->seq1 ? seq->seq1->machine : 0,
861                                         seq->seq2 ? seq->seq2->machine : 0,
862                                         seq->seq3 ? seq->seq3->machine : 0);
863                         if (chan < MAXSEQ)
864                                 seq->machine = chan;
865                 }
866         }
867
868         if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
869                 if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
870         }
871
872         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */
873
874
875         /* not sure if this is needed with update_changed_seq_and_deps.
876          * it was NOT called in blender 2.4x, but wont hurt */
877         BKE_sequencer_sort(scene); 
878
879         if (RNA_boolean_get(op->ptr, "replace_sel")) {
880                 ED_sequencer_deselect_all(scene);
881                 BKE_sequencer_active_set(scene, seq);
882                 seq->flag |= SELECT;
883         }
884
885         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
886
887         return OPERATOR_FINISHED;
888 }
889
890
891 /* add color */
892 static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
893 {
894         short is_type_set = RNA_struct_property_is_set(op->ptr, "type");
895         int type = -1;
896         int prop_flag = SEQPROP_ENDFRAME;
897
898         if (!ED_operator_sequencer_active(C)) {
899                 BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
900                 return OPERATOR_CANCELLED;
901         }
902
903         if (is_type_set) {
904                 type = RNA_enum_get(op->ptr, "type");
905
906                 /* when invoking an effect strip which uses inputs,
907                  * skip initializing the channel from the mouse.
908                  * Instead leave the property unset so exec() initializes it to be
909                  * above the strips its applied to. */
910                 if (BKE_sequence_effect_get_num_inputs(type) != 0) {
911                         prop_flag |= SEQPROP_NOCHAN;
912                 }
913         }
914
915         sequencer_generic_invoke_xy__internal(C, op, event, prop_flag);
916
917         return sequencer_add_effect_strip_exec(C, op);
918 }
919
920 void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
921 {
922         /* identifiers */
923         ot->name = "Add Effect Strip";
924         ot->idname = "SEQUENCER_OT_effect_strip_add";
925         ot->description = "Add an effect to the sequencer, most are applied on top of existing strips";
926
927         /* api callbacks */
928         ot->invoke = sequencer_add_effect_strip_invoke;
929         ot->exec = sequencer_add_effect_strip_exec;
930
931         ot->poll = ED_operator_scene_editable;
932         
933         /* flags */
934         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
935         
936         WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE,
937                                        WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
938         sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
939         RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type");
940         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);
941 }