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