Blender  V2.93
sequencer_edit.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "BLI_blenlib.h"
31 #include "BLI_math.h"
32 #include "BLI_timecode.h"
33 #include "BLI_utildefines.h"
34 
35 #include "BLT_translation.h"
36 
37 #include "DNA_scene_types.h"
38 #include "DNA_sound_types.h"
39 
40 #include "BKE_context.h"
41 #include "BKE_global.h"
42 #include "BKE_lib_id.h"
43 #include "BKE_main.h"
44 #include "BKE_report.h"
45 #include "BKE_sound.h"
46 
47 #include "SEQ_add.h"
48 #include "SEQ_clipboard.h"
49 #include "SEQ_edit.h"
50 #include "SEQ_effects.h"
51 #include "SEQ_iterator.h"
52 #include "SEQ_prefetch.h"
53 #include "SEQ_relations.h"
54 #include "SEQ_render.h"
55 #include "SEQ_select.h"
56 #include "SEQ_sequencer.h"
57 #include "SEQ_time.h"
58 #include "SEQ_transform.h"
59 #include "SEQ_utils.h"
60 
61 #include "WM_api.h"
62 #include "WM_types.h"
63 
64 #include "RNA_define.h"
65 
66 /* For menu, popup, icons, etc. */
67 #include "ED_numinput.h"
68 #include "ED_outliner.h"
69 #include "ED_screen.h"
70 #include "ED_sequencer.h"
71 
72 #include "UI_interface.h"
73 #include "UI_resources.h"
74 #include "UI_view2d.h"
75 
76 #include "DEG_depsgraph.h"
77 #include "DEG_depsgraph_build.h"
78 
79 /* Own include. */
80 #include "sequencer_intern.h"
81 
82 /* -------------------------------------------------------------------- */
86 typedef struct TransSeq {
87  int start, machine;
92  /* int final_left, final_right; */ /* UNUSED */
93  int len;
95 
98 /* -------------------------------------------------------------------- */
103 {
105 }
106 
108 {
109  if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
110  return (SEQ_active_mask_get(scene) != NULL);
111  }
112 
113  return false;
114 }
115 
117 {
118  SpaceSeq *sseq = CTX_wm_space_seq(C);
119 
120  if (sseq) {
123  }
124 
125  return false;
126 }
127 
128 /* Are we displaying the seq output (not channels or histogram). */
130 {
133 }
134 
136 {
139 }
140 
143 /* -------------------------------------------------------------------- */
147 /* Operator functions. */
149 {
150  return (SEQ_editing_get(CTX_data_scene(C), false) != NULL);
151 }
152 
153 #if 0 /* UNUSED */
154 bool sequencer_strip_poll(bContext *C)
155 {
156  Editing *ed;
157  return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
158  (ed->act_seq != NULL));
159 }
160 #endif
161 
163 {
164  Editing *ed;
165  Sequence *seq;
166  return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
167  ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
168 }
169 
171 {
172  SpaceSeq *sseq = CTX_wm_space_seq(C);
173  Editing *ed = SEQ_editing_get(CTX_data_scene(C), false);
174  if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF)) {
175  return 1;
176  }
177 
178  return 0;
179 }
180 
182 {
183  SpaceSeq *sseq = CTX_wm_space_seq(C);
184  if (sseq && ED_space_sequencer_check_show_strip(sseq)) {
185  return 1;
186  }
187 
188  return 0;
189 }
190 
193 /* -------------------------------------------------------------------- */
198 {
200  const bool do_all = RNA_boolean_get(op->ptr, "all");
201  const Editing *ed = SEQ_editing_get(scene, false);
202 
203  SEQ_edit_remove_gaps(scene, ed->seqbasep, CFRA, do_all);
204 
207 
208  return OPERATOR_FINISHED;
209 }
210 
212 {
213  /* Identifiers. */
214  ot->name = "Remove Gaps";
215  ot->idname = "SEQUENCER_OT_gap_remove";
216  ot->description =
217  "Remove gap at current frame to first strip at the right, independent of selection or "
218  "locked state of strips";
219 
220  /* Api callbacks. */
221  // ot->invoke = sequencer_snap_invoke;
224 
225  /* Flags. */
227 
228  RNA_def_boolean(ot->srna, "all", 0, "All Gaps", "Do all gaps to right of current frame");
229 }
230 
233 /* -------------------------------------------------------------------- */
238 {
240  const int frames = RNA_int_get(op->ptr, "frames");
241  const Editing *ed = SEQ_editing_get(scene, false);
243 
245 
246  return OPERATOR_FINISHED;
247 }
248 
250 {
251  /* Identifiers. */
252  ot->name = "Insert Gaps";
253  ot->idname = "SEQUENCER_OT_gap_insert";
254  ot->description =
255  "Insert gap at current frame to first strips at the right, independent of selection or "
256  "locked state of strips";
257 
258  /* Api callbacks. */
259  // ot->invoke = sequencer_snap_invoke;
262 
263  /* Flags. */
265 
267  "frames",
268  10,
269  0,
270  INT_MAX,
271  "Frames",
272  "Frames to insert after current strip",
273  0,
274  1000);
275 }
276 
279 /* -------------------------------------------------------------------- */
284 {
286 
287  Editing *ed = SEQ_editing_get(scene, false);
288  Sequence *seq;
289  int snap_frame;
290 
291  snap_frame = RNA_int_get(op->ptr, "frame");
292 
293  /* Check metas. */
294  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
295  if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
297  if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
299  scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start);
300  }
301  else {
302  if (seq->flag & SEQ_LEFTSEL) {
303  SEQ_transform_set_left_handle_frame(seq, snap_frame);
304  }
305  else { /* SEQ_RIGHTSEL */
306  SEQ_transform_set_right_handle_frame(seq, snap_frame);
307  }
310  }
312  }
313  }
314 
315  /* Test for effects and overlap. */
316  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
317  if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
318  seq->flag &= ~SEQ_OVERLAP;
319  if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
321  }
322  }
323  }
324 
325  /* Recalculate bounds of effect strips, offsetting the keyframes if not snapping any handle. */
326  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
327  if (seq->type & SEQ_TYPE_EFFECT) {
328  const bool either_handle_selected = (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) != 0;
329 
330  if (seq->seq1 && (seq->seq1->flag & SELECT)) {
331  if (!either_handle_selected) {
332  SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
333  }
335  }
336  else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
337  if (!either_handle_selected) {
338  SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
339  }
341  }
342  else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
343  if (!either_handle_selected) {
344  SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
345  }
347  }
348  }
349  }
350 
351  SEQ_sort(scene);
352 
355 
356  return OPERATOR_FINISHED;
357 }
358 
359 static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
360 {
362 
363  int snap_frame;
364 
365  snap_frame = CFRA;
366 
367  RNA_int_set(op->ptr, "frame", snap_frame);
368  return sequencer_snap_exec(C, op);
369 }
370 
372 {
373  /* Identifiers. */
374  ot->name = "Snap Strips to the Current Frame";
375  ot->idname = "SEQUENCER_OT_snap";
376  ot->description = "Frame where selected strips will be snapped";
377 
378  /* Api callbacks. */
382 
383  /* Flags. */
385 
387  "frame",
388  0,
389  INT_MIN,
390  INT_MAX,
391  "Frame",
392  "Frame where selected strips will be snapped",
393  INT_MIN,
394  INT_MAX);
395 }
396 
399 /* -------------------------------------------------------------------- */
403 typedef struct SlipData {
404  int init_mouse[2];
405  float init_mouseloc[2];
408  bool *trim;
409  int num_seq;
410  bool slow;
411  int slow_offset; /* Offset at the point where offset was turned on. */
414 
415 static void transseq_backup(TransSeq *ts, Sequence *seq)
416 {
417  ts->start = seq->start;
418  ts->machine = seq->machine;
419  ts->startstill = seq->startstill;
420  ts->endstill = seq->endstill;
421  ts->startdisp = seq->startdisp;
422  ts->enddisp = seq->enddisp;
423  ts->startofs = seq->startofs;
424  ts->endofs = seq->endofs;
425  ts->anim_startofs = seq->anim_startofs;
426  ts->anim_endofs = seq->anim_endofs;
427  ts->len = seq->len;
428 }
429 
430 static void transseq_restore(TransSeq *ts, Sequence *seq)
431 {
432  seq->start = ts->start;
433  seq->machine = ts->machine;
434  seq->startstill = ts->startstill;
435  seq->endstill = ts->endstill;
436  seq->startdisp = ts->startdisp;
437  seq->enddisp = ts->enddisp;
438  seq->startofs = ts->startofs;
439  seq->endofs = ts->endofs;
440  seq->anim_startofs = ts->anim_startofs;
441  seq->anim_endofs = ts->anim_endofs;
442  seq->len = ts->len;
443 }
444 
446  ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
447 {
448  Sequence *seq;
449  int num_items = 0;
450 
451  for (seq = seqbasep->first; seq; seq = seq->next) {
452  if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
453  seq_array[offset + num_items] = seq;
454  trim[offset + num_items] = do_trim && ((seq->type & SEQ_TYPE_EFFECT) == 0);
455  num_items++;
456 
457  if (seq->type == SEQ_TYPE_META) {
458  /* Trim the sub-sequences. */
459  num_items += slip_add_sequences_recursive(
460  &seq->seqbase, seq_array, trim, num_items + offset, false);
461  }
462  }
463  }
464 
465  return num_items;
466 }
467 
468 static int slip_count_sequences_recursive(ListBase *seqbasep, bool first_level)
469 {
470  Sequence *seq;
471  int trimmed_sequences = 0;
472 
473  for (seq = seqbasep->first; seq; seq = seq->next) {
474  if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
475  trimmed_sequences++;
476 
477  if (seq->type == SEQ_TYPE_META) {
478  /* Trim the sub-sequences. */
479  trimmed_sequences += slip_count_sequences_recursive(&seq->seqbase, false);
480  }
481  }
482  }
483 
484  return trimmed_sequences;
485 }
486 
487 static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
488 {
489  SlipData *data;
491  Editing *ed = SEQ_editing_get(scene, false);
492  float mouseloc[2];
493  int num_seq;
495 
496  /* Recursively count the trimmed elements. */
497  num_seq = slip_count_sequences_recursive(ed->seqbasep, true);
498 
499  if (num_seq == 0) {
500  return OPERATOR_CANCELLED;
501  }
502 
503  data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
504  data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
505  data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
506  data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
507  data->num_seq = num_seq;
508 
509  initNumInput(&data->num_input);
510  data->num_input.idx_max = 0;
511  data->num_input.val_flag[0] |= NUM_NO_FRACTION;
512  data->num_input.unit_sys = USER_UNIT_NONE;
513  data->num_input.unit_type[0] = 0;
514 
515  slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
516 
517  for (int i = 0; i < num_seq; i++) {
518  transseq_backup(data->ts + i, data->seq_array[i]);
519  }
520 
521  UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
522 
523  copy_v2_v2_int(data->init_mouse, event->mval);
524  copy_v2_v2(data->init_mouseloc, mouseloc);
525 
526  data->slow = false;
527 
529 
530  /* Notify so we draw extensions immediately. */
532 
533  return OPERATOR_RUNNING_MODAL;
534 }
535 
537 {
538  /* Only data types supported for now. */
539  Editing *ed = SEQ_editing_get(scene, false);
540  bool changed = false;
541 
542  /* Iterate in reverse so meta-strips are iterated after their children. */
543  for (int i = data->num_seq - 1; i >= 0; i--) {
544  Sequence *seq = data->seq_array[i];
545  int endframe;
546 
547  /* Offset seq start. */
548  seq->start = data->ts[i].start + offset;
549 
550  if (data->trim[i]) {
551  /* Find the end-frame. */
552  endframe = seq->start + seq->len;
553 
554  /* Compute the sequence offsets. */
555  if (endframe > seq->enddisp) {
556  seq->endstill = 0;
557  seq->endofs = endframe - seq->enddisp;
558  changed = true;
559  }
560  else if (endframe <= seq->enddisp) {
561  seq->endstill = seq->enddisp - endframe;
562  seq->endofs = 0;
563  changed = true;
564  }
565 
566  if (seq->start > seq->startdisp) {
567  seq->startstill = seq->start - seq->startdisp;
568  seq->startofs = 0;
569  changed = true;
570  }
571  else if (seq->start <= seq->startdisp) {
572  seq->startstill = 0;
573  seq->startofs = seq->startdisp - seq->start;
574  changed = true;
575  }
576  }
577  else {
578  /* No transform data (likely effect strip). Only move start and end. */
579  seq->startdisp = data->ts[i].startdisp + offset;
580  seq->enddisp = data->ts[i].enddisp + offset;
581  changed = true;
582  }
583 
584  /* Effects are only added if we they are in a meta-strip.
585  * In this case, dependent strips will just be transformed and
586  * we can skip calculating for effects.
587  * This way we can avoid an extra loop just for effects. */
588  if (!(seq->type & SEQ_TYPE_EFFECT)) {
590  }
591  }
592  if (changed) {
593  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
594  }
595  return changed;
596 }
597 
598 /* Make sure, that each strip contains at least 1 frame of content. */
599 static void sequencer_slip_apply_limits(SlipData *data, int *offset)
600 {
601  for (int i = 0; i < data->num_seq; i++) {
602  if (data->trim[i]) {
603  Sequence *seq = data->seq_array[i];
604  int seq_content_start = data->ts[i].start + *offset;
605  int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs;
606  int diff = 0;
607 
608  if (seq_content_start >= seq->enddisp) {
609  diff = seq->enddisp - seq_content_start - 1;
610  }
611 
612  if (seq_content_end <= seq->startdisp) {
613  diff = seq->startdisp - seq_content_end + 1;
614  }
615  *offset += diff;
616  }
617  }
618 }
619 
621 {
623  Editing *ed = SEQ_editing_get(scene, false);
624  int offset = RNA_int_get(op->ptr, "offset");
625  bool success = false;
626 
627  /* Recursively count the trimmed elements. */
628  int num_seq = slip_count_sequences_recursive(ed->seqbasep, true);
629 
630  if (num_seq == 0) {
631  return OPERATOR_CANCELLED;
632  }
633 
634  SlipData *data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
635  data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
636  data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
637  data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
638  data->num_seq = num_seq;
639 
640  slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
641 
642  for (int i = 0; i < num_seq; i++) {
643  transseq_backup(data->ts + i, data->seq_array[i]);
644  }
645 
647  success = sequencer_slip_recursively(scene, data, offset);
648 
649  MEM_freeN(data->seq_array);
650  MEM_freeN(data->trim);
651  MEM_freeN(data->ts);
652  MEM_freeN(data);
653 
654  if (success) {
657  return OPERATOR_FINISHED;
658  }
659  return OPERATOR_CANCELLED;
660 }
661 
663 {
664  char msg[UI_MAX_DRAW_STR];
665 
666  if (area) {
667  if (hasNumInput(&data->num_input)) {
668  char num_str[NUM_STR_REP_LEN];
669  outputNumInput(&data->num_input, num_str, &scene->unit);
670  BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %s"), num_str);
671  }
672  else {
673  BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %d"), offset);
674  }
675  }
676 
678 }
679 
680 static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
681 {
682  Main *bmain = CTX_data_main(C);
684  SlipData *data = (SlipData *)op->customdata;
686  const bool has_numInput = hasNumInput(&data->num_input);
687  bool handled = true;
688 
689  /* Modal numinput active, try to handle numeric inputs. */
690  if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) {
691  float offset_fl;
692  applyNumInput(&data->num_input, &offset_fl);
693  int offset = round_fl_to_int(offset_fl);
694 
697 
698  RNA_int_set(op->ptr, "offset", offset);
699 
700  if (sequencer_slip_recursively(scene, data, offset)) {
702  }
703 
704  return OPERATOR_RUNNING_MODAL;
705  }
706 
707  switch (event->type) {
708  case MOUSEMOVE: {
709  if (!has_numInput) {
710  float mouseloc[2];
711  int offset;
712  int mouse_x;
714 
715  if (data->slow) {
716  mouse_x = event->mval[0] - data->slow_offset;
717  mouse_x *= 0.1f;
718  mouse_x += data->slow_offset;
719  }
720  else {
721  mouse_x = event->mval[0];
722  }
723 
724  /* Choose the side based on which side of the current frame the mouse is. */
725  UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
726  offset = mouseloc[0] - data->init_mouseloc[0];
727 
730 
731  RNA_int_set(op->ptr, "offset", offset);
732 
733  if (sequencer_slip_recursively(scene, data, offset)) {
735  }
736  }
737  break;
738  }
739 
740  case LEFTMOUSE:
741  case EVT_RETKEY:
742  case EVT_SPACEKEY: {
743  MEM_freeN(data->seq_array);
744  MEM_freeN(data->trim);
745  MEM_freeN(data->ts);
746  MEM_freeN(data);
747  op->customdata = NULL;
748  if (area) {
750  }
753  return OPERATOR_FINISHED;
754  }
755 
756  case EVT_ESCKEY:
757  case RIGHTMOUSE: {
758  Editing *ed = SEQ_editing_get(scene, false);
759 
760  for (int i = 0; i < data->num_seq; i++) {
761  transseq_restore(data->ts + i, data->seq_array[i]);
762  }
763 
764  for (int i = 0; i < data->num_seq; i++) {
765  Sequence *seq = data->seq_array[i];
766  SEQ_add_reload_new_file(bmain, scene, seq, false);
768  }
769 
770  MEM_freeN(data->seq_array);
771  MEM_freeN(data->ts);
772  MEM_freeN(data->trim);
773  MEM_freeN(data);
774  op->customdata = NULL;
775 
777 
778  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
779 
780  if (area) {
782  }
783 
784  return OPERATOR_CANCELLED;
785  }
786 
787  case EVT_RIGHTSHIFTKEY:
788  case EVT_LEFTSHIFTKEY:
789  if (!has_numInput) {
790  if (event->val == KM_PRESS) {
791  data->slow = true;
792  data->slow_offset = event->mval[0];
793  }
794  else if (event->val == KM_RELEASE) {
795  data->slow = false;
796  }
797  }
798  break;
799 
800  default:
801  handled = false;
802  break;
803  }
804 
805  /* Modal numinput inactive, try to handle numeric inputs. */
806  if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) {
807  float offset_fl;
808  applyNumInput(&data->num_input, &offset_fl);
809  int offset = round_fl_to_int(offset_fl);
810 
813 
814  RNA_int_set(op->ptr, "offset", offset);
815 
816  if (sequencer_slip_recursively(scene, data, offset)) {
818  }
819  }
820 
821  return OPERATOR_RUNNING_MODAL;
822 }
823 
825 {
826  /* Identifiers. */
827  ot->name = "Trim Strips";
828  ot->idname = "SEQUENCER_OT_slip";
829  ot->description = "Trim the contents of the active strip";
830 
831  /* Api callbacks. */
836 
837  /* Flags. */
839 
841  "offset",
842  0,
843  INT32_MIN,
844  INT32_MAX,
845  "Offset",
846  "Offset to the data of the strip",
847  INT32_MIN,
848  INT32_MAX);
849 }
850 
853 /* -------------------------------------------------------------------- */
858 {
860  Editing *ed = SEQ_editing_get(scene, false);
861  Sequence *seq;
862  bool selected;
863 
864  selected = !RNA_boolean_get(op->ptr, "unselected");
865 
866  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
867  if ((seq->flag & SEQ_LOCK) == 0) {
868  if (selected) {
869  if (seq->flag & SELECT) {
870  seq->flag |= SEQ_MUTE;
872  }
873  }
874  else {
875  if ((seq->flag & SELECT) == 0) {
876  seq->flag |= SEQ_MUTE;
878  }
879  }
880  }
881  }
882 
885 
886  return OPERATOR_FINISHED;
887 }
888 
890 {
891  /* Identifiers. */
892  ot->name = "Mute Strips";
893  ot->idname = "SEQUENCER_OT_mute";
894  ot->description = "Mute (un)selected strips";
895 
896  /* Api callbacks. */
899 
900  /* Flags. */
902 
904  ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
905 }
906 
909 /* -------------------------------------------------------------------- */
914 {
916  Editing *ed = SEQ_editing_get(scene, false);
917  Sequence *seq;
918  bool selected;
919 
920  selected = !RNA_boolean_get(op->ptr, "unselected");
921 
922  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
923  if ((seq->flag & SEQ_LOCK) == 0) {
924  if (selected) {
925  if (seq->flag & SELECT) {
926  seq->flag &= ~SEQ_MUTE;
928  }
929  }
930  else {
931  if ((seq->flag & SELECT) == 0) {
932  seq->flag &= ~SEQ_MUTE;
934  }
935  }
936  }
937  }
938 
941 
942  return OPERATOR_FINISHED;
943 }
944 
946 {
947  /* Identifiers. */
948  ot->name = "Unmute Strips";
949  ot->idname = "SEQUENCER_OT_unmute";
950  ot->description = "Unmute (un)selected strips";
951 
952  /* Api callbacks. */
955 
956  /* Flags. */
958 
960  ot->srna, "unselected", 0, "Unselected", "Unmute unselected rather than selected strips");
961 }
962 
965 /* -------------------------------------------------------------------- */
970 {
972  Editing *ed = SEQ_editing_get(scene, false);
973  Sequence *seq;
974 
975  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
976  if (seq->flag & SELECT) {
977  seq->flag |= SEQ_LOCK;
978  }
979  }
980 
982 
983  return OPERATOR_FINISHED;
984 }
985 
987 {
988  /* Identifiers. */
989  ot->name = "Lock Strips";
990  ot->idname = "SEQUENCER_OT_lock";
991  ot->description = "Lock strips so they can't be transformed";
992 
993  /* Api callbacks. */
996 
997  /* Flags. */
999 }
1000 
1003 /* -------------------------------------------------------------------- */
1008 {
1010  Editing *ed = SEQ_editing_get(scene, false);
1011  Sequence *seq;
1012 
1013  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1014  if (seq->flag & SELECT) {
1015  seq->flag &= ~SEQ_LOCK;
1016  }
1017  }
1018 
1020 
1021  return OPERATOR_FINISHED;
1022 }
1023 
1025 {
1026  /* Identifiers. */
1027  ot->name = "Unlock Strips";
1028  ot->idname = "SEQUENCER_OT_unlock";
1029  ot->description = "Unlock strips so they can be transformed";
1030 
1031  /* Api callbacks. */
1034 
1035  /* Flags. */
1037 }
1038 
1041 /* -------------------------------------------------------------------- */
1046 {
1047  Main *bmain = CTX_data_main(C);
1049  Editing *ed = SEQ_editing_get(scene, false);
1050  Sequence *seq;
1051  const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
1052 
1053  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1054  if (seq->flag & SELECT) {
1056  SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length);
1057 
1058  if (adjust_length) {
1059  if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
1061  }
1062  }
1063  }
1064  }
1065 
1067 
1068  return OPERATOR_FINISHED;
1069 }
1070 
1072 {
1073  PropertyRNA *prop;
1074 
1075  /* Identifiers. */
1076  ot->name = "Reload Strips";
1077  ot->idname = "SEQUENCER_OT_reload";
1078  ot->description = "Reload strips in the sequencer";
1079 
1080  /* Api callbacks. */
1083 
1084  /* Flags. */
1085  ot->flag = OPTYPE_REGISTER; /* No undo, the data changed is stored outside 'main'. */
1086 
1087  prop = RNA_def_boolean(ot->srna,
1088  "adjust_length",
1089  0,
1090  "Adjust Length",
1091  "Adjust length of strips to their data length");
1093 }
1094 
1097 /* -------------------------------------------------------------------- */
1102 {
1103  if (G.is_rendering) {
1104  return 0;
1105  }
1106  return sequencer_edit_poll(C);
1107 }
1108 
1110 {
1112  Editing *ed = SEQ_editing_get(scene, false);
1113 
1114  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
1115 
1117 
1118  return OPERATOR_FINISHED;
1119 }
1120 
1122 {
1123  /* Identifiers. */
1124  ot->name = "Refresh Sequencer";
1125  ot->idname = "SEQUENCER_OT_refresh_all";
1126  ot->description = "Refresh the sequencer editor";
1127 
1128  /* Api callbacks. */
1131 }
1132 
1135 /* -------------------------------------------------------------------- */
1140  Sequence *activeseq,
1141  int type,
1142  Sequence **r_selseq1,
1143  Sequence **r_selseq2,
1144  Sequence **r_selseq3,
1145  const char **r_error_str)
1146 {
1147  Editing *ed = SEQ_editing_get(scene, false);
1148  Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
1149 
1150  *r_error_str = NULL;
1151 
1152  if (!activeseq) {
1153  seq2 = SEQ_select_active_get(scene);
1154  }
1155 
1156  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1157  if (seq->flag & SELECT) {
1158  if (seq->type == SEQ_TYPE_SOUND_RAM && SEQ_effect_get_num_inputs(type) != 0) {
1159  *r_error_str = N_("Cannot apply effects to audio sequence strips");
1160  return 0;
1161  }
1162  if (!ELEM(seq, activeseq, seq2)) {
1163  if (seq2 == NULL) {
1164  seq2 = seq;
1165  }
1166  else if (seq1 == NULL) {
1167  seq1 = seq;
1168  }
1169  else if (seq3 == NULL) {
1170  seq3 = seq;
1171  }
1172  else {
1173  *r_error_str = N_("Cannot apply effect to more than 3 sequence strips");
1174  return 0;
1175  }
1176  }
1177  }
1178  }
1179 
1180  /* Make sequence selection a little bit more intuitive
1181  * for 3 strips: the last-strip should be seq3. */
1182  if (seq3 != NULL && seq2 != NULL) {
1183  Sequence *tmp = seq2;
1184  seq2 = seq3;
1185  seq3 = tmp;
1186  }
1187 
1188  switch (SEQ_effect_get_num_inputs(type)) {
1189  case 0:
1190  *r_selseq1 = *r_selseq2 = *r_selseq3 = NULL;
1191  return 1; /* Success. */
1192  case 1:
1193  if (seq2 == NULL) {
1194  *r_error_str = N_("At least one selected sequence strip is needed");
1195  return 0;
1196  }
1197  if (seq1 == NULL) {
1198  seq1 = seq2;
1199  }
1200  if (seq3 == NULL) {
1201  seq3 = seq2;
1202  }
1204  case 2:
1205  if (seq1 == NULL || seq2 == NULL) {
1206  *r_error_str = N_("2 selected sequence strips are needed");
1207  return 0;
1208  }
1209  if (seq3 == NULL) {
1210  seq3 = seq2;
1211  }
1212  break;
1213  }
1214 
1215  if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
1216  *r_error_str = N_("TODO: in what cases does this happen?");
1217  return 0;
1218  }
1219 
1220  *r_selseq1 = seq1;
1221  *r_selseq2 = seq2;
1222  *r_selseq3 = seq3;
1223 
1224  /* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */
1225  if (SEQ_effect_get_num_inputs(type) < 3) {
1226  *r_selseq3 = NULL;
1227  }
1228  if (SEQ_effect_get_num_inputs(type) < 2) {
1229  *r_selseq2 = NULL;
1230  }
1231 
1232  return 1;
1233 }
1234 
1236 {
1238  Sequence *seq1, *seq2, *seq3, *last_seq = SEQ_select_active_get(scene);
1239  const char *error_msg;
1240 
1241  if (SEQ_effect_get_num_inputs(last_seq->type) == 0) {
1242  BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs");
1243  return OPERATOR_CANCELLED;
1244  }
1245 
1247  scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) ||
1248  SEQ_effect_get_num_inputs(last_seq->type) == 0) {
1249  BKE_report(op->reports, RPT_ERROR, error_msg);
1250  return OPERATOR_CANCELLED;
1251  }
1252  /* Check if reassigning would create recursivity. */
1253  if (SEQ_relations_render_loop_check(seq1, last_seq) ||
1254  SEQ_relations_render_loop_check(seq2, last_seq) ||
1255  SEQ_relations_render_loop_check(seq3, last_seq)) {
1256  BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected");
1257  return OPERATOR_CANCELLED;
1258  }
1259 
1260  last_seq->seq1 = seq1;
1261  last_seq->seq2 = seq2;
1262  last_seq->seq3 = seq3;
1263 
1264  int old_start = last_seq->start;
1266  SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start));
1267 
1269 
1270  return OPERATOR_FINISHED;
1271 }
1272 
1274 {
1276  Editing *ed = SEQ_editing_get(scene, false);
1277 
1278  if (ed) {
1279  Sequence *last_seq = SEQ_select_active_get(scene);
1280  if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) {
1281  return 1;
1282  }
1283  }
1284 
1285  return 0;
1286 }
1287 
1289 {
1290  /* Identifiers. */
1291  ot->name = "Reassign Inputs";
1292  ot->idname = "SEQUENCER_OT_reassign_inputs";
1293  ot->description = "Reassign the inputs for the effect strip";
1294 
1295  /* Api callbacks. */
1298 
1299  /* Flags. */
1301 }
1302 
1305 /* -------------------------------------------------------------------- */
1310 {
1312  Sequence *seq, *last_seq = SEQ_select_active_get(scene);
1313 
1314  if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) {
1315  BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap");
1316  return OPERATOR_CANCELLED;
1317  }
1318 
1319  seq = last_seq->seq1;
1320  last_seq->seq1 = last_seq->seq2;
1321  last_seq->seq2 = seq;
1322 
1324 
1326 
1327  return OPERATOR_FINISHED;
1328 }
1330 {
1331  /* Identifiers. */
1332  ot->name = "Swap Inputs";
1333  ot->idname = "SEQUENCER_OT_swap_inputs";
1334  ot->description = "Swap the first two inputs for the effect strip";
1335 
1336  /* Api callbacks. */
1339 
1340  /* Flags. */
1342 }
1343 
1346 /* -------------------------------------------------------------------- */
1350 static int mouse_frame_side(View2D *v2d, short mouse_x, int frame)
1351 {
1352  int mval[2];
1353  float mouseloc[2];
1354 
1355  mval[0] = mouse_x;
1356  mval[1] = 0;
1357 
1358  /* Choose the side based on which side of the current frame the mouse is on. */
1359  UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseloc[0], &mouseloc[1]);
1360 
1361  return mouseloc[0] > frame ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT;
1362 }
1363 
1365  {SEQ_SPLIT_SOFT, "SOFT", 0, "Soft", ""},
1366  {SEQ_SPLIT_HARD, "HARD", 0, "Hard", ""},
1367  {0, NULL, 0, NULL, NULL},
1368 };
1369 
1371  {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse Position", ""},
1372  {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
1373  {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
1374  {SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""},
1375  {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""},
1376  {0, NULL, 0, NULL, NULL},
1377 };
1378 
1380 {
1381  Main *bmain = CTX_data_main(C);
1383  Editing *ed = SEQ_editing_get(scene, false);
1384  bool changed = false;
1385  bool seq_selected = false;
1386 
1387  const int split_frame = RNA_int_get(op->ptr, "frame");
1388  const int split_channel = RNA_int_get(op->ptr, "channel");
1389  const bool use_cursor_position = RNA_boolean_get(op->ptr, "use_cursor_position");
1390  const eSeqSplitMethod method = RNA_enum_get(op->ptr, "type");
1391  const int split_side = RNA_enum_get(op->ptr, "side");
1392  const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection");
1393 
1395 
1396  LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
1397  seq->tmp = NULL;
1398  }
1399 
1401  if (use_cursor_position && seq->machine != split_channel) {
1402  continue;
1403  }
1404 
1405  if (ignore_selection || seq->flag & SELECT) {
1406  if (SEQ_edit_strip_split(bmain, scene, ed->seqbasep, seq, split_frame, method) != NULL) {
1407  changed = true;
1408  }
1409  }
1410  }
1411 
1412  if (changed) { /* Got new strips? */
1413  if (ignore_selection) {
1414  if (use_cursor_position) {
1416  if (seq->enddisp == split_frame && seq->machine == split_channel) {
1417  seq_selected = seq->flag & SEQ_ALLSEL;
1418  }
1419  }
1420  if (!seq_selected) {
1422  if (seq->startdisp == split_frame && seq->machine == split_channel) {
1423  seq->flag &= ~SEQ_ALLSEL;
1424  }
1425  }
1426  }
1427  }
1428  }
1429  else {
1430  if (split_side != SEQ_SIDE_BOTH) {
1432  if (split_side == SEQ_SIDE_LEFT) {
1433  if (seq->startdisp >= split_frame) {
1434  seq->flag &= ~SEQ_ALLSEL;
1435  }
1436  }
1437  else {
1438  if (seq->enddisp <= split_frame) {
1439  seq->flag &= ~SEQ_ALLSEL;
1440  }
1441  }
1442  }
1443  }
1444  }
1445 
1446  SEQ_sort(scene);
1447  }
1448  if (changed) {
1450  return OPERATOR_FINISHED;
1451  }
1452 
1453  /* Passthrough to selection if used as tool. */
1455 }
1456 
1457 static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1458 {
1460  View2D *v2d = UI_view2d_fromcontext(C);
1461 
1462  int split_side = RNA_enum_get(op->ptr, "side");
1463  int split_frame = CFRA;
1464 
1465  if (split_side == SEQ_SIDE_MOUSE) {
1466  if (ED_operator_sequencer_active(C) && v2d) {
1467  split_side = mouse_frame_side(v2d, event->mval[0], split_frame);
1468  }
1469  else {
1470  split_side = SEQ_SIDE_BOTH;
1471  }
1472  }
1473  float mouseloc[2];
1474  UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
1475  if (RNA_boolean_get(op->ptr, "use_cursor_position")) {
1476  RNA_int_set(op->ptr, "frame", mouseloc[0]);
1477  }
1478  else {
1479  RNA_int_set(op->ptr, "frame", split_frame);
1480  }
1481  RNA_int_set(op->ptr, "channel", mouseloc[1]);
1482  RNA_enum_set(op->ptr, "side", split_side);
1483  /*RNA_enum_set(op->ptr, "type", split_hard); */
1484 
1485  return sequencer_split_exec(C, op);
1486 }
1487 
1489 {
1490  uiLayout *layout = op->layout;
1492  uiLayoutSetPropSep(layout, true);
1493  uiLayoutSetPropDecorate(layout, false);
1494 
1495  PointerRNA ptr;
1496  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
1497 
1498  uiLayout *row = uiLayoutRow(layout, false);
1499  uiItemR(row, &ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1500  uiItemR(layout, &ptr, "frame", 0, NULL, ICON_NONE);
1501  uiItemR(layout, &ptr, "side", 0, NULL, ICON_NONE);
1502 
1503  uiItemS(layout);
1504 
1505  uiItemR(layout, &ptr, "use_cursor_position", 0, NULL, ICON_NONE);
1506  if (RNA_boolean_get(&ptr, "use_cursor_position")) {
1507  uiItemR(layout, &ptr, "channel", 0, NULL, ICON_NONE);
1508  }
1509 }
1510 
1512 {
1513  /* Identifiers. */
1514  ot->name = "Split Strips";
1515  ot->idname = "SEQUENCER_OT_split";
1516  ot->description = "Split the selected strips in two";
1517 
1518  /* Api callbacks. */
1523 
1524  /* Flags. */
1526 
1527  PropertyRNA *prop;
1528  RNA_def_int(ot->srna,
1529  "frame",
1530  0,
1531  INT_MIN,
1532  INT_MAX,
1533  "Frame",
1534  "Frame where selected strips will be split",
1535  INT_MIN,
1536  INT_MAX);
1537  RNA_def_int(ot->srna,
1538  "channel",
1539  0,
1540  INT_MIN,
1541  INT_MAX,
1542  "Channel",
1543  "Channel in which strip will be cut",
1544  INT_MIN,
1545  INT_MAX);
1546  RNA_def_enum(ot->srna,
1547  "type",
1550  "Type",
1551  "The type of split operation to perform on strips");
1552 
1554  "use_cursor_position",
1555  0,
1556  "Use Cursor Position",
1557  "Split at position of the cursor instead of current frame");
1558 
1559  prop = RNA_def_enum(ot->srna,
1560  "side",
1563  "Side",
1564  "The side that remains selected after splitting");
1565 
1567 
1568  prop = RNA_def_boolean(
1569  ot->srna,
1570  "ignore_selection",
1571  false,
1572  "Ignore Selection",
1573  "Make cut event if strip is not selected preserving selection state after cut");
1574 
1576 }
1577 
1580 /* -------------------------------------------------------------------- */
1584 static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
1585 {
1586  Scene *scene = (Scene *)arg_pt;
1587  char name[sizeof(seq->name) - 2];
1588 
1589  BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
1591  SEQ_dupe_animdata(scene, name, seq->name + 2);
1592  return 1;
1593 }
1594 
1596 {
1598  Editing *ed = SEQ_editing_get(scene, false);
1599 
1600  ListBase nseqbase = {NULL, NULL};
1601 
1602  if (ed == NULL) {
1603  return OPERATOR_CANCELLED;
1604  }
1605 
1607 
1608  if (nseqbase.first) {
1609  Sequence *seq = nseqbase.first;
1610  /* Rely on the nseqbase list being added at the end.
1611  * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */
1612  BLI_movelisttolist(ed->seqbasep, &nseqbase);
1613 
1614  for (; seq; seq = seq->next) {
1616  }
1617 
1619  return OPERATOR_FINISHED;
1620  }
1621 
1622  return OPERATOR_CANCELLED;
1623 }
1624 
1626 {
1627  /* Identifiers. */
1628  ot->name = "Duplicate Strips";
1629  ot->idname = "SEQUENCER_OT_duplicate";
1630  ot->description = "Duplicate the selected strips";
1631 
1632  /* Api callbacks. */
1635 
1636  /* Flags. */
1638 }
1639 
1642 /* -------------------------------------------------------------------- */
1647 {
1648  Main *bmain = CTX_data_main(C);
1650  Editing *ed = SEQ_editing_get(scene, false);
1651 
1653 
1655  if (seq->flag & SELECT) {
1657  }
1658  }
1660 
1662  DEG_relations_tag_update(bmain);
1664  return OPERATOR_FINISHED;
1665 }
1666 
1667 static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1668 {
1669  ARegion *region = CTX_wm_region(C);
1670 
1671  if (region->regiontype == RGN_TYPE_WINDOW) {
1672  /* Bounding box of 30 pixels is used for markers shortcuts,
1673  * prevent conflict with markers shortcuts here.
1674  */
1675  if (event->mval[1] <= 30) {
1676  return OPERATOR_PASS_THROUGH;
1677  }
1678  }
1679 
1680  return sequencer_delete_exec(C, op);
1681 }
1682 
1684 {
1685 
1686  /* Identifiers. */
1687  ot->name = "Erase Strips";
1688  ot->idname = "SEQUENCER_OT_delete";
1689  ot->description = "Erase selected strips from the sequencer";
1690 
1691  /* Api callbacks. */
1695 
1696  /* Flags. */
1698 }
1699 
1702 /* -------------------------------------------------------------------- */
1707 {
1709  Editing *ed = SEQ_editing_get(scene, false);
1710  Sequence *seq;
1711 
1712  /* For effects, try to find a replacement input. */
1713  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1714  if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1715  seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
1716  }
1717  }
1718 
1719  /* Update lengths, etc. */
1720  seq = ed->seqbasep->first;
1721  while (seq) {
1723  seq = seq->next;
1724  }
1725 
1726  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1727  if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1728  if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
1730  }
1731  }
1732  }
1733 
1735 
1736  return OPERATOR_FINISHED;
1737 }
1738 
1740 {
1741 
1742  /* Identifiers. */
1743  ot->name = "Clear Strip Offset";
1744  ot->idname = "SEQUENCER_OT_offset_clear";
1745  ot->description = "Clear strip offsets from the start and end frames";
1746 
1747  /* Api callbacks. */
1750 
1751  /* Flags. */
1753 }
1754 
1757 /* -------------------------------------------------------------------- */
1762 {
1764  Editing *ed = SEQ_editing_get(scene, false);
1765 
1766  Sequence *seq, *seq_new;
1767  Strip *strip_new;
1768  StripElem *se, *se_new;
1769  int start_ofs, timeline_frame, frame_end;
1770  int step = RNA_int_get(op->ptr, "length");
1771 
1772  seq = ed->seqbasep->first; /* Poll checks this is valid. */
1773 
1775 
1776  while (seq) {
1777  if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
1778  Sequence *seq_next;
1779 
1780  /* Remove seq so overlap tests don't conflict,
1781  * see seq_free_sequence below for the real freeing. */
1782  BLI_remlink(ed->seqbasep, seq);
1783  /* if (seq->ipo) id_us_min(&seq->ipo->id); */
1784  /* XXX, remove fcurve and assign to split image strips */
1785 
1786  start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false);
1787  frame_end = SEQ_transform_get_right_handle_frame(seq, false);
1788 
1789  while (timeline_frame < frame_end) {
1790  /* New seq. */
1791  se = SEQ_render_give_stripelem(seq, timeline_frame);
1792 
1793  seq_new = SEQ_sequence_dupli_recursive(
1795 
1796  seq_new->start = start_ofs;
1797  seq_new->type = SEQ_TYPE_IMAGE;
1798  seq_new->len = 1;
1799  seq_new->endstill = step - 1;
1800 
1801  /* New strip. */
1802  strip_new = seq_new->strip;
1803  strip_new->us = 1;
1804 
1805  /* New stripdata, only one element now. */
1806  /* Note this assume all elements (images) have the same dimension,
1807  * since we only copy the name here. */
1808  se_new = MEM_reallocN(strip_new->stripdata, sizeof(*se_new));
1809  BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
1810  strip_new->stripdata = se_new;
1811 
1812  SEQ_time_update_sequence(scene, seq_new);
1813 
1814  if (step > 1) {
1815  seq_new->flag &= ~SEQ_OVERLAP;
1816  if (SEQ_transform_test_overlap(ed->seqbasep, seq_new)) {
1818  }
1819  }
1820 
1821  /* XXX, COPY FCURVES */
1822 
1823  timeline_frame++;
1824  start_ofs += step;
1825  }
1826 
1827  seq_next = seq->next;
1828  SEQ_sequence_free(scene, seq, true);
1829  seq = seq_next;
1830  }
1831  else {
1832  seq = seq->next;
1833  }
1834  }
1835 
1836  SEQ_sort(scene);
1837 
1839 
1840  return OPERATOR_FINISHED;
1841 }
1842 
1844 {
1845  /* Identifiers. */
1846  ot->name = "Separate Images";
1847  ot->idname = "SEQUENCER_OT_images_separate";
1848  ot->description = "On image sequence strips, it returns a strip for each image";
1849 
1850  /* Api callbacks. */
1854 
1855  /* Flags. */
1857 
1858  RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
1859 }
1860 
1863 /* -------------------------------------------------------------------- */
1868 {
1870  Editing *ed = SEQ_editing_get(scene, false);
1871  Sequence *active_seq = SEQ_select_active_get(scene);
1872 
1873  if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) {
1874  /* Enter metastrip. */
1875  SEQ_meta_stack_alloc(ed, active_seq);
1876  SEQ_seqbase_active_set(ed, &active_seq->seqbase);
1878  }
1879  else {
1880  /* Exit metastrip if possible. */
1881  if (BLI_listbase_is_empty(&ed->metastack)) {
1882  return OPERATOR_CANCELLED;
1883  }
1884 
1888  SEQ_meta_stack_free(ed, ms);
1889  }
1890 
1893 
1894  return OPERATOR_FINISHED;
1895 }
1896 
1898 {
1899  /* Identifiers. */
1900  ot->name = "Toggle Meta Strip";
1901  ot->idname = "SEQUENCER_OT_meta_toggle";
1902  ot->description = "Toggle a metastrip (to edit enclosed strips)";
1903 
1904  /* Api callbacks. */
1907 
1908  /* Flags. */
1910 }
1911 
1914 /* -------------------------------------------------------------------- */
1919 {
1921  Editing *ed = SEQ_editing_get(scene, false);
1922  Sequence *active_seq = SEQ_select_active_get(scene);
1923  ListBase *active_seqbase = SEQ_active_seqbase_get(ed);
1924 
1925  if (SEQ_transform_seqbase_isolated_sel_check(active_seqbase) == false) {
1926  BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
1927  return OPERATOR_CANCELLED;
1928  }
1929 
1931 
1932  int channel_max = 1, meta_start_frame = MAXFRAME, meta_end_frame = MINFRAME;
1933  Sequence *seqm = SEQ_sequence_alloc(active_seqbase, 1, 1, SEQ_TYPE_META);
1934 
1935  /* Remove all selected from main list, and put in meta.
1936  * Sequence is moved within the same edit, no need to re-generate the UUID. */
1937  LISTBASE_FOREACH_MUTABLE (Sequence *, seq, active_seqbase) {
1938  if (seq != seqm && seq->flag & SELECT) {
1939  BLI_remlink(active_seqbase, seq);
1940  BLI_addtail(&seqm->seqbase, seq);
1942  channel_max = max_ii(seq->machine, channel_max);
1943  meta_start_frame = min_ii(seq->startdisp, meta_start_frame);
1944  meta_end_frame = max_ii(seq->enddisp, meta_end_frame);
1945  }
1946  }
1947 
1948  seqm->machine = active_seq ? active_seq->machine : channel_max;
1949  strcpy(seqm->name + 2, "MetaStrip");
1951  seqm->start = meta_start_frame;
1952  seqm->len = meta_end_frame - meta_start_frame;
1955  if (SEQ_transform_test_overlap(active_seqbase, seqm)) {
1956  SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene);
1957  }
1958 
1961 
1962  return OPERATOR_FINISHED;
1963 }
1964 
1966 {
1967  /* Identifiers. */
1968  ot->name = "Make Meta Strip";
1969  ot->idname = "SEQUENCER_OT_meta_make";
1970  ot->description = "Group selected strips into a metastrip";
1971 
1972  /* Api callbacks. */
1975 
1976  /* Flags. */
1978 }
1979 
1982 /* -------------------------------------------------------------------- */
1987 {
1989  Editing *ed = SEQ_editing_get(scene, false);
1990  Sequence *active_seq = SEQ_select_active_get(scene);
1991 
1992  if (active_seq == NULL || active_seq->type != SEQ_TYPE_META) {
1993  return OPERATOR_CANCELLED;
1994  }
1995 
1997 
1998  LISTBASE_FOREACH (Sequence *, seq, &active_seq->seqbase) {
2000  }
2001 
2002  /* Remove all selected from meta, and put in main list.
2003  * Sequence is moved within the same edit, no need to re-generate the UUID. */
2004  BLI_movelisttolist(ed->seqbasep, &active_seq->seqbase);
2005  BLI_listbase_clear(&active_seq->seqbase);
2006 
2007  ListBase *active_seqbase = SEQ_active_seqbase_get(ed);
2008  SEQ_edit_flag_for_removal(scene, active_seqbase, active_seq);
2009  SEQ_edit_remove_flagged_sequences(scene, active_seqbase);
2010 
2011  /* Test for effects and overlap. */
2012  LISTBASE_FOREACH (Sequence *, seq, active_seqbase) {
2013  if (seq->flag & SELECT) {
2014  seq->flag &= ~SEQ_OVERLAP;
2015  if (SEQ_transform_test_overlap(active_seqbase, seq)) {
2016  SEQ_transform_seqbase_shuffle(active_seqbase, seq, scene);
2017  }
2018  }
2019  }
2020 
2021  SEQ_sort(scene);
2024 
2025  return OPERATOR_FINISHED;
2026 }
2027 
2029 {
2030  /* Identifiers. */
2031  ot->name = "UnMeta Strip";
2032  ot->idname = "SEQUENCER_OT_meta_separate";
2033  ot->description = "Put the contents of a metastrip back in the sequencer";
2034 
2035  /* Api callbacks. */
2038 
2039  /* Flags. */
2041 }
2042 
2045 /* -------------------------------------------------------------------- */
2050  const short side,
2051  const bool do_skip_mute,
2052  const bool do_center)
2053 {
2054  bool changed = false;
2055  int timeline_frame = CFRA;
2056  int next_frame = SEQ_time_find_next_prev_edit(
2057  scene, timeline_frame, side, do_skip_mute, do_center, false);
2058 
2059  if (next_frame != timeline_frame) {
2060  CFRA = next_frame;
2061  changed = true;
2062  }
2063 
2064  return changed;
2065 }
2066 
2068 {
2069  /* Prevent changes during render. */
2070  if (G.is_rendering) {
2071  return 0;
2072  }
2073 
2074  return sequencer_edit_poll(C);
2075 }
2076 
2078 {
2080  const bool next = RNA_boolean_get(op->ptr, "next");
2081  const bool center = RNA_boolean_get(op->ptr, "center");
2082 
2083  /* Currently do_skip_mute is always true. */
2085  return OPERATOR_CANCELLED;
2086  }
2087 
2089 
2090  return OPERATOR_FINISHED;
2091 }
2092 
2094 {
2095  /* Identifiers. */
2096  ot->name = "Jump to Strip";
2097  ot->idname = "SEQUENCER_OT_strip_jump";
2098  ot->description = "Move frame to previous edit point";
2099 
2100  /* Api callbacks. */
2103 
2104  /* Flags. */
2105  ot->flag = OPTYPE_UNDO;
2106 
2107  /* Properties. */
2108  RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
2109  RNA_def_boolean(ot->srna, "center", true, "Use Strip Center", "");
2110 }
2111 
2114 /* -------------------------------------------------------------------- */
2119  {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
2120  {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
2121  {0, NULL, 0, NULL, NULL},
2122 };
2123 
2124 static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
2125 {
2126  int gap = seqb->startdisp - seqa->enddisp;
2127  int seq_a_start;
2128  int seq_b_start;
2129 
2130  seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
2131  SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start);
2133 
2134  seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
2135  SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start);
2137 }
2138 
2139 static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel)
2140 {
2141  /* sel: 0==unselected, 1==selected, -1==don't care. */
2142  Sequence *seq, *best_seq = NULL;
2143  Editing *ed = SEQ_editing_get(scene, false);
2144 
2145  int dist, best_dist;
2146  best_dist = MAXFRAME * 2;
2147 
2148  if (ed == NULL) {
2149  return NULL;
2150  }
2151 
2152  seq = ed->seqbasep->first;
2153  while (seq) {
2154  if ((seq != test) && (test->machine == seq->machine) && (test->depth == seq->depth) &&
2155  ((sel == -1) || (sel == (seq->flag & SELECT)))) {
2156  dist = MAXFRAME * 2;
2157 
2158  switch (lr) {
2159  case SEQ_SIDE_LEFT:
2160  if (seq->enddisp <= test->startdisp) {
2161  dist = test->enddisp - seq->startdisp;
2162  }
2163  break;
2164  case SEQ_SIDE_RIGHT:
2165  if (seq->startdisp >= test->enddisp) {
2166  dist = seq->startdisp - test->enddisp;
2167  }
2168  break;
2169  }
2170 
2171  if (dist == 0) {
2172  best_seq = seq;
2173  break;
2174  }
2175  if (dist < best_dist) {
2176  best_dist = dist;
2177  best_seq = seq;
2178  }
2179  }
2180  seq = seq->next;
2181  }
2182  return best_seq; /* Can be null. */
2183 }
2184 
2185 static bool seq_is_parent(Sequence *par, Sequence *seq)
2186 {
2187  return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
2188 }
2189 
2191 {
2193  Editing *ed = SEQ_editing_get(scene, false);
2194  Sequence *active_seq = SEQ_select_active_get(scene);
2195  Sequence *seq, *iseq;
2196  int side = RNA_enum_get(op->ptr, "side");
2197 
2198  if (active_seq == NULL) {
2199  return OPERATOR_CANCELLED;
2200  }
2201 
2202  seq = find_next_prev_sequence(scene, active_seq, side, -1);
2203 
2204  if (seq) {
2205 
2206  /* Disallow effect strips. */
2207  if (SEQ_effect_get_num_inputs(seq->type) >= 1 &&
2208  (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) {
2209  return OPERATOR_CANCELLED;
2210  }
2211  if ((SEQ_effect_get_num_inputs(active_seq->type) >= 1) &&
2212  (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) {
2213  return OPERATOR_CANCELLED;
2214  }
2215 
2216  switch (side) {
2217  case SEQ_SIDE_LEFT:
2218  swap_sequence(scene, seq, active_seq);
2219  break;
2220  case SEQ_SIDE_RIGHT:
2221  swap_sequence(scene, active_seq, seq);
2222  break;
2223  }
2224 
2225  /* XXX - Should be a generic function. */
2226  for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2227  if ((iseq->type & SEQ_TYPE_EFFECT) &&
2228  (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2230  }
2231  }
2232 
2233  /* Do this in a new loop since both effects need to be calculated first. */
2234  for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2235  if ((iseq->type & SEQ_TYPE_EFFECT) &&
2236  (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2237  /* This may now overlap. */
2238  if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) {
2240  }
2241  }
2242  }
2243 
2244  SEQ_sort(scene);
2245 
2247 
2248  return OPERATOR_FINISHED;
2249  }
2250 
2251  return OPERATOR_CANCELLED;
2252 }
2253 
2255 {
2256  /* Identifiers. */
2257  ot->name = "Swap Strip";
2258  ot->idname = "SEQUENCER_OT_swap";
2259  ot->description = "Swap active strip with strip to the right or left";
2260 
2261  /* Api callbacks. */
2264 
2265  /* Flags. */
2267 
2268  /* Properties. */
2269  RNA_def_enum(
2270  ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
2271 }
2272 
2275 /* -------------------------------------------------------------------- */
2280 {
2281  int retval = OPERATOR_CANCELLED;
2283  Sequence *active_seq = SEQ_select_active_get(scene);
2284  StripElem *se = NULL;
2285 
2286  if (active_seq == NULL) {
2287  return OPERATOR_CANCELLED;
2288  }
2289 
2290  if (active_seq->strip) {
2291  switch (active_seq->type) {
2292  case SEQ_TYPE_IMAGE:
2293  se = SEQ_render_give_stripelem(active_seq, scene->r.cfra);
2294  break;
2295  case SEQ_TYPE_MOVIE:
2296  se = active_seq->strip->stripdata;
2297  break;
2298  case SEQ_TYPE_SCENE:
2299  case SEQ_TYPE_META:
2300  case SEQ_TYPE_SOUND_RAM:
2301  case SEQ_TYPE_SOUND_HD:
2302  default:
2303  break;
2304  }
2305  }
2306 
2307  if (se) {
2308  /* Prevent setting the render size if sequence values aren't initialized. */
2309  if ((se->orig_width > 0) && (se->orig_height > 0)) {
2310  scene->r.xsch = se->orig_width;
2311  scene->r.ysch = se->orig_height;
2313  retval = OPERATOR_FINISHED;
2314  }
2315  }
2316 
2317  return retval;
2318 }
2319 
2321 {
2322  /* Identifiers. */
2323  ot->name = "Set Render Size";
2324  ot->idname = "SEQUENCER_OT_rendersize";
2325  ot->description = "Set render size and aspect from active sequence";
2326 
2327  /* Api callbacks. */
2330 
2331  /* Flags. */
2333 }
2334 
2337 /* -------------------------------------------------------------------- */
2342 {
2343  if (seq->type == SEQ_TYPE_META) {
2344  Sequence *iseq;
2345  for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
2346  seq_copy_del_sound(scene, iseq);
2347  }
2348  }
2349  else if (seq->scene_sound) {
2351  seq->scene_sound = NULL;
2352  }
2353 }
2354 
2356 {
2357  Main *bmain = CTX_data_main(C);
2359  Editing *ed = SEQ_editing_get(scene, false);
2360 
2362 
2364  BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
2365  return OPERATOR_CANCELLED;
2366  }
2367 
2368  /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since
2369  * nobody can reach them anyway.
2370  * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */
2372  scene,
2374  ed->seqbasep,
2375  0,
2377 
2379 
2380  /* Remove anything that references the current scene. */
2382  seq_copy_del_sound(scene, seq);
2383  }
2384 
2385  /* Replace datablock pointers with copies, to keep things working in case
2386  * data-blocks get deleted or another .blend file is opened. */
2388 
2389  return OPERATOR_FINISHED;
2390 }
2391 
2393 {
2394  /* Identifiers. */
2395  ot->name = "Copy";
2396  ot->idname = "SEQUENCER_OT_copy";
2397  ot->description = "Copy selected strips to clipboard";
2398 
2399  /* Api callbacks. */
2402 
2403  /* Flags. */
2404  ot->flag = OPTYPE_REGISTER;
2405 }
2406 
2409 /* -------------------------------------------------------------------- */
2414 {
2415  Editing *ed = SEQ_editing_get(scene, false);
2416 
2417  if (ed == NULL) {
2418  return;
2419  }
2420 
2422  seq->flag &= ~SEQ_ALLSEL;
2423  }
2424 }
2425 
2427 {
2428  Main *bmain = CTX_data_main(C);
2430  Editing *ed = SEQ_editing_get(scene, true); /* Create if needed. */
2431  ListBase nseqbase = {NULL, NULL};
2432  int ofs;
2433  Sequence *iseq, *iseq_first;
2434 
2436  BKE_report(op->reports, RPT_INFO, "No strips to paste");
2437  return OPERATOR_CANCELLED;
2438  }
2439 
2441  if (RNA_boolean_get(op->ptr, "keep_offset")) {
2443  }
2444  else {
2445  int min_seq_startdisp = INT_MAX;
2447  if (seq->startdisp < min_seq_startdisp) {
2448  min_seq_startdisp = seq->startdisp;
2449  }
2450  }
2451  /* Paste strips after playhead. */
2452  ofs = scene->r.cfra - min_seq_startdisp;
2453  }
2454 
2455  /* Copy strips, temporarily restoring pointers to actual data-blocks. This
2456  * must happen on the clipboard itself, so that copying does user counting
2457  * on the actual data-blocks. */
2461 
2462  iseq_first = nseqbase.first;
2463 
2464  /* NOTE: SEQ_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences
2465  * in the new list. */
2466  BLI_movelisttolist(ed->seqbasep, &nseqbase);
2467 
2468  for (iseq = iseq_first; iseq; iseq = iseq->next) {
2469  /* Make sure, that pasted strips have unique names. */
2471  /* Translate after name has been changed, otherwise this will affect animdata of original
2472  * strip. */
2474  /* Ensure, that pasted strips don't overlap. */
2475  if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) {
2477  }
2478  }
2479 
2481  DEG_relations_tag_update(bmain);
2484 
2485  return OPERATOR_FINISHED;
2486 }
2487 
2489 {
2490  /* Identifiers. */
2491  ot->name = "Paste";
2492  ot->idname = "SEQUENCER_OT_paste";
2493  ot->description = "Paste strips from clipboard";
2494 
2495  /* Api callbacks. */
2498 
2499  /* Flags. */
2501 
2502  /* Properties. */
2503  PropertyRNA *prop = RNA_def_boolean(
2504  ot->srna, "keep_offset", false, "Keep Offset", "Keep strip offset to playhead when pasting");
2506 }
2507 
2510 /* -------------------------------------------------------------------- */
2515 {
2517  Sequence *seq_act;
2518  Sequence *seq_other;
2519  const char *error_msg;
2520 
2521  if (SEQ_select_active_get_pair(scene, &seq_act, &seq_other) == 0) {
2522  BKE_report(op->reports, RPT_ERROR, "Please select two strips");
2523  return OPERATOR_CANCELLED;
2524  }
2525 
2526  if (SEQ_edit_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
2527  BKE_report(op->reports, RPT_ERROR, error_msg);
2528  return OPERATOR_CANCELLED;
2529  }
2530 
2531  if (seq_act->scene_sound) {
2533  }
2534 
2535  if (seq_other->scene_sound) {
2537  }
2538 
2539  seq_act->scene_sound = NULL;
2540  seq_other->scene_sound = NULL;
2541 
2542  SEQ_time_update_sequence(scene, seq_act);
2543  SEQ_time_update_sequence(scene, seq_other);
2544 
2545  if (seq_act->sound) {
2547  }
2548  if (seq_other->sound) {
2550  }
2551 
2554 
2556 
2557  return OPERATOR_FINISHED;
2558 }
2559 
2561 {
2562  /* Identifiers. */
2563  ot->name = "Sequencer Swap Data";
2564  ot->idname = "SEQUENCER_OT_swap_data";
2565  ot->description = "Swap 2 sequencer strips";
2566 
2567  /* Api callbacks. */
2570 
2571  /* Flags. */
2573 }
2574 
2577 /* -------------------------------------------------------------------- */
2582  {0, "A_B", 0, "A -> B", ""},
2583  {1, "B_C", 0, "B -> C", ""},
2584  {2, "A_C", 0, "A -> C", ""},
2585  {0, NULL, 0, NULL, NULL},
2586 };
2587 
2589 {
2591  Editing *ed = SEQ_editing_get(scene, false);
2593 
2594  Sequence **seq_1, **seq_2;
2595 
2596  switch (RNA_enum_get(op->ptr, "swap")) {
2597  case 0:
2598  seq_1 = &seq->seq1;
2599  seq_2 = &seq->seq2;
2600  break;
2601  case 1:
2602  seq_1 = &seq->seq2;
2603  seq_2 = &seq->seq3;
2604  break;
2605  default: /* 2 */
2606  seq_1 = &seq->seq1;
2607  seq_2 = &seq->seq3;
2608  break;
2609  }
2610 
2611  if (*seq_1 == NULL || *seq_2 == NULL) {
2612  BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap");
2613  return OPERATOR_CANCELLED;
2614  }
2615 
2616  SWAP(Sequence *, *seq_1, *seq_2);
2617 
2619 
2620  /* Invalidate cache. */
2621  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
2623 
2624  return OPERATOR_FINISHED;
2625 }
2626 
2628 {
2629  /* Identifiers. */
2630  ot->name = "Change Effect Input";
2631  ot->idname = "SEQUENCER_OT_change_effect_input";
2632 
2633  /* Api callbacks. */
2636 
2637  /* Flags. */
2639 
2640  ot->prop = RNA_def_enum(
2641  ot->srna, "swap", prop_change_effect_input_types, 0, "Swap", "The effect inputs to swap");
2642 }
2643 
2646 /* -------------------------------------------------------------------- */
2651  {SEQ_TYPE_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"},
2652  {SEQ_TYPE_ADD, "ADD", 0, "Add", "Add effect strip type"},
2653  {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"},
2654  {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"},
2655  {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"},
2656  {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"},
2657  {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"},
2658  {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"},
2659  {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"},
2660  {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"},
2661  {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"},
2662  {SEQ_TYPE_COLOR, "COLOR", 0, "Color", "Color effect strip type"},
2663  {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", "Color effect strip type"},
2664  {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""},
2665  {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
2666  {SEQ_TYPE_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", 0, "Gaussian Blur", ""},
2667  {SEQ_TYPE_TEXT, "TEXT", 0, "Text", ""},
2668  {SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""},
2669  {0, NULL, 0, NULL, NULL},
2670 };
2671 
2673 {
2675  Editing *ed = SEQ_editing_get(scene, false);
2677  const int new_type = RNA_enum_get(op->ptr, "type");
2678 
2679  /* Free previous effect and init new effect. */
2680  struct SeqEffectHandle sh;
2681 
2682  if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
2683  return OPERATOR_CANCELLED;
2684  }
2685 
2686  /* Can someone explain the logic behind only allowing to increase this,
2687  * copied from 2.4x - campbell */
2689  BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips");
2690  return OPERATOR_CANCELLED;
2691  }
2692 
2693  sh = SEQ_effect_handle_get(seq);
2694  sh.free(seq, true);
2695 
2696  seq->type = new_type;
2697 
2698  sh = SEQ_effect_handle_get(seq);
2699  sh.init(seq);
2700 
2702  /* Invalidate cache. */
2703  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
2704 
2706 
2707  return OPERATOR_FINISHED;
2708 }
2709 
2711 {
2712  /* Identifiers. */
2713  ot->name = "Change Effect Type";
2714  ot->idname = "SEQUENCER_OT_change_effect_type";
2715 
2716  /* Api callbacks. */
2719 
2720  /* Flags. */
2722 
2723  ot->prop = RNA_def_enum(ot->srna,
2724  "type",
2727  "Type",
2728  "Sequencer effect type");
2729 }
2730 
2733 /* -------------------------------------------------------------------- */
2738 {
2739  Main *bmain = CTX_data_main(C);
2741  Editing *ed = SEQ_editing_get(scene, false);
2743  const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
2744  const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders");
2745  int minext_frameme, numdigits;
2746 
2747  if (seq->type == SEQ_TYPE_IMAGE) {
2748  char directory[FILE_MAX];
2749  int len;
2750  StripElem *se;
2751 
2752  /* Need to find min/max frame for placeholders. */
2753  if (use_placeholders) {
2754  len = sequencer_image_seq_get_minmax_frame(op, seq->sfra, &minext_frameme, &numdigits);
2755  }
2756  else {
2758  }
2759  if (len == 0) {
2760  return OPERATOR_CANCELLED;
2761  }
2762 
2763  RNA_string_get(op->ptr, "directory", directory);
2764  if (is_relative_path) {
2765  /* TODO, shouldn't this already be relative from the filesel?
2766  * (as the 'filepath' is) for now just make relative here,
2767  * but look into changing after 2.60 - campbell */
2768  BLI_path_rel(directory, BKE_main_blendfile_path(bmain));
2769  }
2770  BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir));
2771 
2772  if (seq->strip->stripdata) {
2773  MEM_freeN(seq->strip->stripdata);
2774  }
2775  seq->strip->stripdata = se = MEM_callocN(len * sizeof(StripElem), "stripelem");
2776 
2777  if (use_placeholders) {
2778  sequencer_image_seq_reserve_frames(op, se, len, minext_frameme, numdigits);
2779  }
2780  else {
2781  RNA_BEGIN (op->ptr, itemptr, "files") {
2782  char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
2783  BLI_strncpy(se->name, filename, sizeof(se->name));
2784  MEM_freeN(filename);
2785  se++;
2786  }
2787  RNA_END;
2788  }
2789 
2790  /* Reset these else we wont see all the images. */
2791  seq->anim_startofs = seq->anim_endofs = 0;
2792 
2793  /* Correct start/end frames so we don't move.
2794  * Important not to set seq->len = len; allow the function to handle it. */
2795  SEQ_add_reload_new_file(bmain, scene, seq, true);
2796 
2798 
2799  /* Invalidate cache. */
2800  SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
2801  }
2802  else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
2803  bSound *sound = seq->sound;
2804  if (sound == NULL) {
2805  return OPERATOR_CANCELLED;
2806  }
2807  char filepath[FILE_MAX];
2808  RNA_string_get(op->ptr, "filepath", filepath);
2809  BLI_strncpy(sound->filepath, filepath, sizeof(sound->filepath));
2810  BKE_sound_load(bmain, sound);
2811  }
2812  else {
2813  /* Lame, set rna filepath. */
2814  PointerRNA seq_ptr;
2815  PropertyRNA *prop;
2816  char filepath[FILE_MAX];
2817 
2818  RNA_pointer_create(&scene->id, &RNA_Sequence, seq, &seq_ptr);
2819 
2820  RNA_string_get(op->ptr, "filepath", filepath);
2821  prop = RNA_struct_find_property(&seq_ptr, "filepath");
2822  RNA_property_string_set(&seq_ptr, prop, filepath);
2823  RNA_property_update(C, &seq_ptr, prop);
2824  }
2825 
2827 
2828  return OPERATOR_FINISHED;
2829 }
2830 
2832 {
2835  char filepath[FILE_MAX];
2836 
2837  BLI_join_dirfile(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name);
2838 
2839  RNA_string_set(op->ptr, "directory", seq->strip->dir);
2840  RNA_string_set(op->ptr, "filepath", filepath);
2841 
2842  /* Set default display depending on seq type. */
2843  if (seq->type == SEQ_TYPE_IMAGE) {
2844  RNA_boolean_set(op->ptr, "filter_movie", false);
2845  }
2846  else {
2847  RNA_boolean_set(op->ptr, "filter_image", false);
2848  }
2849 
2851 
2852  return OPERATOR_RUNNING_MODAL;
2853 }
2854 
2856 {
2857  /* Identifiers. */
2858  ot->name = "Change Data/Files";
2859  ot->idname = "SEQUENCER_OT_change_path";
2860 
2861  /* Api callbacks. */
2865 
2866  /* Flags. */
2868 
2871  FILE_SPECIAL,
2872  FILE_OPENFILE,
2878  "use_placeholders",
2879  false,
2880  "Use Placeholders",
2881  "Use placeholders for missing frames of the strip");
2882 }
2883 
2886 /* -------------------------------------------------------------------- */
2891  wmOperator *op,
2892  const wmEvent *UNUSED(event))
2893 {
2894  Main *bmain = CTX_data_main(C);
2895  if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
2896  char filepath[FILE_MAX];
2897 
2898  if (BKE_main_blendfile_path(bmain)[0] == '\0') {
2899  BLI_strncpy(filepath, "untitled", sizeof(filepath));
2900  }
2901  else {
2902  BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
2903  }
2904 
2905  BLI_path_extension_replace(filepath, sizeof(filepath), ".srt");
2906  RNA_string_set(op->ptr, "filepath", filepath);
2907  }
2908 
2910 
2911  return OPERATOR_RUNNING_MODAL;
2912 }
2913 
2915 {
2917  Sequence *seq, *seq_next;
2918  Editing *ed = SEQ_editing_get(scene, false);
2919  ListBase text_seq = {0};
2920  int iter = 0;
2921  FILE *file;
2922  char filepath[FILE_MAX];
2923 
2924  if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
2925  BKE_report(op->reports, RPT_ERROR, "No filename given");
2926  return OPERATOR_CANCELLED;
2927  }
2928 
2929  RNA_string_get(op->ptr, "filepath", filepath);
2930  BLI_path_extension_ensure(filepath, sizeof(filepath), ".srt");
2931 
2932  /* Avoid File write exceptions. */
2933  if (!BLI_exists(filepath)) {
2934  BLI_make_existing_file(filepath);
2935  if (!BLI_file_touch(filepath)) {
2936  BKE_report(op->reports, RPT_ERROR, "Can't create subtitle file");
2937  return OPERATOR_CANCELLED;
2938  }
2939  }
2940  else if (!BLI_file_is_writable(filepath)) {
2941  BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file");
2942  return OPERATOR_CANCELLED;
2943  }
2944 
2945  SEQ_ALL_BEGIN (ed, seq) {
2946  if (seq->type == SEQ_TYPE_TEXT) {
2947  BLI_addtail(&text_seq, MEM_dupallocN(seq));
2948  }
2949  }
2950  SEQ_ALL_END;
2951 
2952  if (BLI_listbase_is_empty(&text_seq)) {
2953  BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export");
2954  return OPERATOR_CANCELLED;
2955  }
2956 
2958 
2959  /* Open and write file. */
2960  file = BLI_fopen(filepath, "w");
2961 
2962  for (seq = text_seq.first; seq; seq = seq_next) {
2963  TextVars *data = seq->effectdata;
2964  char timecode_str_start[32];
2965  char timecode_str_end[32];
2966 
2967  BLI_timecode_string_from_time(timecode_str_start,
2968  sizeof(timecode_str_start),
2969  -2,
2970  FRA2TIME(seq->startdisp),
2971  FPS,
2973  BLI_timecode_string_from_time(timecode_str_end,
2974  sizeof(timecode_str_end),
2975  -2,
2976  FRA2TIME(seq->enddisp),
2977  FPS,
2979 
2980  fprintf(
2981  file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text);
2982 
2983  seq_next = seq->next;
2984  MEM_freeN(seq);
2985  }
2986 
2987  fclose(file);
2988 
2989  return OPERATOR_FINISHED;
2990 }
2991 
2993 {
2994  Editing *ed;
2995  Sequence *seq;
2996  return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
2997  ((seq = ed->act_seq) != NULL) && (seq->type == SEQ_TYPE_TEXT));
2998 }
2999 
3001 {
3002  /* Identifiers. */
3003  ot->name = "Export Subtitles";
3004  ot->idname = "SEQUENCER_OT_export_subtitles";
3005  ot->description = "Export .srt file containing text strips";
3006 
3007  /* Api callbacks. */
3011 
3012  /* Flags. */
3014 
3017  FILE_BLENDER,
3018  FILE_SAVE,
3022 }
3023 
3026 /* -------------------------------------------------------------------- */
3031 {
3033  Editing *ed = SEQ_editing_get(scene, false);
3034  Sequence *seq;
3035 
3036  int sfra = MAXFRAME;
3037  int efra = -MAXFRAME;
3038  bool selected = false;
3039  const bool preview = RNA_boolean_get(op->ptr, "preview");
3040 
3041  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
3042  if (seq->flag & SELECT) {
3043  selected = true;
3044  sfra = min_ii(sfra, seq->startdisp);
3045  efra = max_ii(efra, seq->enddisp - 1);
3046  }
3047  }
3048 
3049  if (!selected) {
3050  BKE_report(op->reports, RPT_WARNING, "Select one or more strips");
3051  return OPERATOR_CANCELLED;
3052  }
3053  if (efra < 0) {
3054  BKE_report(op->reports, RPT_ERROR, "Can't set a negative range");
3055  return OPERATOR_CANCELLED;
3056  }
3057 
3058  if (preview) {
3059  scene->r.flag |= SCER_PRV_RANGE;
3060  scene->r.psfra = max_ii(0, sfra);
3061  scene->r.pefra = efra;
3062  }
3063  else {
3064  scene->r.flag &= ~SCER_PRV_RANGE;
3065  scene->r.sfra = max_ii(0, sfra);
3066  scene->r.efra = efra;
3067  }
3068 
3070 
3071  return OPERATOR_FINISHED;
3072 }
3073 
3075 {
3076  PropertyRNA *prop;
3077 
3078  /* Identifiers. */
3079  ot->name = "Set Range to Strips";
3080  ot->idname = "SEQUENCER_OT_set_range_to_strips";
3081  ot->description = "Set the frame range to the selected strips start and end";
3082 
3083  /* Api callbacks. */
3086 
3087  /* Flags. */
3089 
3090  prop = RNA_def_boolean(ot->srna, "preview", false, "Preview", "Set the preview range instead");
3092 }
3093 
3096 /* -------------------------------------------------------------------- */
3100 enum {
3105 };
3106 
3108  {STRIP_TRANSFORM_POSITION, "POSITION", 0, "Position", "Reset strip transform location"},
3109  {STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"},
3110  {STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"},
3111  {STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"},
3112  {0, NULL, 0, NULL, NULL},
3113 };
3114 
3116 {
3118  const Editing *ed = SEQ_editing_get(scene, false);
3119  Sequence *seq;
3120  const int property = RNA_enum_get(op->ptr, "property");
3121 
3122  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
3123  if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
3125  switch (property) {
3127  transform->xofs = 0;
3128  transform->yofs = 0;
3129  break;
3130  case STRIP_TRANSFORM_SCALE:
3131  transform->scale_x = 1.0f;
3132  transform->scale_y = 1.0f;
3133  break;
3135  transform->rotation = 0.0f;
3136  break;
3137  case STRIP_TRANSFORM_ALL:
3138  transform->xofs = 0;
3139  transform->yofs = 0;
3140  transform->scale_x = 1.0f;
3141  transform->scale_y = 1.0f;
3142  transform->rotation = 0.0f;
3143  break;
3144  }
3146  }
3147  }
3148 
3150  return OPERATOR_FINISHED;
3151 }
3152 
3154 {
3155  /* Identifiers. */
3156  ot->name = "Clear Strip Transform";
3157  ot->idname = "SEQUENCER_OT_strip_transform_clear";
3158  ot->description = "Reset image transformation to default value";
3159 
3160  /* Api callbacks. */
3163 
3164  /* Flags. */
3166 
3167  ot->prop = RNA_def_enum(ot->srna,
3168  "property",
3171  "Property",
3172  "Strip transform property to be reset");
3173 }
3174 
3177 /* -------------------------------------------------------------------- */
3182  {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"},
3183  {SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"},
3184  {SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"},
3185  {0, NULL, 0, NULL, NULL},
3186 };
3187 
3189 {
3191  const Editing *ed = SEQ_editing_get(scene, false);
3192  Sequence *seq;
3193  const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method");
3194 
3195  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
3196  if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
3197  const int timeline_frame = CFRA;
3198  StripElem *strip_elem = SEQ_render_give_stripelem(seq, timeline_frame);
3199 
3200  if (strip_elem == NULL) {
3201  continue;
3202  }
3203 
3205  strip_elem->orig_width,
3206  strip_elem->orig_height,
3207  scene->r.xsch,
3208  scene->r.ysch,
3209  fit_method);
3211  }
3212  }
3213 
3215  return OPERATOR_FINISHED;
3216 }
3217 
3219 {
3220  /* Identifiers. */
3221  ot->name = "Strip Transform Set Fit";
3222  ot->idname = "SEQUENCER_OT_strip_transform_fit";
3223 
3224  /* Api callbacks. */
3227 
3228  /* Flags. */
3230 
3231  ot->prop = RNA_def_enum(ot->srna,
3232  "fit_method",
3235  "Fit Method",
3236  "Scale fit fit_method");
3237 }
3238 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct SpaceSeq * CTX_wm_space_seq(const bContext *C)
Definition: context.c:827
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_FREE_NO_MAIN
Definition: BKE_lib_id.h:188
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_sound_load(struct Main *main, struct bSound *sound)
void * BKE_sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence)
void BKE_sound_remove_scene_sound(struct Scene *scene, void *handle)
#define ATTR_FALLTHROUGH
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:349
bool BLI_file_touch(const char *file) ATTR_NONNULL()
Definition: fileops.c:294
bool BLI_file_is_writable(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:265
FILE * BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:1003
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
Definition: BLI_listbase.h:184
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1347
#define FILE_MAX
bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1601
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1571
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL()
Definition: path_util.c:519
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string_utf8.c:258
size_t BLI_timecode_string_from_time(char *str, const size_t maxncpy, const int brevity_level, const float time_seconds, const double scene_fps, const short timecode_style) ATTR_NONNULL()
Definition: timecode.c:51
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
#define N_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_SEQUENCER_STRIPS
Definition: DNA_ID.h:658
#define MINFRAME
#define CFRA
#define USER_UNIT_NONE
#define SCER_PRV_RANGE
#define FPS
eSeqImageFitMethod
@ SEQ_SCALE_TO_FILL
@ SEQ_STRETCH_TO_FILL
@ SEQ_SCALE_TO_FIT
#define FRA2TIME(a)
#define MAXFRAME
@ RGN_TYPE_WINDOW
@ SEQ_MUTE
@ SEQ_RIGHTSEL
@ SEQ_OVERLAP
@ SEQ_LOCK
@ SEQ_LEFTSEL
#define SEQ_HAS_PATH(_seq)
#define SEQ_ALLSEL
@ SEQ_TYPE_TRANSFORM
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_SOUND_HD
@ SEQ_TYPE_GLOW
@ SEQ_TYPE_COLORMIX
@ SEQ_TYPE_WIPE
@ SEQ_TYPE_META
@ SEQ_TYPE_OVERDROP
@ SEQ_TYPE_ALPHAUNDER
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_GAMCROSS
@ SEQ_TYPE_MULTICAM
@ SEQ_TYPE_MUL
@ SEQ_TYPE_GAUSSIAN_BLUR
@ SEQ_TYPE_ADD
@ SEQ_TYPE_ALPHAOVER
@ SEQ_TYPE_TEXT
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_SUB
@ SEQ_TYPE_SPEED
@ SEQ_TYPE_COLOR
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_MOVIE
@ SEQ_TYPE_ADJUSTMENT
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_BLENDER
@ FILE_TYPE_FOLDER
@ SEQ_VIEW_SEQUENCE_PREVIEW
@ SEQ_VIEW_SEQUENCE
@ SEQ_VIEW_PREVIEW
@ FILE_OPENFILE
@ FILE_SAVE
@ FILE_DEFAULTDISPLAY
@ SEQ_DRAW_SEQUENCE
@ SEQ_DRAW_IMG_IMBUF
@ USER_TIMECODE_SUBRIP
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:102
void initNumInput(NumInput *n)
Definition: numinput.c:83
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:27
@ NUM_NO_FRACTION
Definition: ED_numinput.h:72
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:207
bool hasNumInput(const NumInput *n)
Definition: numinput.c:185
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_outliner_select_sync_from_sequence_tag(struct bContext *C)
Definition: outliner_sync.c:74
bool ED_operator_sequencer_active(struct bContext *C)
Definition: screen_ops.c:319
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:815
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
#define RNA_BEGIN(sptr, itemptr, propname)
Definition: RNA_access.h:1248
#define RNA_END
Definition: RNA_access.h:1255
StructRNA RNA_Sequence
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
@ PROP_HIDDEN
Definition: RNA_types.h:202
#define C
Definition: RandGen.cpp:39
eSeqSplitMethod
Definition: SEQ_edit.h:46
@ SEQ_SPLIT_SOFT
Definition: SEQ_edit.h:47
@ SEQ_SPLIT_HARD
Definition: SEQ_edit.h:48
#define SEQ_ALL_END
Definition: SEQ_iterator.h:48
#define SEQ_ALL_BEGIN(ed, _seq)
Definition: SEQ_iterator.h:41
#define SEQ_DUPE_UNIQUE_NAME
Definition: SEQ_sequencer.h:50
#define SEQ_DUPE_CONTEXT
Definition: SEQ_sequencer.h:51
@ SEQ_SIDE_RIGHT
Definition: SEQ_sequencer.h:42
@ SEQ_SIDE_MOUSE
Definition: SEQ_sequencer.h:39
@ SEQ_SIDE_BOTH
Definition: SEQ_sequencer.h:43
@ SEQ_SIDE_NO_CHANGE
Definition: SEQ_sequencer.h:44
@ SEQ_SIDE_LEFT
Definition: SEQ_sequencer.h:41
@ UI_ITEM_R_EXPAND
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:90
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
struct View2D * UI_view2d_fromcontext(const struct bContext *C)
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
#define WM_FILESEL_DIRECTORY
Definition: WM_api.h:535
#define WM_FILESEL_RELPATH
Definition: WM_api.h:533
#define WM_FILESEL_FILEPATH
Definition: WM_api.h:537
#define WM_FILESEL_FILES
Definition: WM_api.h:538
#define ND_SEQUENCER
Definition: WM_types.h:337
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_RENDER_OPTIONS
Definition: WM_types.h:335
#define NC_SCENE
Definition: WM_types.h:279
#define KM_PRESS
Definition: WM_types.h:242
#define ND_FRAME
Definition: WM_types.h:334
#define KM_RELEASE
Definition: WM_types.h:243
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
ListBase seqbase_clipboard
Definition: clipboard.c:56
void SEQ_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
Definition: clipboard.c:172
int seqbase_clipboard_frame
Definition: clipboard.c:57
void SEQ_clipboard_pointers_store(Main *bmain, ListBase *seqbase)
Definition: clipboard.c:164
void SEQ_clipboard_free(void)
Definition: clipboard.c:61
#define SELECT
FILE * file
Scene scene
struct SeqEffectHandle SEQ_effect_handle_get(Sequence *seq)
Definition: effects.c:4291
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:4328
int SEQ_iterator_recursive_apply(Sequence *seq, int(*apply_fn)(Sequence *, void *), void *arg)
Definition: iterator.c:155
static void seq_array(Editing *ed, const bool use_current_sequences, Sequence ***r_seqarray, int *r_seqarray_len)
Definition: iterator.c:77
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong * next
static char * trim(char *str)
Definition: msgfmt.c:76
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
static void area(int d1, int d2, int e1, int e2, float weights[2])
void SEQ_prefetch_stop(Scene *scene)
Definition: prefetch.c:272
StripElem * SEQ_render_give_stripelem(Sequence *seq, int timeline_frame)
Definition: render.c:242
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3903
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3401
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
Definition: rna_access.c:6527
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
void SEQ_sequence_base_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase, int dupe_flag, const int flag)
Definition: sequencer.c:559
MetaStack * SEQ_meta_stack_alloc(Editing *ed, Sequence *seq_meta)
Definition: sequencer.c:377
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition: sequencer.c:350
Sequence * SEQ_sequence_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *new_seq_list, Sequence *seq, int dupe_flag)
Definition: sequencer.c:548
MetaStack * SEQ_meta_stack_active_get(const Editing *ed)
Definition: sequencer.c:405
void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs)
Definition: sequencer.c:620
void SEQ_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst)
Definition: sequencer.c:655
void SEQ_seqbase_active_set(Editing *ed, ListBase *seqbase)
Definition: sequencer.c:365
void SEQ_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata)
Definition: sequencer.c:213
void SEQ_meta_stack_free(Editing *ed, MetaStack *ms)
Definition: sequencer.c:393
Sequence * SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type)
Definition: sequencer.c:113
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
void sequencer_image_seq_reserve_frames(wmOperator *op, StripElem *se, int len, int minframe, int numdigits)
int sequencer_image_seq_get_minmax_frame(wmOperator *op, int sfra, int *r_minframe, int *r_numdigits)
bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **r_selseq1, Sequence **r_selseq2, Sequence **r_selseq3, const char **r_error_str)
static int sequencer_snap_exec(bContext *C, wmOperator *op)
static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
bool sequencer_strip_has_path_poll(bContext *C)
static int sequencer_mute_exec(bContext *C, wmOperator *op)
static void transseq_restore(TransSeq *ts, Sequence *seq)
static Sequence * find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel)
static int slip_add_sequences_recursive(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
void SEQUENCER_OT_copy(wmOperatorType *ot)
void SEQUENCER_OT_delete(wmOperatorType *ot)
bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
void SEQUENCER_OT_rendersize(wmOperatorType *ot)
static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
void SEQUENCER_OT_snap(struct wmOperatorType *ot)
static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
EnumPropertyItem sequencer_prop_effect_types[]
void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot)
static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void sequencer_slip_apply_limits(SlipData *data, int *offset)
void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
void ED_sequencer_deselect_all(Scene *scene)
static void transseq_backup(TransSeq *ts, Sequence *seq)
static int sequencer_reload_exec(bContext *C, wmOperator *op)
bool ED_space_sequencer_maskedit_poll(bContext *C)
static int sequencer_slip_exec(bContext *C, wmOperator *op)
static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_mute(struct wmOperatorType *ot)
bool ED_space_sequencer_maskedit_mask_poll(bContext *C)
void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot)
static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int sequencer_export_subtitles_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int sequencer_paste_exec(bContext *C, wmOperator *op)
static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_swap_data(wmOperatorType *ot)
static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
static const EnumPropertyItem scale_fit_methods[]
static bool sequencer_refresh_all_poll(bContext *C)
void SEQUENCER_OT_slip(struct wmOperatorType *ot)
void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot)
static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool sequencer_view_preview_poll(bContext *C)
@ STRIP_TRANSFORM_ALL
@ STRIP_TRANSFORM_SCALE
@ STRIP_TRANSFORM_POSITION
@ STRIP_TRANSFORM_ROTATION
static void seq_copy_del_sound(Scene *scene, Sequence *seq)
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_images_separate(wmOperatorType *ot)
static int sequencer_unmute_exec(bContext *C, wmOperator *op)
static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
EnumPropertyItem prop_side_types[]
static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
static bool sequencer_strip_is_text_poll(bContext *C)
void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot)
void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
static int sequencer_gap_insert_exec(bContext *C, wmOperator *op)
static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot)
static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static bool strip_jump_internal(Scene *scene, const short side, const bool do_skip_mute, const bool do_center)
void SEQUENCER_OT_meta_make(wmOperatorType *ot)
static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_split(struct wmOperatorType *ot)
static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
void SEQUENCER_OT_duplicate(wmOperatorType *ot)
static bool sequencer_effect_poll(bContext *C)
void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot)
static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_lock(struct wmOperatorType *ot)
static int mouse_frame_side(View2D *v2d, short mouse_x, int frame)
bool sequencer_edit_poll(bContext *C)
static bool sequencer_strip_jump_poll(bContext *C)
struct SlipData SlipData
static bool seq_is_parent(Sequence *par, Sequence *seq)
static int slip_count_sequences_recursive(ListBase *seqbasep, bool first_level)
bool sequencer_view_strips_poll(bContext *C)
static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset)
void SEQUENCER_OT_swap(wmOperatorType *ot)
static int sequencer_split_exec(bContext *C, wmOperator *op)
static int sequencer_change_path_exec(bContext *C, wmOperator *op)
static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
void SEQUENCER_OT_paste(wmOperatorType *ot)
static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot)
void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
static const EnumPropertyItem prop_split_types[]
void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
struct TransSeq TransSeq
static const EnumPropertyItem prop_side_lr_types[]
static int sequencer_copy_exec(bContext *C, wmOperator *op)
bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene)
static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op)
static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
static int sequencer_swap_exec(bContext *C, wmOperator *op)
static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
static const EnumPropertyItem prop_change_effect_input_types[]
void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
static void sequencer_split_ui(bContext *C, wmOperator *op)
void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot)
static const EnumPropertyItem transform_reset_properties[]
void SEQUENCER_OT_reload(struct wmOperatorType *ot)
static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
#define INT32_MAX
Definition: stdint.h:140
#define INT32_MIN
Definition: stdint.h:139
void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const bool lock_range)
Definition: strip_add.c:623
bool SEQ_edit_remove_gaps(Scene *scene, ListBase *seqbase, const int initial_frame, const bool remove_all_gaps)
Definition: strip_edit.c:406
void SEQ_edit_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
Definition: strip_edit.c:176
int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
Definition: strip_edit.c:52
Sequence * SEQ_edit_strip_split(Main *bmain, Scene *scene, ListBase *seqbase, Sequence *seq, const int timeline_frame, const eSeqSplitMethod method)
Definition: strip_edit.c:357
void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
Definition: strip_edit.c:194
bool SEQ_relations_render_loop_check(Sequence *seq_main, Sequence *seq)
void SEQ_relations_invalidate_cache_raw(Scene *scene, Sequence *seq)
void SEQ_relations_update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
void SEQ_relations_invalidate_dependent(Scene *scene, Sequence *seq)
void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
Sequence * SEQ_select_active_get(Scene *scene)
Definition: strip_select.c:35
int SEQ_select_active_get_pair(Scene *scene, Sequence **r_seq_act, Sequence **r_seq_other)
Definition: strip_select.c:57
void SEQ_select_active_set(Scene *scene, Sequence *seq)
Definition: strip_select.c:46
int SEQ_time_cmp_time_startdisp(const void *a, const void *b)
Definition: strip_time.c:262
int SEQ_time_find_next_prev_edit(Scene *scene, int timeline_frame, const short side, const bool do_skip_mute, const bool do_center, const bool do_unselected)
Definition: strip_time.c:270
void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
Definition: strip_time.c:197
bool SEQ_transform_seqbase_isolated_sel_check(ListBase *seqbase)
bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
bool SEQ_transform_sequence_can_be_translated(Sequence *seq)
bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test)
void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq)
void SEQ_transform_set_right_handle_frame(Sequence *seq, int val)
void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delta)
int SEQ_transform_get_right_handle_frame(Sequence *seq, bool metaclip)
void SEQ_transform_set_left_handle_frame(Sequence *seq, int val)
int SEQ_transform_get_left_handle_frame(Sequence *seq, bool metaclip)
void SEQ_transform_offset_after_frame(Scene *scene, ListBase *seqbase, const int delta, const int timeline_frame)
short regiontype
ListBase seqbase
ListBase * seqbasep
Sequence * act_seq
ListBase metastack
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
Sequence * parseq
ListBase * oldbasep
struct Editing * ed
struct RenderData r
struct UnitSettings unit
void(* init)(struct Sequence *seq)
Definition: SEQ_effects.h:51
void(* free)(struct Sequence *seq, const bool do_id_user)
Definition: SEQ_effects.h:65
struct Sequence * seq3
void * scene_sound
ListBase seqbase
struct bSound * sound
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
int init_mouse[2]
bool * trim
float init_mouseloc[2]
NumInput num_input
TransSeq * ts
Sequence ** seq_array
char name[256]
StripTransform * transform
StripElem * stripdata
char dir[768]
int anim_endofs
int startstill
int anim_startofs
char filepath[1024]
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:787
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
#define G(x, y, z)
Mask * SEQ_active_mask_get(Scene *scene)
Definition: utils.c:505
void SEQ_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq)
Definition: utils.c:139
void SEQ_sort(Scene *scene)
Definition: utils.c:58
void SEQ_set_scale_to_fit(const Sequence *seq, const int image_width, const int image_height, const int preview_width, const int preview_height, const eSeqImageFitMethod fit_method)
Definition: utils.c:557
uint len
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_fileselect(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_SPACEKEY
@ MOUSEMOVE
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
@ EVT_RETKEY
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag, short display, short sort)
int WM_operator_props_popup_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))