switch move/swap tracks, add mv trk shortcut, update msg
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / tracksedit.C
index 1129502accdb7e1d8b62caf010991a644dd21bf5..8a8602f6090f8032b150d42b8cb001a757ab28c2 100644 (file)
@@ -50,7 +50,7 @@
 int Tracks::blade(double position)
 {
        for( Track *track=first; track!=0; track=track->next ) {
 int Tracks::blade(double position)
 {
        for( Track *track=first; track!=0; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                track->blade(position);
        }
        return 0;
                track->blade(position);
        }
        return 0;
@@ -64,7 +64,7 @@ int Tracks::clear(double start, double end, int clear_plugins, int edit_autos)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->clear(start,
                                end,
                {
                        current_track->clear(start,
                                end,
@@ -84,7 +84,7 @@ void Tracks::clear_automation(double selectionstart, double selectionend)
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->clear_automation(selectionstart,
                                selectionend,
                {
                        current_track->clear_automation(selectionstart,
                                selectionend,
@@ -100,7 +100,7 @@ void Tracks::clear_transitions(double start, double end)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        int64_t start_units = current_track->to_units(start, 0);
                        int64_t end_units = current_track->to_units(end, 0);
                {
                        int64_t start_units = current_track->to_units(start, 0);
                        int64_t end_units = current_track->to_units(end, 0);
@@ -120,6 +120,33 @@ void Tracks::clear_transitions(double start, double end)
        }
 }
 
        }
 }
 
+int Tracks::clear_hard_edges(double start, double end)
+{
+       for( Track *track=first; track; track=track->next ) {
+               if( !track->is_armed() ) continue;
+               int64_t start_units = track->to_units(start, 0);
+               int64_t end_units = track->to_units(end, 0);
+
+               for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                       int64_t pos = edit->startproject;
+                       if( pos > end_units ) break;
+                       if( pos >= start_units ) {
+                               edit->hard_left = 0;
+                               if( edit->previous )
+                                       edit->previous->hard_right = 0;
+                       }
+                       pos += edit->length;
+                       if( pos > end_units ) break;
+                       if( pos >= start_units ) {
+                               edit->hard_right = 0;
+                               if( edit->next )
+                                       edit->next->hard_left = 0;
+                       }
+               }
+       }
+       return 0;
+}
+
 void Tracks::shuffle_edits(double start, double end)
 {
 // This doesn't affect automation or effects
 void Tracks::shuffle_edits(double start, double end)
 {
 // This doesn't affect automation or effects
@@ -129,7 +156,7 @@ void Tracks::shuffle_edits(double start, double end)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->shuffle_edits(start, end, first_track);
 
                {
                        current_track->shuffle_edits(start, end, first_track);
 
@@ -147,7 +174,7 @@ void Tracks::reverse_edits(double start, double end)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->reverse_edits(start, end, first_track);
 
                {
                        current_track->reverse_edits(start, end, first_track);
 
@@ -155,19 +182,17 @@ void Tracks::reverse_edits(double start, double end)
                }
        }
 }
                }
        }
 }
+
 void Tracks::align_edits(double start, double end)
 {
 // This doesn't affect automation or effects
 void Tracks::align_edits(double start, double end)
 {
 // This doesn't affect automation or effects
-       ArrayList<double> times;
-
-       for(Track *current_track = first;
-               current_track;
-               current_track = current_track->next)
-       {
-               if(current_track->record)
-               {
-                       current_track->align_edits(start, end, &times);
-               }
+       Track *master_track = 0;
+       for( Track *track=first; track; track=track->next ) {
+               if( !track->is_armed() ) continue;
+               if( !master_track )
+                       master_track = track;
+               else
+                       track->align_edits(start, end, master_track);
        }
 }
 
        }
 }
 
@@ -178,7 +203,7 @@ void Tracks::set_edit_length(double start, double end, double length)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
 #define USE_FLOATING_LENGTHS
 
                {
 #define USE_FLOATING_LENGTHS
 
@@ -319,7 +344,7 @@ void Tracks::set_transition_length(double start, double end, double length)
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        int64_t start_units = current_track->to_units(start, 0);
                        int64_t end_units = current_track->to_units(end, 0);
                {
                        int64_t start_units = current_track->to_units(start, 0);
                        int64_t end_units = current_track->to_units(end, 0);
@@ -347,34 +372,48 @@ void Tracks::set_transition_length(double start, double end, double length)
 void Tracks::set_transition_length(Transition *transition, double length)
 {
 // Must verify existence of transition
 void Tracks::set_transition_length(Transition *transition, double length)
 {
 // Must verify existence of transition
-       int done = 0;
-       if(!transition) return;
-       for(Track *current_track = first;
-               current_track && !done;
-               current_track = current_track->next)
-       {
-               for(Edit *current_edit = current_track->edits->first;
-                       current_edit && !done;
-                       current_edit = current_edit->next)
-               {
-                       if(current_edit->transition == transition)
-                       {
-                               transition->length = current_track->to_units(length, 1);
-                               if( current_edit == current_track->edits->last &&
-                                   current_edit->silence() ) {
-                                       current_edit->length = current_edit->transition->length;
+       int found = 0;
+       if( !transition ) return;
+       for( Track *track=first; track && !found; track=track->next ) {
+               for( Edit *edit=track->edits->first; edit && !found; edit = edit->next ) {
+                       if( edit->transition == transition ) {
+                               transition->length = track->to_units(length, 1);
+                               if( edit == track->edits->last && edit->silence() ) {
+                                       edit->length = edit->transition->length;
                                }
                                }
-                               done = 1;
+                               found = 1;
                        }
                }
        }
                        }
                }
        }
+       if( !found ) return;
+       if( edl->session->gang_tracks == GANG_NONE ) return;
+       Track *track = transition->edit->track;
+       double pos = track->from_units(transition->edit->startproject);
+       Track *current = edl->tracks->first;
+       for( ; current; current=current->next ) {
+               if( current == track ) continue;
+               if( current->data_type != track->data_type ) continue;
+               if( !current->armed_gang(track) ) continue;
+               int64_t track_pos = current->to_units(pos, 1);
+               Edit *edit = current->edits->editof(track_pos, PLAY_FORWARD, 0);
+               if( !edit || !edit->transition ) continue;
+               double edit_pos = track->from_units(edit->startproject);
+               if( !edl->equivalent(pos, edit_pos) ) continue;
+// modify gang same transitions at same position
+               if( edit->transition->Plugin::identical(transition) ) {
+                       edit->transition->length = transition->length;
+               }
+               if( edit == track->edits->last && edit->silence() ) {
+                       edit->length = edit->transition->length;
+               }
+       }
 }
 
 void Tracks::paste_transitions(double start, double end, int track_type, char* title)
 {
        int count = 0;
        for( Track *track=first; track; track=track->next ) {
 }
 
 void Tracks::paste_transitions(double start, double end, int track_type, char* title)
 {
        int count = 0;
        for( Track *track=first; track; track=track->next ) {
-               if( !track->record || track->data_type != track_type ) continue;
+               if( !track->is_armed() || track->data_type != track_type ) continue;
                for( Edit *edit=track->edits->first;  edit; edit=edit->next ) {
                        if( !edit->is_selected ) continue;
                        edit->insert_transition(title);
                for( Edit *edit=track->edits->first;  edit; edit=edit->next ) {
                        if( !edit->is_selected ) continue;
                        edit->insert_transition(title);
@@ -387,7 +426,7 @@ void Tracks::paste_transitions(double start, double end, int track_type, char* t
        }
 
        for( Track *track=first; track; track=track->next ) {
        }
 
        for( Track *track=first; track; track=track->next ) {
-               if( !track->record || track->data_type != track_type ) continue;
+               if( !track->is_armed() || track->data_type != track_type ) continue;
                int64_t start_units = track->to_units(start, 0);
                int64_t end_units = track->to_units(end, 0);
                if( start_units == end_units ) {
                int64_t start_units = track->to_units(start, 0);
                int64_t end_units = track->to_units(end, 0);
                if( start_units == end_units ) {
@@ -425,7 +464,7 @@ void Tracks::set_automation_mode(double selectionstart,
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->set_automation_mode(selectionstart,
                                selectionend,
                {
                        current_track->set_automation_mode(selectionstart,
                                selectionend,
@@ -438,7 +477,7 @@ int Tracks::clear_default_keyframe()
 {
        for(Track *current = first; current; current = NEXT)
        {
 {
        for(Track *current = first; current; current = NEXT)
        {
-               if(current->record)
+               if(current->is_armed())
                        current->clear_automation(0, 0, 0, 1);
        }
        return 0;
                        current->clear_automation(0, 0, 0, 1);
        }
        return 0;
@@ -456,7 +495,7 @@ int Tracks::clear_handle(double start,
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
 
        for(current_track = first; current_track; current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->clear_handle(start,
                                end,
                {
                        current_track->clear_handle(start,
                                end,
@@ -492,7 +531,7 @@ int Tracks::copy_automation(double selectionstart,
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->copy_automation(selectionstart,
                                selectionend,
                {
                        current_track->copy_automation(selectionstart,
                                selectionend,
@@ -519,22 +558,18 @@ int Tracks::delete_tracks()
 {
        int total_deleted = 0;
        int done = 0;
 {
        int total_deleted = 0;
        int done = 0;
+       int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
 
 
-       while(!done)
-       {
+       while( !done ) {
                done = 1;
                done = 1;
-               Track *next_track = 0;
-               for (Track* current = first; current && done; current = next_track)
-               {
-                       next_track = current->next;
-                       if(current->record)
-                       {
-                               delete_track(current);
-                               current = NULL;
-                               total_deleted++;
-                               done = 0;
-                               break;
+               for( Track* track=first, *nxt=0; done && track; track=nxt ) {
+                       nxt = track->next;
+                       if( gang ) {
+                               while( nxt && !nxt->master ) nxt = nxt->next;
                        }
                        }
+                       if( !track->is_armed() ) continue;
+                       delete_track(track);
+                       ++total_deleted;
                }
        }
        return total_deleted;
                }
        }
        return total_deleted;
@@ -555,7 +590,7 @@ void Tracks::move_edits(ArrayList<Edit*> *in_edits, Track *track, double positio
        int current_aedit = 0, current_vedit = 0;
 //printf("Tracks::move_edits 1\n");
        for( Track *dest_track=track; dest_track; dest_track=dest_track->next ) {
        int current_aedit = 0, current_vedit = 0;
 //printf("Tracks::move_edits 1\n");
        for( Track *dest_track=track; dest_track; dest_track=dest_track->next ) {
-               if( !dest_track->record ) continue;
+               if( !dest_track->is_armed() ) continue;
 // Need a local copy of the source edit since the original source edit may
 // change in the editing operation.
 // Get source edit
 // Need a local copy of the source edit since the original source edit may
 // change in the editing operation.
 // Get source edit
@@ -612,7 +647,7 @@ void Tracks::move_edits(ArrayList<Edit*> *in_edits, Track *track, double positio
                }
 
                FileXML track_xml;
                }
 
                FileXML track_xml;
-               source_track->copy(source_start, source_end, &track_xml, "");
+               source_track->copy(COPY_TRACKS, source_start, source_end, &track_xml, "");
                if( !track_xml.read_tag() )
                        clip_track->load(&track_xml, 0, LOAD_ALL);
 
                if( !track_xml.read_tag() )
                        clip_track->load(&track_xml, 0, LOAD_ALL);
 
@@ -662,6 +697,7 @@ void Tracks::move_effect(Plugin *plugin, Track *track, int64_t position)
                                start, length, plugin->plugin_type);
        result->copy_from(plugin);
        result->shift(position - plugin->startproject);
                                start, length, plugin->plugin_type);
        result->copy_from(plugin);
        result->shift(position - plugin->startproject);
+       result->gui_id = plugin->gui_id;
 
 // Clear new plugin from old set
        plugin->plugin_set->clear(plugin->startproject,
 
 // Clear new plugin from old set
        plugin->plugin_set->clear(plugin->startproject,
@@ -711,7 +747,7 @@ int Tracks::concatenate_tracks(int edit_plugins, int edit_autos)
                        output_track;
                        output_track = output_track->next)
                        if(output_track->data_type == data_type &&
                        output_track;
                        output_track = output_track->next)
                        if(output_track->data_type == data_type &&
-                               output_track->record) break;
+                               output_track->is_armed()) break;
 
                first_output_track = output_track;
 
 
                first_output_track = output_track;
 
@@ -722,7 +758,7 @@ int Tracks::concatenate_tracks(int edit_plugins, int edit_autos)
                {
                        if(input_track->data_type == data_type &&
                                input_track->play &&
                {
                        if(input_track->data_type == data_type &&
                                input_track->play &&
-                               !input_track->record) break;
+                               !input_track->is_armed()) break;
                }
 
 
                }
 
 
@@ -746,7 +782,7 @@ int Tracks::concatenate_tracks(int edit_plugins, int edit_autos)
                                {
 
                                        if(input_track->data_type == data_type &&
                                {
 
                                        if(input_track->data_type == data_type &&
-                                               !input_track->record &&
+                                               !input_track->is_armed() &&
                                                input_track->play) break;
                                }
 
                                                input_track->play) break;
                                }
 
@@ -755,7 +791,7 @@ int Tracks::concatenate_tracks(int edit_plugins, int edit_autos)
                                        output_track = output_track->next)
                                {
                                        if(output_track->data_type == data_type &&
                                        output_track = output_track->next)
                                {
                                        if(output_track->data_type == data_type &&
-                                               output_track->record) break;
+                                               output_track->is_armed()) break;
                                }
 
                                if(!output_track)
                                }
 
                                if(!output_track)
@@ -800,30 +836,91 @@ void Tracks::change_plugins(SharedLocation &old_location, SharedLocation &new_lo
 // =========================================== EDL editing
 
 
 // =========================================== EDL editing
 
 
-int Tracks::copy(double start,
-       double end,
-       int all,
-       FileXML *file,
-       const char *output_path)
+int Tracks::copy(int copy_flags, double start, double end,
+               FileXML *file, const char *output_path)
 {
 {
-// nothing selected
-       if(start == end && !all) return 1;
+       int all = (copy_flags & COPY_ALL) ? 1 : 0;
+// if nothing selected
+       if( start == end && !all ) return 1;
+       for( Track *track=first; track; track=track->next ) {
+               if( track->is_armed() || all )
+                       track->copy(copy_flags, start, end, file, output_path);
+       }
+       return 0;
+}
 
 
-       Track* current;
 
 
-       for(current = first;
-               current;
-               current = NEXT)
-       {
-               if(current->record || all)
-               {
-                       current->copy(start, end, file,output_path);
+
+int Tracks::roll_track_up(Track *track)
+{
+       if( first == last ) return 1;
+       int n = 1;
+       Track *src = track, *dst = src->previous;
+       if( edl->session->gang_tracks != GANG_NONE ) {
+               while( src && !src->master ) src = src->previous;
+               if( !src ) src = first;
+               Track *nxt = src->next;
+               while( nxt && !nxt->master ) { ++n;  nxt = nxt->next; }
+               dst = src->previous;
+               while( dst && !dst->master ) { dst = dst->previous; }
+       }
+       if( src == dst ) return 1;
+       roll_tracks(src, dst, n);
+       return 0;
+}
+
+int Tracks::roll_track_down(Track *track)
+{
+       if( first == last ) return 1;
+       int n = 1;
+       Track *src = track, *dst = src->next;
+       if( edl->session->gang_tracks != GANG_NONE ) {
+               while( src && !src->master ) src = src->previous;
+               if( !src ) src = first;
+               Track *nxt = src->next;
+               while( nxt && !nxt->master ) { ++n;  nxt = nxt->next; }
+               if( nxt ) {
+                       nxt = nxt->next;
+                       while( nxt && !nxt->master ) { nxt = nxt->next; }
                }
                }
+               else
+                       nxt = first;
+               dst = nxt;
        }
        }
+       else
+               dst = !dst ? first : dst->next;
+       if( src == dst ) return 1;
+       roll_tracks(src, dst, n);
+       return 0;
+}
 
 
+
+int Tracks::roll_tracks_up()
+{
+       if( first == last ) return 1;
+       int n = 1;
+       Track *src = first, *dst = 0;
+       if( edl->session->gang_tracks != GANG_NONE ) {
+               Track *nxt = src->next;
+               while( nxt && !nxt->master ) { ++n;  nxt = nxt->next; }
+       }
+       if( src == dst ) return 1;
+       roll_tracks(src, dst, n);
        return 0;
 }
 
        return 0;
 }
 
+int Tracks::roll_tracks_down()
+{
+       if( first == last ) return 1;
+       int n = 1;
+       Track *src = last, *dst = first;
+       if( edl->session->gang_tracks != GANG_NONE ) {
+               while( src && !src->master ) { ++n;  src = src->previous; }
+       }
+       if( src == dst ) return 1;
+       roll_tracks(src, dst, n);
+       return 0;
+}
 
 
 int Tracks::move_track_up(Track *track)
 
 
 int Tracks::move_track_up(Track *track)
@@ -832,20 +929,7 @@ int Tracks::move_track_up(Track *track)
        if(!next_track) next_track = last;
 
        change_modules(number_of(track), number_of(next_track), 1);
        if(!next_track) next_track = last;
 
        change_modules(number_of(track), number_of(next_track), 1);
-
-// printf("Tracks::move_track_up 1 %p %p\n", track, next_track);
-// int count = 0;
-// for(Track *current = first; current && count < 5; current = NEXT, count++)
-//     printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
-// printf("Tracks::move_track_up 2\n");
-//
        swap(track, next_track);
        swap(track, next_track);
-
-// count = 0;
-// for(Track *current = first; current && count < 5; current = NEXT, count++)
-//     printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
-// printf("Tracks::move_track_up 3\n");
-
        return 0;
 }
 
        return 0;
 }
 
@@ -862,24 +946,15 @@ int Tracks::move_track_down(Track *track)
 
 int Tracks::move_tracks_up()
 {
 
 int Tracks::move_tracks_up()
 {
-       Track *track, *next_track;
        int result = 0;
        int result = 0;
-
-       for(track = first;
-               track;
-               track = next_track)
-       {
-               next_track = track->next;
-
-               if(track->record)
-               {
-                       if(track->previous)
-                       {
-                               change_modules(number_of(track->previous), number_of(track), 1);
-
-                               swap(track->previous, track);
-                               result = 1;
-                       }
+       Track *next = first;
+       while( next ) {
+               Track *track = next;  next = track->next;
+               if( !track->armed ) continue;
+               if( track->previous ) {
+                       change_modules(number_of(track->previous), number_of(track), 1);
+                       swap(track->previous, track);
+                       result = 1;
                }
        }
 
                }
        }
 
@@ -888,38 +963,27 @@ int Tracks::move_tracks_up()
 
 int Tracks::move_tracks_down()
 {
 
 int Tracks::move_tracks_down()
 {
-       Track *track, *previous_track;
        int result = 0;
        int result = 0;
-
-       for(track = last;
-               track;
-               track = previous_track)
-       {
-               previous_track = track->previous;
-
-               if(track->record)
-               {
-                       if(track->next)
-                       {
-                               change_modules(number_of(track), number_of(track->next), 1);
-
-                               swap(track, track->next);
-                               result = 1;
-                       }
+       Track *prev = last;
+       while( prev ) {
+               Track *track = prev;  prev = track->previous;
+               if( !track->armed ) continue;
+               if( track->next ) {
+                       change_modules(number_of(track), number_of(track->next), 1);
+                       swap(track, track->next);
+                       result = 1;
                }
        }
 
        return result;
 }
 
                }
        }
 
        return result;
 }
 
-
-
 void Tracks::paste_audio_transition(PluginServer *server)
 {
        for(Track *current = first; current; current = NEXT)
        {
                if(current->data_type == TRACK_AUDIO &&
 void Tracks::paste_audio_transition(PluginServer *server)
 {
        for(Track *current = first; current; current = NEXT)
        {
                if(current->data_type == TRACK_AUDIO &&
-                       current->record)
+                       current->is_armed())
                {
                        int64_t position = current->to_units(
                                edl->local_session->get_selectionstart(), 0);
                {
                        int64_t position = current->to_units(
                                edl->local_session->get_selectionstart(), 0);
@@ -949,7 +1013,6 @@ void Tracks::paste_automation(double selectionstart,
        Track* current_atrack = 0;
        Track* current_vtrack = 0;
        Track* dst_track = 0;
        Track* current_atrack = 0;
        Track* current_vtrack = 0;
        Track* dst_track = 0;
-       int src_type;
        int result = 0;
        double length;
        double frame_rate = edl->session->frame_rate;
        int result = 0;
        double length;
        double frame_rate = edl->session->frame_rate;
@@ -958,10 +1021,9 @@ void Tracks::paste_automation(double selectionstart,
        string[0] = 0;
 
 // Search for start
        string[0] = 0;
 
 // Search for start
-       do{
-         result = file->read_tag();
-       }while(!result &&
-               !file->tag.title_is("AUTO_CLIPBOARD"));
+       do {
+               result = file->read_tag();
+       } while(!result && !file->tag.title_is("AUTO_CLIPBOARD"));
 
        if(!result)
        {
 
        if(!result)
        {
@@ -969,7 +1031,6 @@ void Tracks::paste_automation(double selectionstart,
                frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
                sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
 
                frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
                sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
 
-
                do
                {
                        result = file->read_tag();
                do
                {
                        result = file->read_tag();
@@ -984,20 +1045,14 @@ void Tracks::paste_automation(double selectionstart,
                                if(file->tag.title_is("TRACK"))
                                {
                                        file->tag.get_property("TYPE", string);
                                if(file->tag.title_is("TRACK"))
                                {
                                        file->tag.get_property("TYPE", string);
-                                       if(!strcmp(string, "AUDIO"))
-                                       {
-                                               src_type = TRACK_AUDIO;
-                                       }
-                                       else
-                                       {
-                                               src_type = TRACK_VIDEO;
-                                       }
-
+                                       double src_rate = !strcmp(string, "AUDIO") ?
+                                               sample_rate : frame_rate;
+                                       double src_length = length / src_rate;
 // paste to any media type
                                        if(typeless)
                                        {
                                                if(!current_track) current_track = first;
 // paste to any media type
                                        if(typeless)
                                        {
                                                if(!current_track) current_track = first;
-                                               while(current_track && !current_track->record)
+                                               while(current_track && !current_track->is_armed())
                                                        current_track = current_track->next;
                                                dst_track = current_track;
                                        }
                                                        current_track = current_track->next;
                                                dst_track = current_track;
                                        }
@@ -1012,7 +1067,7 @@ void Tracks::paste_automation(double selectionstart,
 
                                                while(current_atrack &&
                                                        (current_atrack->data_type != TRACK_AUDIO ||
 
                                                while(current_atrack &&
                                                        (current_atrack->data_type != TRACK_AUDIO ||
-                                                       !current_atrack->record))
+                                                       !current_atrack->is_armed()))
                                                        current_atrack = current_atrack->next;
                                                dst_track = current_atrack;
                                        }
                                                        current_atrack = current_atrack->next;
                                                dst_track = current_atrack;
                                        }
@@ -1026,7 +1081,7 @@ void Tracks::paste_automation(double selectionstart,
 
                                                while(current_vtrack &&
                                                        (current_vtrack->data_type != TRACK_VIDEO ||
 
                                                while(current_vtrack &&
                                                        (current_vtrack->data_type != TRACK_VIDEO ||
-                                                       !current_vtrack->record))
+                                                       !current_vtrack->is_armed()))
                                                        current_vtrack = current_vtrack->next;
 
                                                dst_track = current_vtrack;
                                                        current_vtrack = current_vtrack->next;
 
                                                dst_track = current_vtrack;
@@ -1034,22 +1089,9 @@ void Tracks::paste_automation(double selectionstart,
 
                                        if(dst_track)
                                        {
 
                                        if(dst_track)
                                        {
-                                               double frame_rate2 = frame_rate;
-                                               double sample_rate2 = sample_rate;
-
-                                               if(src_type != dst_track->data_type)
-                                               {
-                                                       frame_rate2 = sample_rate;
-                                                       sample_rate2 = frame_rate;
-                                               }
-
-                                               dst_track->paste_automation(selectionstart,
-                                                       length,
-                                                       frame_rate2,
-                                                       sample_rate2,
-                                                       file,
-                                                       default_only,
-                                                       active_only);
+                                               dst_track->paste_automation(file,
+                                                       selectionstart, src_length, src_rate,
+                                                       default_only, active_only);
                                        }
                                }
                        }
                                        }
                                }
                        }
@@ -1066,6 +1108,20 @@ void Tracks::paste_automation(double selectionstart,
 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
 {
        dest_edit->insert_transition(server->title);
 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
 {
        dest_edit->insert_transition(server->title);
+       if( edl->session->gang_tracks == GANG_NONE ) return;
+       Track *track = dest_edit->track;
+       double pos = track->from_units(dest_edit->startproject);
+       for( Track *current=first; current; current=current->next ) {
+               if( current == track ) continue;
+               if( current->data_type != track->data_type ) continue;
+               if( !current->armed_gang(track) ) continue;
+               int64_t track_pos = current->to_units(pos, 1);
+               Edit *edit = current->edits->editof(track_pos, PLAY_FORWARD, 0);
+               if( !edit ) continue;
+               double edit_pos = track->from_units(edit->startproject);
+               if( !edl->equivalent(pos, edit_pos) ) continue;
+               edit->insert_transition(server->title);
+       }
 }
 
 void Tracks::paste_video_transition(PluginServer *server, int first_track)
 }
 
 void Tracks::paste_video_transition(PluginServer *server, int first_track)
@@ -1073,7 +1129,7 @@ void Tracks::paste_video_transition(PluginServer *server, int first_track)
        for(Track *current = first; current; current = NEXT)
        {
                if(current->data_type == TRACK_VIDEO &&
        for(Track *current = first; current; current = NEXT)
        {
                if(current->data_type == TRACK_VIDEO &&
-                       current->record)
+                       current->is_armed())
                {
                        int64_t position = current->to_units(
                                edl->local_session->get_selectionstart(), 0);
                {
                        int64_t position = current->to_units(
                                edl->local_session->get_selectionstart(), 0);
@@ -1106,7 +1162,7 @@ int Tracks::paste_silence(double start,
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if(current_track->record)
+               if(current_track->is_armed())
                {
                        current_track->paste_silence(start,
                                end,
                {
                        current_track->paste_silence(start,
                                end,
@@ -1142,7 +1198,7 @@ int Tracks::modify_edithandles(double &oldposition, double &newposition,
        int edit_plugins, int edit_autos, int group_id)
 {
        for( Track *track=first; track; track=track->next ) {
        int edit_plugins, int edit_autos, int group_id)
 {
        for( Track *track=first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                track->modify_edithandles(oldposition, newposition,
                        currentend, handle_mode, edit_labels,
                        edit_plugins, edit_autos, group_id);
                track->modify_edithandles(oldposition, newposition,
                        currentend, handle_mode, edit_labels,
                        edit_plugins, edit_autos, group_id);
@@ -1157,7 +1213,7 @@ int Tracks::modify_pluginhandles(double &oldposition, double &newposition,
        int edit_autos, Edits *trim_edits)
 {
        for( Track *track=first; track; track=track->next ) {
        int edit_autos, Edits *trim_edits)
 {
        for( Track *track=first; track; track=track->next ) {
-               if( !track->record ) continue;
+               if( !track->is_armed() ) continue;
                track->modify_pluginhandles(oldposition, newposition,
                        currentend, handle_mode, edit_labels,
                        edit_autos, trim_edits);
                track->modify_pluginhandles(oldposition, newposition,
                        currentend, handle_mode, edit_labels,
                        edit_autos, trim_edits);
@@ -1198,7 +1254,7 @@ int Tracks::scale_time(float rate_scale, int ignore_record, int scale_edits, int
                current_track;
                current_track = current_track->next)
        {
                current_track;
                current_track = current_track->next)
        {
-               if((current_track->record || ignore_record) &&
+               if((current_track->is_armed() || ignore_record) &&
                        current_track->data_type == TRACK_VIDEO)
                {
                        current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);
                        current_track->data_type == TRACK_VIDEO)
                {
                        current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);