Merge branch 'blender-v2.81-release'
[blender.git] / source / blender / editors / transform / transform_convert_sequencer.c
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
20 /** \file
21  * \ingroup edtransform
22  */
23
24 #include "DNA_space_types.h"
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_math.h"
29
30 #include "BKE_context.h"
31 #include "BKE_sequencer.h"
32 #include "BKE_report.h"
33
34 #include "UI_view2d.h"
35
36 #include "transform.h"
37 #include "transform_convert.h"
38
39 /* -------------------------------------------------------------------- */
40 /** \name Sequencer Transform Creation
41  *
42  * \{ */
43
44 /* This function applies the rules for transforming a strip so duplicate
45  * checks don't need to be added in multiple places.
46  *
47  * recursive, count and flag MUST be set.
48  *
49  * seq->depth must be set before running this function so we know if the strips
50  * are root level or not
51  */
52 static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count, int *flag)
53 {
54   /* for extend we need to do some tricks */
55   if (t->mode == TFM_TIME_EXTEND) {
56
57     /* *** Extend Transform *** */
58
59     Scene *scene = t->scene;
60     int cfra = CFRA;
61     int left = BKE_sequence_tx_get_final_left(seq, true);
62     int right = BKE_sequence_tx_get_final_right(seq, true);
63
64     if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
65       *recursive = false;
66       *count = 0;
67       *flag = 0;
68     }
69     else if (seq->type == SEQ_TYPE_META) {
70
71       /* for meta's we only ever need to extend their children, no matter what depth
72        * just check the meta's are in the bounds */
73       if (t->frame_side == 'R' && right <= cfra) {
74         *recursive = false;
75       }
76       else if (t->frame_side == 'L' && left >= cfra) {
77         *recursive = false;
78       }
79       else {
80         *recursive = true;
81       }
82
83       *count = 1;
84       *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
85     }
86     else {
87
88       *recursive = false; /* not a meta, so no thinking here */
89       *count = 1;         /* unless its set to 0, extend will never set 2 handles at once */
90       *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
91
92       if (t->frame_side == 'R') {
93         if (right <= cfra) {
94           *count = *flag = 0;
95         } /* ignore */
96         else if (left > cfra) {
97         } /* keep the selection */
98         else {
99           *flag |= SEQ_RIGHTSEL;
100         }
101       }
102       else {
103         if (left >= cfra) {
104           *count = *flag = 0;
105         } /* ignore */
106         else if (right < cfra) {
107         } /* keep the selection */
108         else {
109           *flag |= SEQ_LEFTSEL;
110         }
111       }
112     }
113   }
114   else {
115
116     t->frame_side = 'B';
117
118     /* *** Normal Transform *** */
119
120     if (seq->depth == 0) {
121
122       /* Count */
123
124       /* Non nested strips (resect selection and handles) */
125       if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
126         *recursive = false;
127         *count = 0;
128         *flag = 0;
129       }
130       else {
131         if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
132           *flag = seq->flag;
133           *count = 2; /* we need 2 transdata's */
134         }
135         else {
136           *flag = seq->flag;
137           *count = 1; /* selected or with a handle selected */
138         }
139
140         /* Recursive */
141
142         if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
143           /* if any handles are selected, don't recurse */
144           *recursive = true;
145         }
146         else {
147           *recursive = false;
148         }
149       }
150     }
151     else {
152       /* Nested, different rules apply */
153
154 #ifdef SEQ_TX_NESTED_METAS
155       *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
156       *count = 1; /* ignore the selection for nested */
157       *recursive = (seq->type == SEQ_TYPE_META);
158 #else
159       if (seq->type == SEQ_TYPE_META) {
160         /* Meta's can only directly be moved between channels since they
161          * don't have their start and length set directly (children affect that)
162          * since this Meta is nested we don't need any of its data in fact.
163          * BKE_sequence_calc() will update its settings when run on the top-level meta. */
164         *flag = 0;
165         *count = 0;
166         *recursive = true;
167       }
168       else {
169         *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
170         *count = 1; /* ignore the selection for nested */
171         *recursive = false;
172       }
173 #endif
174     }
175   }
176 }
177
178 static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth)
179 {
180   Sequence *seq;
181   int tot = 0, recursive, count, flag;
182
183   for (seq = seqbase->first; seq; seq = seq->next) {
184     seq->depth = depth;
185
186     /* 'seq->tmp' is used by seq_tx_get_final_{left, right}
187      * to check sequence's range and clamp to it if needed.
188      * It's first place where digging into sequences tree, so store link to parent here. */
189     seq->tmp = parent;
190
191     SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */
192     tot += count;
193
194     if (recursive) {
195       tot += SeqTransCount(t, seq, &seq->seqbase, depth + 1);
196     }
197   }
198
199   return tot;
200 }
201
202 static TransData *SeqToTransData(
203     TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
204 {
205   int start_left;
206
207   switch (sel_flag) {
208     case SELECT:
209       /* Use seq_tx_get_final_left() and an offset here
210        * so transform has the left hand location of the strip.
211        * tdsq->start_offset is used when flushing the tx data back */
212       start_left = BKE_sequence_tx_get_final_left(seq, false);
213       td2d->loc[0] = start_left;
214       tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
215       break;
216     case SEQ_LEFTSEL:
217       start_left = BKE_sequence_tx_get_final_left(seq, false);
218       td2d->loc[0] = start_left;
219       break;
220     case SEQ_RIGHTSEL:
221       td2d->loc[0] = BKE_sequence_tx_get_final_right(seq, false);
222       break;
223   }
224
225   td2d->loc[1] = seq->machine; /* channel - Y location */
226   td2d->loc[2] = 0.0f;
227   td2d->loc2d = NULL;
228
229   tdsq->seq = seq;
230
231   /* Use instead of seq->flag for nested strips and other
232    * cases where the selection may need to be modified */
233   tdsq->flag = flag;
234   tdsq->sel_flag = sel_flag;
235
236   td->extra = (void *)tdsq; /* allow us to update the strip from here */
237
238   td->flag = 0;
239   td->loc = td2d->loc;
240   copy_v3_v3(td->center, td->loc);
241   copy_v3_v3(td->iloc, td->loc);
242
243   memset(td->axismtx, 0, sizeof(td->axismtx));
244   td->axismtx[2][2] = 1.0f;
245
246   td->ext = NULL;
247   td->val = NULL;
248
249   td->flag |= TD_SELECTED;
250   td->dist = 0.0;
251
252   unit_m3(td->mtx);
253   unit_m3(td->smtx);
254
255   /* Time Transform (extend) */
256   td->val = td2d->loc;
257   td->ival = td2d->loc[0];
258
259   return td;
260 }
261
262 static int SeqToTransData_Recursive(
263     TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
264 {
265   Sequence *seq;
266   int recursive, count, flag;
267   int tot = 0;
268
269   for (seq = seqbase->first; seq; seq = seq->next) {
270
271     SeqTransInfo(t, seq, &recursive, &count, &flag);
272
273     /* add children first so recalculating metastrips does nested strips first */
274     if (recursive) {
275       int tot_children = SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq);
276
277       td = td + tot_children;
278       td2d = td2d + tot_children;
279       tdsq = tdsq + tot_children;
280
281       tot += tot_children;
282     }
283
284     /* use 'flag' which is derived from seq->flag but modified for special cases */
285     if (flag & SELECT) {
286       if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
287         if (flag & SEQ_LEFTSEL) {
288           SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
289           tot++;
290         }
291         if (flag & SEQ_RIGHTSEL) {
292           SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
293           tot++;
294         }
295       }
296       else {
297         SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT);
298         tot++;
299       }
300     }
301   }
302   return tot;
303 }
304
305 static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
306 {
307   Sequence *seq;
308   int recursive, count, flag;
309   int max = INT32_MIN, min = INT32_MAX;
310
311   for (seq = seqbase->first; seq; seq = seq->next) {
312
313     /* just to get the flag since there are corner cases where this isn't totally obvious */
314     SeqTransInfo(t, seq, &recursive, &count, &flag);
315
316     /* use 'flag' which is derived from seq->flag but modified for special cases */
317     if (flag & SELECT) {
318       if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
319         if (flag & SEQ_LEFTSEL) {
320           min = min_ii(seq->startdisp, min);
321           max = max_ii(seq->startdisp, max);
322         }
323         if (flag & SEQ_RIGHTSEL) {
324           min = min_ii(seq->enddisp, min);
325           max = max_ii(seq->enddisp, max);
326         }
327       }
328       else {
329         min = min_ii(seq->startdisp, min);
330         max = max_ii(seq->enddisp, max);
331       }
332     }
333   }
334
335   if (ts) {
336     ts->max = max;
337     ts->min = min;
338   }
339 }
340
341 static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
342 {
343   Editing *ed = BKE_sequencer_editing_get(t->scene, false);
344
345   if (ed != NULL) {
346
347     ListBase *seqbasep = ed->seqbasep;
348     TransData *td = tc->data;
349     int a;
350
351     /* prevent updating the same seq twice
352      * if the transdata order is changed this will mess up
353      * but so will TransDataSeq */
354     Sequence *seq_prev = NULL;
355     Sequence *seq;
356
357     if (!(t->state == TRANS_CANCEL)) {
358
359 #if 0  // default 2.4 behavior
360
361       /* flush to 2d vector from internally used 3d vector */
362       for (a = 0; a < t->total; a++, td++) {
363         if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
364           seq = ((TransDataSeq *)td->extra)->seq;
365           BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
366         }
367
368         seq_prev = seq;
369       }
370
371 #else  // durian hack
372       {
373         int overlap = 0;
374
375         for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
376           seq = ((TransDataSeq *)td->extra)->seq;
377           if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
378             overlap = 1;
379             break;
380           }
381         }
382
383         if (overlap) {
384           bool has_effect_root = false, has_effect_any = false;
385           for (seq = seqbasep->first; seq; seq = seq->next) {
386             seq->tmp = NULL;
387           }
388
389           td = tc->data;
390           for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
391             seq = ((TransDataSeq *)td->extra)->seq;
392             if ((seq != seq_prev)) {
393               /* check effects strips, we cant change their time */
394               if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
395                 has_effect_any = true;
396                 if (seq->depth == 0) {
397                   has_effect_root = true;
398                 }
399               }
400               else {
401                 /* Tag seq with a non zero value, used by
402                  * BKE_sequence_base_shuffle_time to identify the ones to shuffle */
403                 if (seq->depth == 0) {
404                   seq->tmp = (void *)1;
405                 }
406               }
407             }
408           }
409
410           if (t->flag & T_ALT_TRANSFORM) {
411             int minframe = MAXFRAME;
412             td = tc->data;
413             for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
414               seq = ((TransDataSeq *)td->extra)->seq;
415               if ((seq != seq_prev) && (seq->depth == 0)) {
416                 minframe = min_ii(minframe, seq->startdisp);
417               }
418             }
419
420             for (seq = seqbasep->first; seq; seq = seq->next) {
421               if (!(seq->flag & SELECT)) {
422                 if (seq->startdisp >= minframe) {
423                   seq->machine += MAXSEQ * 2;
424                 }
425               }
426             }
427
428             BKE_sequence_base_shuffle_time(seqbasep, t->scene);
429
430             for (seq = seqbasep->first; seq; seq = seq->next) {
431               if (seq->machine >= MAXSEQ * 2) {
432                 seq->machine -= MAXSEQ * 2;
433                 seq->tmp = (void *)1;
434               }
435               else {
436                 seq->tmp = NULL;
437               }
438             }
439
440             BKE_sequence_base_shuffle_time(seqbasep, t->scene);
441           }
442           else {
443             BKE_sequence_base_shuffle_time(seqbasep, t->scene);
444           }
445
446           if (has_effect_any) {
447             /* update effects strips based on strips just moved in time */
448             td = tc->data;
449             for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
450               seq = ((TransDataSeq *)td->extra)->seq;
451               if ((seq != seq_prev)) {
452                 if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
453                   BKE_sequence_calc(t->scene, seq);
454                 }
455               }
456             }
457           }
458
459           if (has_effect_root) {
460             /* now if any effects _still_ overlap, we need to move them up */
461             td = tc->data;
462             for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
463               seq = ((TransDataSeq *)td->extra)->seq;
464               if ((seq != seq_prev) && (seq->depth == 0)) {
465                 if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
466                   if (BKE_sequence_test_overlap(seqbasep, seq)) {
467                     BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
468                   }
469                 }
470               }
471             }
472             /* done with effects */
473           }
474         }
475       }
476 #endif
477
478       for (seq = seqbasep->first; seq; seq = seq->next) {
479         /* We might want to build a list of effects that need to be updated during transform */
480         if (seq->type & SEQ_TYPE_EFFECT) {
481           if (seq->seq1 && seq->seq1->flag & SELECT) {
482             BKE_sequence_calc(t->scene, seq);
483           }
484           else if (seq->seq2 && seq->seq2->flag & SELECT) {
485             BKE_sequence_calc(t->scene, seq);
486           }
487           else if (seq->seq3 && seq->seq3->flag & SELECT) {
488             BKE_sequence_calc(t->scene, seq);
489           }
490         }
491       }
492
493       BKE_sequencer_sort(t->scene);
494     }
495     else {
496       /* Canceled, need to update the strips display */
497       for (a = 0; a < tc->data_len; a++, td++) {
498         seq = ((TransDataSeq *)td->extra)->seq;
499         if ((seq != seq_prev) && (seq->depth == 0)) {
500           if (seq->flag & SEQ_OVERLAP) {
501             BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
502           }
503
504           BKE_sequence_calc_disp(t->scene, seq);
505         }
506         seq_prev = seq;
507       }
508     }
509   }
510
511   if ((custom_data->data != NULL) && custom_data->use_free) {
512     TransSeq *ts = custom_data->data;
513     MEM_freeN(ts->tdseq);
514     MEM_freeN(custom_data->data);
515     custom_data->data = NULL;
516   }
517
518   DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
519 }
520
521 void createTransSeqData(bContext *C, TransInfo *t)
522 {
523 #define XXX_DURIAN_ANIM_TX_HACK
524
525   View2D *v2d = UI_view2d_fromcontext(C);
526   Scene *scene = t->scene;
527   Editing *ed = BKE_sequencer_editing_get(t->scene, false);
528   TransData *td = NULL;
529   TransData2D *td2d = NULL;
530   TransDataSeq *tdsq = NULL;
531   TransSeq *ts = NULL;
532   int xmouse;
533
534   int count = 0;
535
536   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
537
538   if (ed == NULL) {
539     tc->data_len = 0;
540     return;
541   }
542
543   tc->custom.type.free_cb = freeSeqData;
544
545   xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]);
546
547   /* which side of the current frame should be allowed */
548   if (t->mode == TFM_TIME_EXTEND) {
549     /* only side on which mouse is gets transformed */
550     t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
551   }
552   else {
553     /* normal transform - both sides of current frame are considered */
554     t->frame_side = 'B';
555   }
556
557 #ifdef XXX_DURIAN_ANIM_TX_HACK
558   {
559     Sequence *seq;
560     for (seq = ed->seqbasep->first; seq; seq = seq->next) {
561       /* hack */
562       if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) {
563         Sequence *seq_user;
564         int i;
565         for (i = 0; i < 3; i++) {
566           seq_user = *((&seq->seq1) + i);
567           if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) &&
568               !(seq_user->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL))) {
569             seq->flag |= SELECT;
570           }
571         }
572       }
573     }
574   }
575 #endif
576
577   count = SeqTransCount(t, NULL, ed->seqbasep, 0);
578
579   /* allocate memory for data */
580   tc->data_len = count;
581
582   /* stop if trying to build list if nothing selected */
583   if (count == 0) {
584     return;
585   }
586
587   tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq");
588   tc->custom.type.use_free = true;
589   td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData");
590   td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D");
591   ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
592
593   /* loop 2: build transdata array */
594   SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
595   SeqTransDataBounds(t, ed->seqbasep, ts);
596
597   /* set the snap mode based on how close the mouse is at the end/start points */
598   if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) {
599     ts->snap_left = true;
600   }
601
602 #undef XXX_DURIAN_ANIM_TX_HACK
603 }
604
605 /** \} */
606
607 /* -------------------------------------------------------------------- */
608 /** \name UVs Transform Flush
609  *
610  * \{ */
611
612 /* commented _only_ because the meta may have animation data which
613  * needs moving too [#28158] */
614
615 #define SEQ_TX_NESTED_METAS
616
617 BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
618 {
619   if (seq->depth == 0) {
620     /* Calculate this strip and all nested strips.
621      * Children are ALWAYS transformed first so we don't need to do this in another loop.
622      */
623     BKE_sequence_calc(sce, seq);
624   }
625   else {
626     BKE_sequence_calc_disp(sce, seq);
627   }
628
629   if (sel_flag == SELECT) {
630     BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start);
631   }
632 }
633
634 void flushTransSeq(TransInfo *t)
635 {
636   /* Editing null check already done */
637   ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep;
638
639   int a, new_frame;
640   TransData *td = NULL;
641   TransData2D *td2d = NULL;
642   TransDataSeq *tdsq = NULL;
643   Sequence *seq;
644
645   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
646
647   /* prevent updating the same seq twice
648    * if the transdata order is changed this will mess up
649    * but so will TransDataSeq */
650   Sequence *seq_prev = NULL;
651   int old_start_prev = 0, sel_flag_prev = 0;
652
653   /* flush to 2d vector from internally used 3d vector */
654   for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
655     int old_start;
656     tdsq = (TransDataSeq *)td->extra;
657     seq = tdsq->seq;
658     old_start = seq->start;
659     new_frame = round_fl_to_int(td2d->loc[0]);
660
661     switch (tdsq->sel_flag) {
662       case SELECT:
663 #ifdef SEQ_TX_NESTED_METAS
664         if ((seq->depth != 0 || BKE_sequence_tx_test(seq))) {
665           /* for meta's, their children move */
666           seq->start = new_frame - tdsq->start_offset;
667         }
668 #else
669         if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) {
670           /* for meta's, their children move */
671           seq->start = new_frame - tdsq->start_offset;
672         }
673 #endif
674         if (seq->depth == 0) {
675           seq->machine = round_fl_to_int(td2d->loc[1]);
676           CLAMP(seq->machine, 1, MAXSEQ);
677         }
678         break;
679       case SEQ_LEFTSEL: /* no vertical transform  */
680         BKE_sequence_tx_set_final_left(seq, new_frame);
681         BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
682
683         /* todo - move this into aftertrans update? - old seq tx needed it anyway */
684         BKE_sequence_single_fix(seq);
685         break;
686       case SEQ_RIGHTSEL: /* no vertical transform  */
687         BKE_sequence_tx_set_final_right(seq, new_frame);
688         BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
689
690         /* todo - move this into aftertrans update? - old seq tx needed it anyway */
691         BKE_sequence_single_fix(seq);
692         break;
693     }
694
695     /* Update *previous* seq! Else, we would update a seq after its first transform,
696      * and if it has more than one (like e.g. SEQ_LEFTSEL and SEQ_RIGHTSEL),
697      * the others are not updated! See T38469.
698      */
699     if (seq != seq_prev) {
700       if (seq_prev) {
701         trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
702       }
703
704       seq_prev = seq;
705       old_start_prev = old_start;
706       sel_flag_prev = tdsq->sel_flag;
707     }
708     else {
709       /* We want to accumulate *all* sel_flags for this seq! */
710       sel_flag_prev |= tdsq->sel_flag;
711     }
712   }
713
714   /* Don't forget to update the last seq! */
715   if (seq_prev) {
716     trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
717   }
718
719   /* originally TFM_TIME_EXTEND, transform changes */
720   if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
721     /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
722
723     /* calc all meta's then effects [#27953] */
724     for (seq = seqbasep->first; seq; seq = seq->next) {
725       if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
726         BKE_sequence_calc(t->scene, seq);
727       }
728     }
729     for (seq = seqbasep->first; seq; seq = seq->next) {
730       if (seq->seq1 || seq->seq2 || seq->seq3) {
731         BKE_sequence_calc(t->scene, seq);
732       }
733     }
734
735     /* update effects inside meta's */
736     for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; a < tc->data_len;
737          a++, td++, td2d++, seq_prev = seq) {
738       tdsq = (TransDataSeq *)td->extra;
739       seq = tdsq->seq;
740       if ((seq != seq_prev) && (seq->depth != 0)) {
741         if (seq->seq1 || seq->seq2 || seq->seq3) {
742           BKE_sequence_calc(t->scene, seq);
743         }
744       }
745     }
746   }
747
748   /* need to do the overlap check in a new loop otherwise adjacent strips
749    * will not be updated and we'll get false positives */
750   seq_prev = NULL;
751   for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
752
753     tdsq = (TransDataSeq *)td->extra;
754     seq = tdsq->seq;
755
756     if (seq != seq_prev) {
757       if (seq->depth == 0) {
758         /* test overlap, displays red outline */
759         seq->flag &= ~SEQ_OVERLAP;
760         if (BKE_sequence_test_overlap(seqbasep, seq)) {
761           seq->flag |= SEQ_OVERLAP;
762         }
763       }
764     }
765     seq_prev = seq;
766   }
767 }
768
769 /** \} */