clear group_id on move_edits, neoph about_bg leak, use inv clr on edit title bar...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / tracks.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "atrack.h"
22 #include "automation.h"
23 #include "clip.h"
24 #include "bchash.h"
25 #include "edit.h"
26 #include "edits.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "file.h"
30 #include "filexml.h"
31 #include "intauto.h"
32 #include "intautos.h"
33 #include "localsession.h"
34 #include "module.h"
35 #include "panauto.h"
36 #include "panautos.h"
37 #include "patchbay.h"
38 #include "mainsession.h"
39 #include "strack.h"
40 #include "theme.h"
41 #include "track.h"
42 #include "trackcanvas.h"
43 #include "tracks.h"
44 #include "transportque.inc"
45 #include "vtrack.h"
46 #include <string.h>
47
48 Tracks::Tracks(EDL *edl)
49  : List<Track>()
50 {
51         this->edl = edl;
52 }
53
54 Tracks::Tracks()
55  : List<Track>()
56 {
57 }
58
59
60 Tracks::~Tracks()
61 {
62         delete_all_tracks();
63 }
64
65
66
67
68
69 void Tracks::equivalent_output(Tracks *tracks, double *result)
70 {
71         if(total_playable_vtracks() != tracks->total_playable_vtracks())
72         {
73                 *result = 0;
74         }
75         else
76         {
77                 Track *current = first;
78                 Track *that_current = tracks->first;
79                 while(current || that_current)
80                 {
81 // Get next video track
82                         while(current && current->data_type != TRACK_VIDEO)
83                                 current = NEXT;
84
85                         while(that_current && that_current->data_type != TRACK_VIDEO)
86                                 that_current = that_current->next;
87
88 // One doesn't exist but the other does
89                         if((!current && that_current) ||
90                                 (current && !that_current))
91                         {
92                                 *result = 0;
93                                 break;
94                         }
95                         else
96 // Both exist
97                         if(current && that_current)
98                         {
99                                 current->equivalent_output(that_current, result);
100                                 current = NEXT;
101                                 that_current = that_current->next;
102                         }
103                 }
104         }
105 }
106
107
108 void Tracks::clear_selected_edits()
109 {
110         for( Track *track=first; track; track=track->next ) {
111                 for( Edit *edit=track->edits->first; edit; edit=edit->next )
112                         edit->is_selected = 0;
113         }
114 }
115
116 void Tracks::select_affected_edits(double position, Track *start_track)
117 {
118         for( Track *track=start_track; track; track=track->next ) {
119                 if( !track->record ) continue;
120                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
121                         double startproject = track->from_units(edit->startproject);
122                         if( edl->equivalent(startproject, position) ) {
123                                 edit->is_selected = 1;
124                                 break;
125                         }
126                 }
127         }
128 }
129
130 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
131 {
132         drag_edits->remove_all();
133         for( Track *track=first; track; track=track->next ) {
134                 if( !track->record ) continue;
135                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
136                         if( !edit->is_selected ) continue;
137                         drag_edits->append(edit);
138                 }
139         }
140 }
141
142 void Tracks::get_automation_extents(float *min,
143         float *max,
144         double start,
145         double end,
146         int autogrouptype)
147 {
148         *min = 0;
149         *max = 0;
150         int coords_undefined = 1;
151         for(Track *current = first; current; current = NEXT)
152         {
153                 if(current->record)
154                 {
155                         current->automation->get_extents(min,
156                                 max,
157                                 &coords_undefined,
158                                 current->to_units(start, 0),
159                                 current->to_units(end, 1),
160                                 autogrouptype);
161                 }
162         }
163 }
164
165
166 void Tracks::copy_from(Tracks *tracks)
167 {
168         Track *new_track = 0;
169
170         delete_all_tracks();
171         for(Track *current = tracks->first; current; current = NEXT)
172         {
173                 switch(current->data_type)
174                 {
175                 case TRACK_AUDIO:
176                         new_track = add_audio_track(0, 0);
177                         break;
178                 case TRACK_VIDEO:
179                         new_track = add_video_track(0, 0);
180                         break;
181                 case TRACK_SUBTITLE:
182                         new_track = add_subttl_track(0, 0);
183                         break;
184                 default:
185                         continue;
186                 }
187                 new_track->copy_from(current);
188         }
189 }
190
191 Tracks& Tracks::operator=(Tracks &tracks)
192 {
193 printf("Tracks::operator= 1\n");
194         copy_from(&tracks);
195         return *this;
196 }
197
198 int Tracks::load(FileXML *xml,
199         int &track_offset,
200         uint32_t load_flags)
201 {
202 // add the appropriate type of track
203         char string[BCTEXTLEN];
204         Track *track = 0;
205         string[0] = 0;
206
207         xml->tag.get_property("TYPE", string);
208
209         if((load_flags & LOAD_ALL) == LOAD_ALL ||
210                 (load_flags & LOAD_EDITS)) {
211                 if(!strcmp(string, "VIDEO")) {
212                         track = add_video_track(0, 0);
213                 }
214                 else if(!strcmp(string, "SUBTTL")) {
215                         track = add_subttl_track(0, 0);
216                 }
217                 else {
218                         track = add_audio_track(0, 0);    // default to audio
219                 }
220         }
221         else {
222                 track = get_item_number(track_offset++);
223         }
224
225 // load it
226         if( track ) track->load(xml, track_offset, load_flags);
227
228         return 0;
229 }
230
231 Track* Tracks::add_audio_track(int above, Track *dst_track)
232 {
233         ATrack* new_track = new ATrack(edl, this);
234         if(!dst_track)
235         {
236                 dst_track = (above ? first : last);
237         }
238
239         if(above)
240         {
241                 insert_before(dst_track, (Track*)new_track);
242         }
243         else
244         {
245                 insert_after(dst_track, (Track*)new_track);
246 // Shift effects referenced below the destination track
247         }
248
249 // Shift effects referenced below the new track
250         for(Track *track = last;
251                 track && track != new_track;
252                 track = track->previous)
253         {
254                 change_modules(number_of(track) - 1, number_of(track), 0);
255         }
256
257
258         new_track->create_objects();
259         new_track->set_default_title();
260
261         int current_pan = 0;
262         for(Track *current = first;
263                 current != (Track*)new_track;
264                 current = NEXT)
265         {
266                 if(current->data_type == TRACK_AUDIO) current_pan++;
267                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
268         }
269
270
271
272         PanAuto* pan_auto =
273                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
274         pan_auto->values[current_pan] = 1.0;
275
276         BC_Pan::calculate_stick_position(edl->session->audio_channels,
277                 edl->session->achannel_positions,
278                 pan_auto->values,
279                 MAX_PAN,
280                 PAN_RADIUS,
281                 pan_auto->handle_x,
282                 pan_auto->handle_y);
283         return new_track;
284 }
285
286 Track* Tracks::add_video_track(int above, Track *dst_track)
287 {
288         VTrack* new_track = new VTrack(edl, this);
289         if(!dst_track)
290                 dst_track = (above ? first : last);
291         if(above)
292                 insert_before(dst_track, (Track*)new_track);
293         else
294                 insert_after(dst_track, (Track*)new_track);
295
296         for(Track *track = last; track && track != new_track; track = track->previous)
297                 change_modules(number_of(track) - 1, number_of(track), 0);
298
299         new_track->create_objects();
300         new_track->set_default_title();
301         return new_track;
302 }
303
304
305 Track* Tracks::add_subttl_track(int above, Track *dst_track)
306 {
307         STrack* new_track = new STrack(edl, this);
308         if(!dst_track)
309                 dst_track = (above ? first : last);
310
311         if(above)
312                 insert_before(dst_track, (Track*)new_track);
313         else
314                 insert_after(dst_track, (Track*)new_track);
315
316         for(Track *track = last; track && track != new_track; track = track->previous)
317                 change_modules(number_of(track) - 1, number_of(track), 0);
318
319         new_track->create_objects();
320         new_track->set_default_title();
321 //      new_track->paste_silence(0,total_length(),0);
322         return new_track;
323 }
324
325
326 int Tracks::delete_track(Track *track)
327 {
328         if (!track)
329                 return 0;
330
331         int old_location = number_of(track);
332         detach_shared_effects(old_location);
333
334 // Shift effects referencing effects below the deleted track
335         for(Track *current = track;
336                 current;
337                 current = NEXT)
338         {
339                 change_modules(number_of(current), number_of(current) - 1, 0);
340         }
341         if(track) delete track;
342
343         return 0;
344 }
345
346 int Tracks::detach_shared_effects(int module)
347 {
348         for(Track *current = first; current; current = NEXT)
349         {
350                 current->detach_shared_effects(module);
351         }
352
353         return 0;
354  }
355
356 int Tracks::total_of(int type)
357 {
358         int result = 0;
359
360         for(Track *current = first; current; current = NEXT)
361         {
362                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
363                 Auto *mute_keyframe = 0;
364                 current->automation->autos[AUTOMATION_MUTE]->
365                         get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
366                 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
367
368                 result +=
369                         (current->play && type == PLAY) ||
370                         (current->record && type == RECORD) ||
371                         (current->gang && type == GANG) ||
372                         (current->draw && type == DRAW) ||
373                         (mute_auto->value && type == MUTE) ||
374                         (current->expand_view && type == EXPAND);
375         }
376         return result;
377 }
378
379 int Tracks::recordable_audio_tracks()
380 {
381         int result = 0;
382         for(Track *current = first; current; current = NEXT)
383                 if(current->data_type == TRACK_AUDIO && current->record) result++;
384         return result;
385 }
386
387 int Tracks::recordable_video_tracks()
388 {
389         int result = 0;
390         for(Track *current = first; current; current = NEXT)
391         {
392                 if(current->data_type == TRACK_VIDEO && current->record) result++;
393         }
394         return result;
395 }
396
397
398 int Tracks::playable_audio_tracks()
399 {
400         int result = 0;
401
402         for(Track *current = first; current; current = NEXT)
403         {
404                 if(current->data_type == TRACK_AUDIO && current->play)
405                 {
406                         result++;
407                 }
408         }
409
410         return result;
411 }
412
413 int Tracks::playable_video_tracks()
414 {
415         int result = 0;
416
417         for(Track *current = first; current; current = NEXT)
418         {
419                 if(current->data_type == TRACK_VIDEO && current->play)
420                 {
421                         result++;
422                 }
423         }
424         return result;
425 }
426
427 int Tracks::total_audio_tracks()
428 {
429         int result = 0;
430         for(Track *current = first; current; current = NEXT)
431                 if(current->data_type == TRACK_AUDIO) result++;
432         return result;
433 }
434
435 int Tracks::total_video_tracks()
436 {
437         int result = 0;
438         for(Track *current = first; current; current = NEXT)
439                 if(current->data_type == TRACK_VIDEO) result++;
440         return result;
441 }
442
443 double Tracks::total_playable_length()
444 {
445         double total = 0;
446         for(Track *current = first; current; current = NEXT)
447         {
448                 if( current->play )
449                 {
450                         double length = current->get_length();
451                         if(length > total) total = length;
452                 }
453         }
454         return total;
455 }
456
457 double Tracks::total_recordable_length()
458 {
459         double total = -1;
460         for(Track *current = first; current; current = NEXT)
461         {
462                 if(current->record)
463                 {
464                         double length = current->get_length();
465                         if(length > total) total = length;
466                 }
467         }
468         return total;
469 }
470
471 double Tracks::total_length()
472 {
473         double total = 0;
474         for(Track *current = first; current; current = NEXT)
475         {
476                 double length = current->get_length();
477                 if(length > total) total = length;
478         }
479         return total;
480 }
481
482 double Tracks::total_audio_length()
483 {
484         double total = 0;
485         for(Track *current = first; current; current = NEXT)
486         {
487                 if(current->data_type == TRACK_AUDIO &&
488                         current->get_length() > total) total = current->get_length();
489         }
490         return total;
491 }
492
493 double Tracks::total_video_length()
494 {
495         double total = 0;
496         for(Track *current = first; current; current = NEXT)
497         {
498                 if(current->data_type == TRACK_VIDEO &&
499                         current->get_length() > total) total = current->get_length();
500         }
501         return total;
502 }
503
504 double Tracks::total_length_framealigned(double fps)
505 {
506         if (total_audio_tracks() && total_video_tracks())
507                 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
508
509         if (total_audio_tracks())
510                 return floor(total_audio_length() * fps) / fps;
511
512         if (total_video_tracks())
513                 return floor(total_video_length() * fps) / fps;
514
515         return 0;
516 }
517
518 void Tracks::translate_projector(float offset_x, float offset_y)
519 {
520         for(Track *current = first; current; current = NEXT)
521         {
522                 if(current->data_type == TRACK_VIDEO)
523                 {
524                         ((VTrack*)current)->translate(offset_x, offset_y, 0);
525                 }
526         }
527 }
528
529 void Tracks::update_y_pixels(Theme *theme)
530 {
531 //      int y = -edl->local_session->track_start;
532         int y = 0;
533         for(Track *current = first; current; current = NEXT)
534         {
535 //printf("Tracks::update_y_pixels %d\n", y);
536                 current->y_pixel = y;
537                 y += current->vertical_span(theme);
538         }
539 }
540
541 int Tracks::dump(FILE *fp)
542 {
543         for(Track* current = first; current; current = NEXT)
544         {
545                 fprintf(fp,"  Track: %p\n", current);
546                 current->dump(fp);
547                 fprintf(fp,"\n");
548         }
549         return 0;
550 }
551
552 void Tracks::select_all(int type,
553                 int value)
554 {
555         for(Track* current = first; current; current = NEXT)
556         {
557                 double position = edl->local_session->get_selectionstart(1);
558
559                 if(type == PLAY) current->play = value;
560                 if(type == RECORD) current->record = value;
561                 if(type == GANG) current->gang = value;
562                 if(type == DRAW) current->draw = value;
563
564                 if(type == MUTE)
565                 {
566                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
567                 }
568
569                 if(type == EXPAND) current->expand_view = value;
570         }
571 }
572
573 // ===================================== file operations
574
575 int Tracks::popup_transition(int cursor_x, int cursor_y)
576 {
577         int result = 0;
578         for(Track* current = first; current && !result; current = NEXT)
579         {
580                 result = current->popup_transition(cursor_x, cursor_y);
581         }
582         return result;
583 }
584
585
586 int Tracks::change_channels(int oldchannels, int newchannels)
587 {
588         for(Track *current = first; current; current = NEXT)
589         { current->change_channels(oldchannels, newchannels); }
590         return 0;
591 }
592
593
594
595 int Tracks::totalpixels()
596 {
597         int result = 0;
598         for(Track* current = first; current; current = NEXT)
599         {
600                 result += edl->local_session->zoom_track;
601         }
602         return result;
603 }
604
605 int Tracks::number_of(Track *track)
606 {
607         int i = 0;
608         for(Track *current = first; current && current != track; current = NEXT)
609         {
610                 i++;
611         }
612         return i;
613 }
614
615 Track* Tracks::number(int number)
616 {
617         Track *current;
618         int i = 0;
619         for(current = first; current && i < number; current = NEXT)
620         {
621                 i++;
622         }
623         return current;
624 }
625
626
627 int Tracks::total_playable_vtracks()
628 {
629         int result = 0;
630         for(Track *current = first; current; current = NEXT)
631         {
632                 if(current->data_type == TRACK_VIDEO && current->play) result++;
633         }
634         return result;
635 }
636
637 int Tracks::plugin_exists(Plugin *plugin)
638 {
639         for(Track *track = first; track; track = track->next)
640         {
641                 if(track->plugin_exists(plugin)) return 1;
642         }
643         return 0;
644 }
645
646 int Tracks::track_exists(Track *track)
647 {
648         for(Track *current = first; current; current = NEXT)
649         {
650                 if(current == track) return 1;
651         }
652         return 0;
653 }
654
655 int Tracks::new_group(int id)
656 {
657         int count = 0;
658         for( Track *track=first; track; track=track->next ) {
659                 if( !track->record ) continue;
660                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
661                         if( !edit->is_selected ) continue;
662                         edit->group_id = id;
663                         ++count;
664                 }
665         }
666         return count;
667 }
668
669 int Tracks::set_group_selected(int id, int v)
670 {
671         int count = 0;
672         for( Track *track=first; track; track=track->next ) {
673                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
674                         if( edit->group_id != id ) continue;
675                         edit->is_selected = v;
676                         ++count;
677                 }
678         }
679         return count;
680 }
681
682 int Tracks::del_group(int id)
683 {
684         int count = 0;
685         for( Track *track=first; track; track=track->next ) {
686                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
687                         if( edit->group_id != id ) continue;
688                         edit->is_selected = 1;
689                         edit->group_id = 0;
690                         ++count;
691                 }
692         }
693         return count;
694 }
695
696 Track *Tracks::get(int idx, int data_type)
697 {
698         for(Track *current = first; current; current = NEXT)
699         {
700                 if( current->data_type != data_type ) continue;
701                 if( --idx < 0 ) return current;
702         }
703         return 0;
704 }
705