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