X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fedit.C;h=f538a503e43de737614bcf25eeb6dc64075e18a4;hp=40e7151a93aed99773d626f21e1ed999fe484412;hb=9ffdfbe8e6fa7daaad4dcfdd46b6ac7b6e7a47e8;hpb=f4cba337b328ed1842085076c3e2c8244e3a94bd diff --git a/cinelerra-5.1/cinelerra/edit.C b/cinelerra-5.1/cinelerra/edit.C index 40e7151a..f538a503 100644 --- a/cinelerra-5.1/cinelerra/edit.C +++ b/cinelerra-5.1/cinelerra/edit.C @@ -29,6 +29,7 @@ #include "edlsession.h" #include "filexml.h" #include "filesystem.h" +#include "labels.h" #include "localsession.h" #include "plugin.h" #include "mainsession.h" @@ -51,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) @@ -60,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() @@ -82,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; @@ -232,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() @@ -242,26 +259,42 @@ int Edit::silence() asset || nested_edl : *((SEdit *)this)->get_text()) ? 0 : 1; } -void Edit::mute() + +void Edit::set_selected(int v) { - if( track->data_type != TRACK_SUBTITLE ) { - asset = 0; - nested_edl = 0; + 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 - *((SEdit *)this)->get_text() = 0; + edl->tracks->set_group_selected(group_id, v); } -void Edit::set_selected(int v) -{ - if( group_id ) - edl->tracks->set_group_selected(group_id, v); - else - is_selected = v >= 0 ? v : !is_selected ? 1 : 0; +// 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; @@ -284,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 @@ -379,33 +418,32 @@ 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 : "", - asset, - asset ? asset->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, group_id %d, is_selected %d\n", - channel, color, group_id, is_selected); - if(transition) - { + fprintf(fp," channel %d, color %08x, hard lt/rt %d/%d" + " group_id %d, is_selected %d\n", + channel, color, hard_left, hard_right, group_id, is_selected); + if( transition ) { fprintf(fp," TRANSITION %p\n", transition); transition->dump(fp); } - fprintf(fp," startsource %jd startproject %jd hard lt/rt %d/%d length %jd\n", - startsource, startproject, hard_left, hard_right, length); fflush(fp); + fprintf(fp," startsource %jd startproject %jd length %jd\n", + startsource, startproject, length); + fflush(fp); return 0; } @@ -426,353 +464,220 @@ int Edit::load_properties(FileXML *file, int64_t &startproject) void Edit::shift(int64_t difference) { -//printf("Edit::shift 1 %p %jd %jd\n", this, startproject, difference); startproject += difference; -//printf("Edit::shift 2 %jd %jd\n", startproject, difference); } -int Edit::shift_start_in(int edit_mode, - int64_t newposition, - int64_t oldposition, - int edit_edits, - int edit_labels, - int edit_plugins, - int edit_autos, - Edits *trim_edits) +void Edit::trim(int64_t difference) { - int64_t cut_length = newposition - oldposition; - int64_t end_previous_source, end_source; - - if(edit_mode == MOVE_ALL_EDITS) - { - if(cut_length < length) - { // clear partial - edits->clear_recursive(oldposition, - newposition, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); - } - else - { // clear entire - edits->clear_recursive(oldposition, - startproject + length, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); - } - } - else - if(edit_mode == MOVE_ONE_EDIT) - { -// Paste silence and cut -//printf("Edit::shift_start_in 1\n"); - if(!previous) - { - Edit *new_edit = edits->create_edit(); - new_edit->startproject = this->startproject; - new_edit->length = 0; - edits->insert_before(this, - new_edit); - } -//printf("Edit::shift_start_in 2 %p\n", previous); - - end_previous_source = previous->get_source_end(previous->startsource + previous->length + cut_length); - if(end_previous_source > 0 && - previous->startsource + previous->length + cut_length > end_previous_source) - cut_length = end_previous_source - previous->startsource - previous->length; - - if(cut_length < length) - { // Move in partial - startproject += cut_length; - startsource += cut_length; - length -= cut_length; - previous->length += cut_length; -//printf("Edit::shift_start_in 2\n"); - } - else - { // Clear entire edit - cut_length = length; - previous->length += cut_length; - for(Edit* current_edit = this; current_edit; current_edit = current_edit->next) - { - current_edit->startproject += cut_length; - } - edits->clear_recursive(oldposition + cut_length, - startproject + cut_length, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); - } -//printf("Edit::shift_start_in 3\n"); + length += difference; + if( startproject < 0 ) { + if( (startsource+=startproject) < 0 ) startsource = 0; + if( (length+=startproject) < 0 ) length = 0; + startproject = 0; } - else - if(edit_mode == MOVE_NO_EDITS) - { - end_source = get_source_end(startsource + length + cut_length); - if(end_source > 0 && startsource + length + cut_length > end_source) - cut_length = end_source - startsource - length; - - startsource += cut_length; + if( startsource < 0 ) + startsource = 0; + int64_t src_len = get_source_end(INT64_MAX); + if( startsource + length > src_len ) { + length = src_len - startsource; + if( length < 0 ) length = 0; } - return 0; + if( length < 0 ) + length = 0; } -int Edit::shift_start_out(int edit_mode, - int64_t newposition, - int64_t oldposition, - int edit_edits, - int edit_labels, - int edit_plugins, - int edit_autos, - Edits *trim_edits) +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 = oldposition - newposition; - - - if(asset || nested_edl) - { - int64_t end_source = get_source_end(1); - -//printf("Edit::shift_start_out 1 %jd %jd\n", startsource, cut_length); - if(end_source > 0 && startsource < cut_length) - { - cut_length = startsource; + int64_t cut_length = newposition - oldposition; + 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; + + switch( edit_mode ) { + case MOVE_RIPPLE: + 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; + length -= cut_length; + break; + case MOVE_SLIP: + edits_moved = 1; + startsource -= cut_length; + 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 ) { + next->startproject += cut_length; + next->startsource += cut_length; + next->trim(-cut_length); } - } - - if(edit_mode == MOVE_ALL_EDITS) - { -//printf("Edit::shift_start_out 10 %jd\n", cut_length); + break; + case MOVE_EDGE: + edits_moved = 1; startsource -= cut_length; length += cut_length; + for( Edit *edit=next; edit; edit=edit->next ) + edit->startproject += cut_length; + break; + } + trim(0); + return follow_edits(start, end, cut_length, edits_moved, rest_moved, + edit_labels, edit_autos, edit_plugins, trim_edits); +} - if(edit_autos) - edits->shift_keyframes_recursive(startproject, - cut_length); - if(edit_plugins) - edits->shift_effects_recursive(startproject, - cut_length, - edit_autos); - - for(Edit* current_edit = next; current_edit; current_edit = current_edit->next) - { - current_edit->startproject += cut_length; - } +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; + 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(edit_mode == MOVE_ONE_EDIT) - { - if(previous) - { - if(cut_length < previous->length) - { // Cut into previous edit - previous->length -= cut_length; - startproject -= cut_length; - startsource -= cut_length; - length += cut_length; - } - else - { // Clear entire previous edit - cut_length = previous->length; - previous->length = 0; - length += cut_length; - startsource -= cut_length; - startproject -= cut_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; + + switch( edit_mode ) { + case MOVE_RIPPLE: + 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; + next->startsource += cut_length; + next->trim(-cut_length); } - } - else - if(edit_mode == MOVE_NO_EDITS) - { + break; + case MOVE_SLIP: + edits_moved = 1; startsource -= cut_length; + 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 ) { + next->startproject += cut_length; + next->startsource += cut_length; + next->trim(-cut_length); + } + break; } - -// Fix infinite length files - if(startsource < 0) startsource = 0; - return 0; -} - -int Edit::shift_end_in(int edit_mode, - int64_t newposition, - int64_t oldposition, - int edit_edits, - int edit_labels, - int edit_plugins, - int edit_autos, - Edits *trim_edits) -{ - int64_t cut_length = oldposition - newposition; - - if(edit_mode == MOVE_ALL_EDITS) - { -//printf("Edit::shift_end_in 1\n"); - if(newposition > startproject) - { // clear partial edit -//printf("Edit::shift_end_in %p %p\n", track->edits, edits); - edits->clear_recursive(newposition, - oldposition, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); + trim(0); + return follow_edits(start, end, cut_length, edits_moved, rest_moved, + edit_labels, edit_autos, edit_plugins, trim_edits); +} + +int Edit::follow_edits(int64_t start, int64_t end, int64_t cut_length, + int edits_moved, int rest_moved, int edit_labels, int edit_autos, + int edit_plugins, Edits *trim_edits) +{ + if( edits_moved && rest_moved ) { + if( edit_labels ) { + double cut_len = track->from_units(cut_length); + double start_pos = edits->track->from_units(start); + if( cut_len < 0 ) + edits->edl->labels->clear(start_pos + cut_len, start_pos, 1); + else if( cut_len > 0 ) + edits->edl->labels->insert(start_pos, cut_len); } - else - { // clear entire edit - edits->clear_recursive(startproject, - oldposition, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); + if( cut_length < 0 ) + track->clear(start + cut_length, start, + 0, 0, edit_autos, edit_plugins, trim_edits); + else if( cut_length > 0 ) { + if( edit_autos ) + track->shift_keyframes(start, cut_length); + if( edit_plugins ) + track->shift_effects(start, cut_length, 1, trim_edits); } } - else - if(edit_mode == MOVE_ONE_EDIT) - { - if(next) - { - if(next->asset) - { - int64_t end_source = next->get_source_end(1); - - if(end_source > 0 && next->startsource - cut_length < 0) - { - cut_length = next->startsource; - } - } - - if(cut_length < length) - { - length -= cut_length; - next->startproject -= cut_length; - next->startsource -= cut_length; - next->length += cut_length; -//printf("Edit::shift_end_in 2 %d\n", cut_length); + else if( edits_moved ) { + if( edit_labels ) { + double cut_len = track->from_units(cut_length); + double start_pos = edits->track->from_units(start); + edits->edl->labels->insert(start_pos, cut_len); + double end_pos = edits->track->from_units(end); + edits->edl->labels->insert(end_pos + cut_len, -cut_len); + } + if( edit_autos ) { + if( cut_length > 0 ) { + track->clear(end, end+cut_length, 0, 0, 0, 1, 0); + track->shift_keyframes(start, cut_length); } - else - { - cut_length = length; - next->length += cut_length; - next->startsource -= cut_length; - next->startproject -= cut_length; - length -= cut_length; + else if( cut_length < 0 ) { + track->clear(start+cut_length, start, 0, 0, 0, 1, 0); + track->shift_keyframes(end+cut_length, -cut_length); } } - else - { - if(cut_length < length) - { - length -= cut_length; + if( edit_plugins ) { + if( cut_length > 0 ) { + track->clear(end, end+cut_length, 0, 0, -1, 0, 0); + track->shift_effects(start, cut_length, 1, 0); } - else - { - cut_length = length; - edits->clear_recursive(startproject, - oldposition, - edit_edits, - edit_labels, - edit_plugins, - edit_autos, - trim_edits); + else if( cut_length < 0 ) { + track->clear(start+cut_length, start, 0, 0, -1, 0, 0); + track->shift_effects(end+cut_length, -cut_length, 1, 0); } } } - else -// Does nothing for plugins - if(edit_mode == MOVE_NO_EDITS) - { -//printf("Edit::shift_end_in 3\n"); - int64_t end_source = get_source_end(1); - if(end_source > 0 && startsource < cut_length) - { - cut_length = startsource; + else if( rest_moved ) { + if( edit_labels ) { + double cut_len = track->from_units(cut_length); + double end_pos = edits->track->from_units(end); + if( cut_len < 0 ) + edits->edl->labels->clear(end_pos + cut_len, end_pos, 1); + else if( cut_len > 0 ) + edits->edl->labels->insert(end_pos, cut_len); + } + if( cut_length < 0 ) + track->clear(end + cut_length, end, + 0, 0, edit_autos, edit_plugins, trim_edits); + else if( cut_length > 0 ) { + if( edit_autos ) + track->shift_keyframes(end, cut_length); + if( edit_plugins ) + track->shift_effects(end, cut_length, 1, trim_edits); } - startsource -= cut_length; } return 0; } -int Edit::shift_end_out(int edit_mode, - int64_t newposition, - int64_t oldposition, - int edit_edits, - int edit_labels, - int edit_plugins, - int edit_autos, - Edits *trim_edits) -{ - int64_t cut_length = newposition - oldposition; - int64_t endsource = get_source_end(startsource + length + cut_length); - -// check end of edit against end of source file - if(endsource > 0 && startsource + length + cut_length > endsource) - cut_length = endsource - startsource - length; -//printf("Edit::shift_end_out 1 %jd %d %d %d\n", oldposition, newposition, this->length, cut_length); - if(edit_mode == MOVE_ALL_EDITS) - { -// Extend length - this->length += cut_length; - -// Effects are shifted in length extension - if(edit_plugins) - edits->shift_effects_recursive(oldposition /* startproject */, - cut_length, - edit_autos); - if(edit_autos) - edits->shift_keyframes_recursive(oldposition /* startproject */, - cut_length); - - for(Edit* current_edit = next; current_edit; current_edit = current_edit->next) - { - current_edit->startproject += cut_length; - } - } - else - if(edit_mode == MOVE_ONE_EDIT) - { - if(next) - { - if(cut_length < next->length) - { - length += cut_length; - next->startproject += cut_length; - next->startsource += cut_length; - next->length -= cut_length; -//printf("Edit::shift_end_out %d cut_length=%d\n", __LINE__, cut_length); - } - else - { -//printf("Edit::shift_end_out %d cut_length=%d next->length=%d\n", __LINE__, cut_length, next->length); - cut_length = next->length; - next->startproject += next->length; - next->startsource += next->length; - next->length = 0; - length += cut_length; -//track->dump(); - } - } - else - { - length += cut_length; - } - } - else - if(edit_mode == MOVE_NO_EDITS) - { - startsource += cut_length; - } - return 0; -} int Edit::popup_transition(float view_start, float zoom_units, int cursor_x, int cursor_y) { @@ -795,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 @@ -807,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)