improve delays created by vicon drawing locks, reset_cache segv fix, gang track toolt...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / edit.C
index 2c8eefcfbb0698a8b56553ed3190059cd92efac0..f538a503e43de737614bcf25eeb6dc64075e18a4 100644 (file)
@@ -52,6 +52,7 @@ Edit::Edit(EDL *edl, Track *track)
        this->track = track;
        if(track) this->edits = track->edits;
        id = EDL::next_id();
+       orig_id = id;
 }
 
 Edit::Edit(EDL *edl, Edits *edits)
@@ -61,6 +62,7 @@ Edit::Edit(EDL *edl, Edits *edits)
        this->edits = edits;
        if(edits) this->track = edits->track;
        id = EDL::next_id();
+       orig_id = id;
 }
 
 Edit::~Edit()
@@ -83,7 +85,6 @@ void Edit::reset()
        channel = 0;
        user_title[0] = 0;
        nested_edl = 0;
-       is_plugin = 0;
        is_selected = 0;
        hard_left = 0;
        hard_right = 0;
@@ -233,8 +234,23 @@ void Edit::insert_transition(char *title)
 
 void Edit::detach_transition()
 {
-       if(transition) delete transition;
+       delete transition;
        transition = 0;
+       if( edl->session->gang_tracks == GANG_NONE ) return;
+       double pos = track->from_units(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 ) continue;
+               double edit_pos = track->from_units(edit->startproject);
+               if( !edl->equivalent(pos, edit_pos) ) continue;
+               delete edit->transition;
+               edit->transition = 0;
+       }
 }
 
 int Edit::silence()
@@ -246,14 +262,39 @@ int Edit::silence()
 
 void Edit::set_selected(int v)
 {
-       if( group_id )
-               edl->tracks->set_group_selected(group_id, v);
+       if( !group_id ) {
+               if( v < 0 ) v = !is_selected ? 1 : 0;
+               int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
+               select_affected_edits(v, gang);
+       }
        else
-               is_selected = v >= 0 ? v : !is_selected ? 1 : 0;
+               edl->tracks->set_group_selected(group_id, v);
 }
 
+// gang<0: rest of tracks, gang==0: this track, gang>0: to next master
+void Edit::select_affected_edits(int v, int gang)
+{
+       is_selected = v;
+       if( !gang ) return;
+       double position = track->from_units(startproject);
+       for( Track *current=track->next; current; current=current->next ) {
+               if( gang > 0 && current->master ) break;
+               if( !current->is_armed() ) continue;
+               for( Edit *edit=current->edits->first; edit; edit=edit->next ) {
+                       if( edit->silence() ) continue;
+                       double start = current->from_units(edit->startproject);
+                       if( edl->equivalent(start, position) ) {
+                               edit->is_selected = v;
+                               break;
+                       }
+               }
+       }
+}
+
+
 void Edit::copy_from(Edit *edit)
 {
+       this->orig_id = edit->orig_id;
        this->nested_edl = edl->nested_edls.get_nested(edit->nested_edl);
        this->asset = edl->assets->update(edit->asset);
        this->startsource = edit->startsource;
@@ -276,6 +317,12 @@ void Edit::copy_from(Edit *edit)
        this->channel = edit->channel;
 }
 
+void Edit::clone_from(Edit *edit)
+{
+       copy_from(edit);
+       edit->orig_id = edit->id;
+}
+
 void Edit::equivalent_output(Edit *edit, int64_t *result)
 {
 // End of edit changed
@@ -371,20 +418,20 @@ double Edit::picon_w()
                w = nested_edl->session->output_w;
                h = nested_edl->session->output_h;
        }
-       return w>0 && h>0 ? ((double)edl->local_session->zoom_track*w)/h : 0;
+       return w>0 && h>0 ? ((double)track->data_h*w)/h : 0;
 }
 
 int Edit::picon_h()
 {
-       return edl->local_session->zoom_track;
+       return track->data_h;
 }
 
 
 int Edit::dump(FILE *fp)
 {
        fprintf(fp,"     EDIT %p\n", this); fflush(fp);
-       fprintf(fp,"      nested_edl=%p %s asset=%p %s\n",
-               nested_edl, nested_edl ? nested_edl->path : "",
+       fprintf(fp,"      id %d, orig_id %d, nested_edl=%p %s asset=%p %s\n",
+               id, orig_id, nested_edl, nested_edl ? nested_edl->path : "",
                asset, asset ? asset->path : "");
        fflush(fp);
        fprintf(fp,"      channel %d, color %08x, hard lt/rt %d/%d"
@@ -443,19 +490,28 @@ int Edit::shift_start(int edit_mode, int64_t newposition, int64_t oldposition,
        int edit_labels, int edit_autos, int edit_plugins, Edits *trim_edits)
 {
        int64_t cut_length = newposition - oldposition;
-       if( !cut_length ) return 0;
+       int rest_moved = edit_mode == MOVE_RIPPLE || edit_mode == MOVE_EDGE ? 1 : 0;
+       if( cut_length > length )
+               cut_length = length;
+       else if( cut_length < -length )
+               cut_length = -length;
+
        int64_t start = startproject, end = start + length;
        Edit *prev = this->previous, *next = this->next;
-       int edits_moved = 0, rest_moved = 0;
+       int edits_moved = 0;
 
        switch( edit_mode ) {
        case MOVE_RIPPLE:
-               edits_moved = rest_moved = 1;
-               if( prev ) prev->trim(cut_length);
-               for( Edit *edit=this; edit; edit=edit->next )
+               edits_moved = 1;
+               startsource += cut_length;
+               cut_length = -cut_length;
+               length += cut_length;
+               for( Edit *edit=next; edit; edit=edit->next )
                        edit->startproject += cut_length;
                break;
        case MOVE_ROLL:
+               if( prev && prev->length + cut_length < 0 )
+                       cut_length = -prev->length;
                if( prev ) prev->trim(cut_length);
                startproject += cut_length;
                startsource += cut_length;
@@ -467,6 +523,10 @@ int Edit::shift_start(int edit_mode, int64_t newposition, int64_t oldposition,
                break;
        case MOVE_SLIDE:
                edits_moved = 1;
+               if( prev && prev->length + cut_length < 0 )
+                       cut_length = -prev->length;
+               if( next && next->length - cut_length < 0 )
+                       cut_length = next->length;
                if( prev ) prev->trim(cut_length);
                startproject += cut_length;
                if( next ) {
@@ -476,7 +536,7 @@ int Edit::shift_start(int edit_mode, int64_t newposition, int64_t oldposition,
                }
                break;
        case MOVE_EDGE:
-               edits_moved = rest_moved = 1;
+               edits_moved = 1;
                startsource -= cut_length;
                length += cut_length;
                for( Edit *edit=next; edit; edit=edit->next )
@@ -484,7 +544,6 @@ int Edit::shift_start(int edit_mode, int64_t newposition, int64_t oldposition,
                break;
        }
        trim(0);
-
        return follow_edits(start, end, cut_length, edits_moved, rest_moved,
                edit_labels, edit_autos, edit_plugins, trim_edits);
 }
@@ -493,19 +552,26 @@ int Edit::shift_end(int edit_mode, int64_t newposition, int64_t oldposition,
        int edit_labels, int edit_autos, int edit_plugins, Edits *trim_edits)
 {
        int64_t cut_length = newposition - oldposition;
-       if( !cut_length ) return 0;
+       int rest_moved = edit_mode == MOVE_RIPPLE || edit_mode == MOVE_EDGE ? 1 : 0;
+       if( cut_length > length ) {
+                if( !rest_moved ) cut_length = length;
+       }
+       else if( cut_length < -length )
+               cut_length = -length;
        int64_t start = startproject, end = start + length;
        Edit *prev = this->previous, *next = this->next;
-       int edits_moved = 0, rest_moved = 0;
+       int edits_moved = 0;
 
        switch( edit_mode ) {
        case MOVE_RIPPLE:
-               rest_moved = 1;
+       case MOVE_EDGE:
                length += cut_length;
                for( Edit *edit=next; edit; edit=edit->next )
                        edit->startproject += cut_length;
                break;
        case MOVE_ROLL:
+               if( next && next->length - cut_length < 0 )
+                       cut_length = next->length;
                length += cut_length;
                if( next ) {
                        next->startproject += cut_length;
@@ -519,6 +585,10 @@ int Edit::shift_end(int edit_mode, int64_t newposition, int64_t oldposition,
                break;
        case MOVE_SLIDE:
                edits_moved = 1;
+               if( prev && prev->length + cut_length < 0 )
+                       cut_length = -prev->length;
+               if( next && next->length - cut_length < 0 )
+                       cut_length = next->length;
                if( prev ) prev->trim(cut_length);
                startproject += cut_length;
                if( next ) {
@@ -527,15 +597,8 @@ int Edit::shift_end(int edit_mode, int64_t newposition, int64_t oldposition,
                        next->trim(-cut_length);
                }
                break;
-       case MOVE_EDGE:
-               edits_moved = 1;
-               if( prev ) prev->trim(cut_length);
-               startproject += cut_length;
-               length -= cut_length;
-               break;
        }
        trim(0);
-
        return follow_edits(start, end, cut_length, edits_moved, rest_moved,
                edit_labels, edit_autos, edit_plugins, trim_edits);
 }
@@ -583,11 +646,11 @@ int Edit::follow_edits(int64_t start, int64_t end, int64_t cut_length,
                }
                if( edit_plugins ) {
                        if( cut_length > 0 ) {
-                               track->clear(end, end+cut_length, 0, 0, 1, 0, 0);
+                               track->clear(end, end+cut_length, 0, 0, -1, 0, 0);
                                track->shift_effects(start, cut_length, 1, 0);
                        }
                        else if( cut_length < 0 ) {
-                               track->clear(start+cut_length, start, 0, 0, 1, 0, 0);
+                               track->clear(start+cut_length, start, 0, 0, -1, 0, 0);
                                track->shift_effects(end+cut_length, -cut_length, 1, 0);
                        }
                }
@@ -637,7 +700,7 @@ int Edit::select_handle(float view_start, float zoom_units, int cursor_x, int cu
 
        int64_t pixel1, pixel2;
        pixel1 = left;
-       pixel2 = pixel1 + 10;
+       pixel2 = pixel1 + xS(10);
 
 // test left edit
 // cursor_x is faked in acanvas
@@ -649,7 +712,7 @@ int Edit::select_handle(float view_start, float zoom_units, int cursor_x, int cu
 
        //int64_t endproject = startproject + length;
        pixel2 = right;
-       pixel1 = pixel2 - 10;
+       pixel1 = pixel2 - xS(10);
 
 // test right edit
        if(cursor_x >= pixel1 && cursor_x <= pixel2)