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