X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindowedit.C;h=458ced964e8f3418505b7d27ccf19adb80662dd0;hp=d458a78b0d5a8ad4f3a26b30f4b9eae8618489aa;hb=f62d927a25cb3b02f2197fde99c77df3005d41a7;hpb=e23393f4ff9f772ac8f47926cf490dc87a630ed4 diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index d458a78b..458ced96 100644 --- a/cinelerra-5.1/cinelerra/mwindowedit.C +++ b/cinelerra-5.1/cinelerra/mwindowedit.C @@ -27,6 +27,7 @@ #include "clip.h" #include "clipedit.h" #include "commercials.h" +#include "convert.h" #include "cplayback.h" #include "ctimebar.h" #include "cwindow.h" @@ -41,6 +42,7 @@ #include "gwindow.h" #include "gwindowgui.h" #include "keyframe.h" +#include "keyframes.h" #include "language.h" #include "labels.h" #include "levelwindow.h" @@ -82,87 +84,71 @@ void MWindow::add_audio_track_entry(int above, Track *dst) { - undo->update_undo_before(); - add_audio_track(above, dst); + undo_before(); + Track *track = add_audio_track(above, dst); + track->master = 1; save_backup(); - undo->update_undo_after(_("add track"), LOAD_ALL); + undo_after(_("add track"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); gui->activate_timeline(); - -// gui->get_scrollbars(0); -// gui->canvas->draw(); -// gui->patchbay->update(); -// gui->cursor->draw(1); -// gui->canvas->flash(); -// gui->canvas->activate(); cwindow->refresh_frame(CHANGE_EDL); } -void MWindow::add_video_track_entry(Track *dst) +void MWindow::add_video_track_entry(int above, Track *dst) { - undo->update_undo_before(); - add_video_track(1, dst); - undo->update_undo_after(_("add track"), LOAD_ALL); + undo_before(); + Track *track = add_video_track(above, dst); + track->master = 1; + undo_after(_("add track"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); gui->activate_timeline(); -// gui->get_scrollbars(0); -// gui->canvas->draw(); -// gui->patchbay->update(); -// gui->cursor->draw(1); -// gui->canvas->flash(); -// gui->canvas->activate(); cwindow->refresh_frame(CHANGE_EDL); save_backup(); } -void MWindow::add_subttl_track_entry(Track *dst) +void MWindow::add_subttl_track_entry(int above, Track *dst) { - undo->update_undo_before(); - add_subttl_track(1, dst); - undo->update_undo_after(_("add track"), LOAD_ALL); + undo_before(); + Track *track = add_subttl_track(above, dst); + track->master = 1; + undo_after(_("add track"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); gui->activate_timeline(); -// gui->get_scrollbars(0); -// gui->canvas->draw(); -// gui->patchbay->update(); -// gui->cursor->draw(1); -// gui->canvas->flash(); -// gui->canvas->activate(); cwindow->refresh_frame(CHANGE_EDL); save_backup(); } -int MWindow::add_audio_track(int above, Track *dst) +Track *MWindow::add_audio_track(int above, Track *dst) { - edl->tracks->add_audio_track(above, dst); + Track *track = edl->tracks->add_audio_track(above, dst); edl->tracks->update_y_pixels(theme); save_backup(); - return 0; + return track; } -int MWindow::add_video_track(int above, Track *dst) +Track *MWindow::add_video_track(int above, Track *dst) { - edl->tracks->add_video_track(above, dst); + Track *track = edl->tracks->add_video_track(above, dst); edl->tracks->update_y_pixels(theme); save_backup(); - return 0; + return track; } -int MWindow::add_subttl_track(int above, Track *dst) +Track *MWindow::add_subttl_track(int above, Track *dst) { - edl->tracks->add_subttl_track(above, dst); + Track *track = edl->tracks->add_subttl_track(above, dst); edl->tracks->update_y_pixels(theme); save_backup(); - return 0; + return track; } void MWindow::asset_to_all() @@ -174,7 +160,7 @@ void MWindow::asset_to_all() { int w, h; - undo->update_undo_before(); + undo_before(); // Get w and h w = indexable->get_w(); @@ -196,13 +182,13 @@ void MWindow::asset_to_all() for( Track *current=edl->tracks->first; current; current=NEXT ) { if( current->data_type == TRACK_VIDEO /* && - current->record */ ) { + current->is_armed() */ ) { current->track_w = w; current->track_h = h; } } - +#ifdef GLx4 if( ((edl->session->output_w % 4) || (edl->session->output_h % 4)) && edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) { @@ -210,7 +196,7 @@ void MWindow::asset_to_all() _("This project's dimensions are not multiples of 4 so\n" "it can't be rendered by OpenGL.")); } - +#endif // Get aspect ratio if( defaults->get("AUTOASPECT", 0) ) { create_aspect_ratio( @@ -228,7 +214,7 @@ void MWindow::asset_to_all() save_backup(); - undo->update_undo_after(_("asset to all"), LOAD_ALL); + undo_after(_("asset to all"), LOAD_ALL); restart_brender(); gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); sync_parameters(CHANGE_ALL); @@ -242,14 +228,14 @@ void MWindow::asset_to_size() if( indexable->have_video() ) { int w, h; - undo->update_undo_before(); + undo_before(); // Get w and h w = indexable->get_w(); h = indexable->get_h(); edl->session->output_w = w; edl->session->output_h = h; - +#ifdef GLx4 if( ((edl->session->output_w % 4) || (edl->session->output_h % 4)) && edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) { @@ -257,7 +243,7 @@ void MWindow::asset_to_size() _("This project's dimensions are not multiples of 4 so\n" "it can't be rendered by OpenGL.")); } - +#endif // Get aspect ratio if( defaults->get("AUTOASPECT", 0) ) { create_aspect_ratio(edl->session->aspect_w, @@ -268,7 +254,7 @@ void MWindow::asset_to_size() save_backup(); - undo->update_undo_after(_("asset to size"), LOAD_ALL); + undo_after(_("asset to size"), LOAD_ALL); restart_brender(); sync_parameters(CHANGE_ALL); } @@ -281,14 +267,14 @@ void MWindow::asset_to_rate() session->drag_assets->get(0)->have_video() ) { double new_framerate = session->drag_assets->get(0)->get_frame_rate(); double old_framerate = edl->session->frame_rate; - undo->update_undo_before(); + undo_before(); edl->session->frame_rate = new_framerate; edl->resample(old_framerate, new_framerate, TRACK_VIDEO); save_backup(); - undo->update_undo_after(_("asset to rate"), LOAD_ALL); + undo_after(_("asset to rate"), LOAD_ALL); restart_brender(); gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); sync_parameters(CHANGE_ALL); @@ -298,12 +284,13 @@ void MWindow::asset_to_rate() void MWindow::clear_entry() { - undo->update_undo_before(); + undo_before(); clear(1); edl->optimize(); save_backup(); - undo->update_undo_after(_("clear"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("clear"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); restart_brender(); update_plugin_guis(); @@ -344,17 +331,17 @@ void MWindow::update_gui(int changed_edl) void MWindow::set_automation_mode(int mode) { - undo->update_undo_before(); + undo_before(); speed_before(); edl->tracks->set_automation_mode( edl->local_session->get_selectionstart(), edl->local_session->get_selectionend(), mode); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 1); save_backup(); char string[BCSTRLEN]; sprintf(string,"set %s", FloatAuto::curve_name(mode)); - undo->update_undo_after(string, + undo_after(string, !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -362,13 +349,13 @@ void MWindow::set_automation_mode(int mode) void MWindow::clear_automation() { - undo->update_undo_before(); + undo_before(); speed_before(); edl->tracks->clear_automation(edl->local_session->get_selectionstart(), edl->local_session->get_selectionend()); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 1); save_backup(); - undo->update_undo_after(_("clear keyframes"), + undo_after(_("clear keyframes"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -376,12 +363,12 @@ void MWindow::clear_automation() int MWindow::clear_default_keyframe() { - undo->update_undo_before(); + undo_before(); speed_before(); edl->tracks->clear_default_keyframe(); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 1); save_backup(); - undo->update_undo_after(_("clear default keyframe"), + undo_after(_("clear default keyframe"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -390,10 +377,10 @@ int MWindow::clear_default_keyframe() void MWindow::clear_labels() { - undo->update_undo_before(); + undo_before(); clear_labels(edl->local_session->get_selectionstart(), edl->local_session->get_selectionend()); - undo->update_undo_after(_("clear labels"), LOAD_TIMEBAR); + undo_after(_("clear labels"), LOAD_TIMEBAR); gui->update_timebar(1); cwindow->update(0, 0, 0, 0, 1); @@ -402,17 +389,58 @@ void MWindow::clear_labels() int MWindow::clear_labels(double start, double end) { + if( start == end ) { + start = 0; + end = edl->tracks->total_length(); + } edl->labels->clear(start, end, 0); return 0; } +void MWindow::clear_hard_edges() +{ + undo_before(); + clear_hard_edges(edl->local_session->get_selectionstart(), + edl->local_session->get_selectionend()); + edl->optimize(); + save_backup(); + undo_after(_("clear hard edges"), LOAD_EDITS); + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + cwindow->refresh_frame(CHANGE_EDL); +} + +int MWindow::clear_hard_edges(double start, double end) +{ + if( start == end ) { + start = 0; + end = edl->tracks->total_length(); + } + edl->clear_hard_edges(start, end); + return 0; +} + +void MWindow::clear_select() +{ + edl->tracks->clear_selected_edits(); + gui->draw_overlays(1); +} + +void MWindow::select_edits(int v) +{ + double start = edl->local_session->get_selectionstart(); + double end = edl->local_session->get_selectionend(); + edl->tracks->select_edits(start, end, v); + gui->draw_overlays(1); +} + void MWindow::concatenate_tracks() { - undo->update_undo_before(); + undo_before(); edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits, edl->session->autos_follow_edits); save_backup(); - undo->update_undo_after(_("concatenate tracks"), LOAD_EDITS); + undo_after(_("concatenate tracks"), LOAD_EDITS); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); @@ -420,6 +448,17 @@ void MWindow::concatenate_tracks() } +int MWindow::copy_flags(int copy_flags) +{ + if( !edl->session->labels_follow_edits ) + copy_flags &= ~COPY_LABELS; + if( !edl->session->autos_follow_edits ) + copy_flags &= ~COPY_AUTOS; + if( !edl->session->plugins_follow_edits ) + copy_flags &= ~COPY_PLUGINS; + return copy_flags; +} + void MWindow::copy() { copy(edl->local_session->get_selectionstart(), @@ -431,7 +470,7 @@ int MWindow::copy(double start, double end) if( start == end ) return 1; FileXML file; - edl->copy(start, end, 0, &file, "", 1); + edl->copy(copy_flags(), start, end, &file, "", 1); const char *file_string = file.string(); long file_length = strlen(file_string); gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); @@ -466,13 +505,11 @@ int MWindow::copy_default_keyframe() return 0; } - // Uses cropping coordinates in edl session to crop and translate video. // We modify the projector since camera automation depends on the track size. -void MWindow::crop_video() +void MWindow::crop_video(int mode) { - - undo->update_undo_before(); + undo_before(); // Clamp EDL crop region if( edl->session->crop_x1 > edl->session->crop_x2 ) { edl->session->crop_x1 ^= edl->session->crop_x2; @@ -484,22 +521,54 @@ void MWindow::crop_video() edl->session->crop_y2 ^= edl->session->crop_y1; edl->session->crop_y1 ^= edl->session->crop_y2; } - - float old_projector_x = (float)edl->session->output_w / 2; - float old_projector_y = (float)edl->session->output_h / 2; - float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2; - float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2; - float projector_offset_x = -(new_projector_x - old_projector_x); - float projector_offset_y = -(new_projector_y - old_projector_y); - - edl->tracks->translate_projector(projector_offset_x, projector_offset_y); - - edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1; - edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1; - edl->session->crop_x1 = 0; - edl->session->crop_y1 = 0; - edl->session->crop_x2 = edl->session->output_w; - edl->session->crop_y2 = edl->session->output_h; + switch( mode ) { + case CROP_REFORMAT: { + float ctr_x = edl->session->output_w / 2.; + float ctr_y = edl->session->output_h / 2.; + float new_x = (edl->session->crop_x1 + edl->session->crop_x2) / 2.; + float new_y = (edl->session->crop_y1 + edl->session->crop_y2) / 2.; + float dx = -(new_x - ctr_x), dy = -(new_y - ctr_y); + edl->tracks->translate_projector(dx, dy, 1); + + edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1; + edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1; + edl->session->crop_x1 = edl->session->crop_y1 = 0; + edl->session->crop_x2 = edl->session->output_w; + edl->session->crop_y2 = edl->session->output_h; + break; } + case CROP_RESIZE: { + float old_w = edl->session->output_w; + float old_h = edl->session->output_h; + float new_w = edl->session->crop_x2 - edl->session->crop_x1; + float new_h = edl->session->crop_y2 - edl->session->crop_y1; + if( !new_w ) new_w = 1; + if( !new_h ) new_h = 1; + float xzoom = old_w / new_w, yzoom = old_h / new_h; + float new_z = bmin(xzoom, yzoom); + float new_x = (edl->session->crop_x1 + edl->session->crop_x2) / 2.; + float new_y = (edl->session->crop_y1 + edl->session->crop_y2) / 2.; + edl->tracks->crop_resize(new_x, new_y, new_z); + + edl->session->crop_x1 = 0; + edl->session->crop_y1 = 0; + edl->session->crop_x2 = edl->session->output_w; + edl->session->crop_y2 = edl->session->output_h; + break; } + case CROP_SHRINK: { + float old_w = edl->session->output_w; + float old_h = edl->session->output_h; + float new_w = edl->session->crop_x2 - edl->session->crop_x1; + float new_h = edl->session->crop_y2 - edl->session->crop_y1; + if( !new_w ) new_w = 1; + if( !new_h ) new_h = 1; + float xzoom = old_w / new_w, yzoom = old_h / new_h; + float new_z = bmin(xzoom, yzoom); + + float new_x = (edl->session->crop_x1 + edl->session->crop_x2) / 2.; + float new_y = (edl->session->crop_y1 + edl->session->crop_y2) / 2.; + edl->tracks->crop_shrink(new_x, new_y, new_z); + break; } + } // Recalculate aspect ratio if( defaults->get("AUTOASPECT", 0) ) { @@ -509,7 +578,7 @@ void MWindow::crop_video() edl->session->output_h); } - undo->update_undo_after(_("crop"), LOAD_ALL); + undo_after(_("crop"), LOAD_ALL); restart_brender(); cwindow->refresh_frame(CHANGE_ALL); @@ -528,11 +597,11 @@ void MWindow::cut() void MWindow::blade(double position) { - undo->update_undo_before(); + undo_before(); edl->blade(position); edl->optimize(); save_backup(); - undo->update_undo_after(_("blade"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("blade"), LOAD_EDITS | LOAD_TIMEBAR); restart_brender(); update_plugin_guis(); gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); @@ -543,7 +612,7 @@ void MWindow::blade(double position) void MWindow::cut(double start, double end, double new_position) { - undo->update_undo_before(); + undo_before(); copy(start, end); edl->clear(start, end, edl->session->labels_follow_edits, @@ -552,7 +621,7 @@ void MWindow::cut(double start, double end, double new_position) edl->optimize(); save_backup(); - undo->update_undo_after(_("split | cut"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("split | cut"), LOAD_EDITS | LOAD_TIMEBAR); if( new_position >= 0 ) { edl->local_session->set_selectionstart(new_position); edl->local_session->set_selectionend(new_position); @@ -603,14 +672,14 @@ void MWindow::cut_right_label() int MWindow::cut_automation() { - undo->update_undo_before(); + undo_before(); speed_before(); copy_automation(); edl->tracks->clear_automation(edl->local_session->get_selectionstart(), edl->local_session->get_selectionend()); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 1); save_backup(); - undo->update_undo_after(_("cut keyframes"), + undo_after(_("cut keyframes"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -620,13 +689,13 @@ int MWindow::cut_automation() int MWindow::cut_default_keyframe() { - undo->update_undo_before(); + undo_before(); speed_before(); copy_default_keyframe(); edl->tracks->clear_default_keyframe(); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 1); save_backup(); - undo->update_undo_after(_("cut default keyframe"), + undo_after(_("cut default keyframe"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -634,17 +703,11 @@ int MWindow::cut_default_keyframe() } -void MWindow::delete_track() -{ - if( edl->tracks->last ) - delete_track(edl->tracks->last); -} - void MWindow::delete_tracks() { - undo->update_undo_before(); + undo_before(); edl->tracks->delete_tracks(); - undo->update_undo_after(_("delete tracks"), LOAD_ALL); + undo_after(_("delete tracks"), LOAD_ALL); save_backup(); restart_brender(); @@ -656,9 +719,9 @@ void MWindow::delete_tracks() void MWindow::delete_track(Track *track) { - undo->update_undo_before(); + undo_before(); edl->tracks->delete_track(track); - undo->update_undo_after(_("delete track"), LOAD_ALL); + undo_after(_("delete track"), LOAD_ALL); restart_brender(); update_plugin_states(); @@ -710,23 +773,44 @@ void MWindow::insert(double position, FileXML *file, //printf("MWindow::insert 6 %p\n", vwindow->get_edl()); } -void MWindow::insert_effects_canvas(double start, - double length) +void MWindow::insert_effects_canvas(Track *dest_track, double start, double length) { - Track *dest_track = session->track_highlighted; - if( !dest_track ) return; + undo_before(); - undo->update_undo_before(); + ArrayList shared_locations; + PluginSet *pluginset = session->pluginset_highlighted; + int gang = edl->local_session->gang_tracks != GANG_NONE ? 1 : 0; + int data_type = dest_track->data_type; + int first_track = 1; - for( int i=0; idrag_pluginservers->total; ++i ) { - PluginServer *plugin = session->drag_pluginservers->values[i]; - insert_effect(plugin->title, 0, dest_track, - i == 0 ? session->pluginset_highlighted : 0, - start, length, PLUGIN_STANDALONE); + for( Track *track=dest_track; track; track=track->next ) { + if( gang && track->master && !first_track ) break; + if( track->data_type != data_type ) continue; + if( !track->is_armed() ) continue; + int module = edl->tracks->number_of(track); + for( int i=0; idrag_pluginservers->total; ++i ) { + PluginServer *plugin = session->drag_pluginservers->values[i]; + int shared = gang; // && plugin->multichannel ? 1 : 0; + int plugin_type = !first_track && shared ? + PLUGIN_SHAREDPLUGIN : PLUGIN_STANDALONE; + SharedLocation *shared_location = !first_track ? + &shared_locations[i] : &shared_locations.append(); + insert_effect(plugin->title, shared_location, track, + pluginset, start, length, plugin_type); + if( first_track && shared ) { + shared_location->module = module; + shared_location->plugin = pluginset ? + track->plugin_set.number_of(pluginset) : + track->plugin_set.total-1 ; + } + } + if( !gang ) break; + first_track = 0; + pluginset = 0; } save_backup(); - undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES); + undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES); restart_brender(); sync_parameters(CHANGE_EDL); // GUI updated in TrackCanvas, after current_operations are reset @@ -736,8 +820,6 @@ void MWindow::insert_effects_cwindow(Track *dest_track) { if( !dest_track ) return; - undo->update_undo_before(); - double start = 0; double length = dest_track->get_length(); @@ -748,55 +830,45 @@ void MWindow::insert_effects_cwindow(Track *dest_track) edl->local_session->get_selectionstart(); } - for( int i=0; idrag_pluginservers->total; ++i ) { - PluginServer *plugin = session->drag_pluginservers->values[i]; - insert_effect(plugin->title, 0, dest_track, 0, - start, length, PLUGIN_STANDALONE); - } - - save_backup(); - undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES); - restart_brender(); - sync_parameters(CHANGE_EDL); + insert_effects_canvas(dest_track, start, length); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); } -void MWindow::insert_effect(char *title, - SharedLocation *shared_location, - int data_type, - int plugin_type, - int single_standalone) +void MWindow::insert_effect(char *title, SharedLocation *shared_location, + int data_type, int plugin_type, int single_standalone) { Track *current = edl->tracks->first; SharedLocation shared_location_local; shared_location_local.copy_from(shared_location); int first_track = 1; + double start_pos = edl->local_session->get_selectionstart(); + double end_pos = edl->local_session->get_selectionend(); for( ; current; current=NEXT ) { - if( current->data_type == data_type && - current->record ) { - insert_effect(title, &shared_location_local, - current, 0, 0, 0, plugin_type); - - if( first_track ) { - if( plugin_type == PLUGIN_STANDALONE && single_standalone ) { - plugin_type = PLUGIN_SHAREDPLUGIN; - shared_location_local.module = edl->tracks->number_of(current); - shared_location_local.plugin = current->plugin_set.total - 1; - } - first_track = 0; + if( current->data_type != data_type ) continue; + if( !current->is_armed() ) continue; + double start = start_pos, end = end_pos; + if( plugin_type == PLUGIN_STANDALONE && start >= end ) { + start = 0; + end = current->get_length(); + } + double length = end - start; + insert_effect(title, &shared_location_local, + current, 0, start, length, plugin_type); + if( first_track ) { + if( plugin_type == PLUGIN_STANDALONE && single_standalone ) { + plugin_type = PLUGIN_SHAREDPLUGIN; + shared_location_local.module = edl->tracks->number_of(current); + shared_location_local.plugin = current->plugin_set.total - 1; + start_pos = start; end_pos = end; } + first_track = 0; } } } - void MWindow::insert_effect(char *title, - SharedLocation *shared_location, - Track *track, - PluginSet *plugin_set, - double start, - double length, - int plugin_type) + SharedLocation *shared_location, Track *track, PluginSet *plugin_set, + double start, double length, int plugin_type) { KeyFrame *default_keyframe = 0; PluginServer *server = 0; @@ -809,9 +881,8 @@ void MWindow::insert_effect(char *title, server->save_data(default_keyframe); } // Insert plugin object - track->insert_effect(title, shared_location, - default_keyframe, plugin_set, - start, length, plugin_type); + track->insert_effect(title, shared_location, default_keyframe, + plugin_set, start, length, plugin_type); track->optimize(); if( plugin_type == PLUGIN_STANDALONE ) { @@ -823,15 +894,14 @@ void MWindow::insert_effect(char *title, int MWindow::modify_edithandles() { - undo->update_undo_before(); + undo_before(); + int handle_mode = edl->session->edit_handle_mode[session->drag_button]; edl->modify_edithandles(session->drag_start, - session->drag_position, - session->drag_handle, - edl->session->edit_handle_mode[session->drag_button], + session->drag_position, session->drag_handle, handle_mode, edl->session->labels_follow_edits, edl->session->plugins_follow_edits, - edl->session->autos_follow_edits); - + edl->session->autos_follow_edits, + session->drag_edit->group_id); finish_modify_handles(); //printf("MWindow::modify_handles 1\n"); return 0; @@ -839,7 +909,7 @@ int MWindow::modify_edithandles() int MWindow::modify_pluginhandles() { - undo->update_undo_before(); + undo_before(); edl->modify_pluginhandles(session->drag_start, session->drag_position, @@ -859,26 +929,26 @@ int MWindow::modify_pluginhandles() void MWindow::finish_modify_handles() { int edit_mode = edl->session->edit_handle_mode[session->drag_button]; - - if( (session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) || - (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT) ) { -//printf("MWindow::finish_modify_handles %d\n", __LINE__); - edl->local_session->set_selectionstart(session->drag_position); - edl->local_session->set_selectionend(session->drag_position); - } - else - if( edit_mode != MOVE_NO_EDITS ) { -//printf("MWindow::finish_modify_handles %d\n", __LINE__); - edl->local_session->set_selectionstart(session->drag_start); - edl->local_session->set_selectionend(session->drag_start); - } - -// clamp the selection to 0 - if( edl->local_session->get_selectionstart(1) < 0 ) { - edl->local_session->set_selectionstart(0); - edl->local_session->set_selectionend(0); - } - undo->update_undo_after(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR); + double position = -1; + switch( edit_mode ) { + case MOVE_RIPPLE: + position = !session->drag_handle ? + session->drag_start : session->drag_position; + break; + case MOVE_ROLL: + case MOVE_SLIDE: + position = session->drag_position; + break; + case MOVE_SLIP: + case MOVE_EDGE: + position = session->drag_start; + break; + } + if( position >= 0 ) { + edl->local_session->set_selectionstart(position); + edl->local_session->set_selectionend(position); + } + undo_after(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR); save_backup(); restart_brender(); @@ -890,104 +960,47 @@ void MWindow::finish_modify_handles() cwindow->update(1, 0, 0, 0, 1); } +int MWindow::modify_transnhandles() +{ + gui->reset_default_message(); + gui->default_message(); + Transition *transition = session->drag_transition; + if( !transition ) return 1; + int64_t length = transition->length; + Track *track = transition->edit->track; + int64_t start_pos = track->to_units(session->drag_start, 0); + int64_t end_pos = track->to_units(session->drag_position, 0); + length += end_pos - start_pos; + if( length < 0 ) length = 0; + if( length == transition->length ) return 0; + + undo_before(); + transition->length = length; + undo_after(_("trans handle"), LOAD_EDITS); + + save_backup(); + restart_brender(); + sync_parameters(CHANGE_EDL); + update_plugin_guis(); + gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); + cwindow->update(1, 0, 0, 0, 1); + + return 0; +} + void MWindow::match_output_size(Track *track) { - undo->update_undo_before(); + undo_before(); track->track_w = edl->session->output_w; track->track_h = edl->session->output_h; save_backup(); - undo->update_undo_after(_("match output size"), LOAD_ALL); + undo_after(_("match output size"), LOAD_ALL); restart_brender(); sync_parameters(CHANGE_EDL); } -EDL *MWindow::selected_edits_to_clip(int packed, double *start_position, Track **start_track) -{ - double start = DBL_MAX, end = DBL_MIN; - Track *first_track=0, *last_track = 0; - for( Track *track=edl->tracks->first; track; track=track->next ) { - if( !track->record ) continue; - int empty = 1; - for( Edit *edit=track->edits->first; edit; edit=edit->next ) { - if( !edit->is_selected || edit->silence() ) continue; - double edit_pos = track->from_units(edit->startproject); - if( start > edit_pos ) start = edit_pos; - if( end < (edit_pos+=edit->length) ) end = edit_pos; - empty = 0; - } - if( empty ) continue; - if( !first_track ) first_track = track; - last_track = track; - } - if( start_position ) *start_position = start; - if( start_track ) *start_track = first_track; - if( !first_track ) return 0; - EDL *new_edl = new EDL(); - new_edl->create_objects(); - new_edl->copy_session(edl); - const char *text = _("new_edl edit"); - new_edl->set_path(text); - strcpy(new_edl->local_session->clip_title, text); - strcpy(new_edl->local_session->clip_notes, text); - new_edl->session->video_tracks = 0; - new_edl->session->audio_tracks = 0; - for( Track *track=edl->tracks->first; track; track=track->next ) { - if( !track->record ) continue; - if( first_track ) { - if( first_track != track ) continue; - first_track = 0; - } - Track *new_track = 0; - if( !packed ) - new_track = new_edl->add_new_track(track->data_type); - int64_t start_pos = track->to_units(start, 0); - int64_t end_pos = track->to_units(end, 0); - int64_t startproject = 0; - for( Edit *edit=track->edits->first; edit; edit=edit->next ) { - if( edit->startproject < start_pos ) continue; - if( edit->startproject >= end_pos ) break; - if( !edit->is_selected || edit->silence() ) continue; - if( !new_track ) - new_track = new_edl->add_new_track(track->data_type); - if( new_track ) { - if( !packed ) { - int64_t edit_position = edit->startproject - start_pos; - if( edit_position > startproject ) { - Edit *silence = new Edit(new_edl, new_track); - silence->startproject = startproject; - silence->length = edit_position - startproject; - new_track->edits->append(silence); - startproject = edit_position; - } - } - Edit *clip_edit = new Edit(new_edl, new_track); - clip_edit->copy_from(edit); - clip_edit->startproject = startproject; - startproject += clip_edit->length; - new_track->edits->append(clip_edit); - } - } - if( last_track == track ) break; - } - return new_edl; -} - -void MWindow::selected_edits_to_clipboard(int packed) -{ - EDL *new_edl = MWindow::selected_edits_to_clip(packed); - if( !new_edl ) return; - double length = new_edl->tracks->total_length(); - FileXML file; - new_edl->copy(0, length, 1, &file, "", 1); - const char *file_string = file.string(); - long file_length = strlen(file_string); - gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); - gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); - new_edl->remove_user(); -} - void MWindow::delete_edit(Edit *edit, const char *msg, int collapse) { ArrayList edits; @@ -998,21 +1011,13 @@ void MWindow::delete_edit(Edit *edit, const char *msg, int collapse) void MWindow::delete_edits(ArrayList *edits, const char *msg, int collapse) { if( !edits->size() ) return; - undo->update_undo_before(); - for( Track *track=edl->tracks->first; track; track=track->next ) { - for( Edit *next=track->edits->first; next; ) { - Edit *edit = next; next = edit->next; - if( !edit->is_selected ) continue; - int64_t len = edit->length; - delete edit; - if( !collapse ) continue; - for( edit=next; edit; edit=edit->next ) - edit->startproject -= len; - } - } + undo_before(); + if( edl->session->labels_follow_edits ) + edl->delete_edit_labels(edits, collapse); + edl->delete_edits(edits, collapse); edl->optimize(); save_backup(); - undo->update_undo_after(msg, LOAD_EDITS); + undo_after(msg, LOAD_EDITS); restart_brender(); cwindow->refresh_frame(CHANGE_EDL); @@ -1039,22 +1044,21 @@ void MWindow::cut_selected_edits(int collapse, int packed) void MWindow::move_edits(ArrayList *edits, - Track *track, - double position, - int behaviour) + Track *track, double position, int mode) { - undo->update_undo_before(); - - edl->tracks->move_edits(edits, - track, - position, + undo_before(); +// lockout timebar labels update +// labels can be deleted with tooltip repeater running + cwindow->gui->lock_window("Tracks::move_edits"); + edl->tracks->move_edits(edits, track, position, edl->session->labels_follow_edits, edl->session->plugins_follow_edits, - edl->session->autos_follow_edits, - behaviour); + edl->session->autos_follow_edits, mode); + cwindow->gui->timebar->update(1); + cwindow->gui->unlock_window(); save_backup(); - undo->update_undo_after(_("move edit"), LOAD_ALL); + undo_after(_("move edit"), LOAD_ALL); restart_brender(); cwindow->refresh_frame(CHANGE_EDL); @@ -1063,12 +1067,72 @@ void MWindow::move_edits(ArrayList *edits, gui->update(1, NORMAL_DRAW, 1, 0, 0, 0, 0); } -void MWindow::move_group(EDL *group, Track *first_track, double position) +void MWindow::selected_edits_to_clipboard(int packed) +{ + EDL *new_edl = edl->selected_edits_to_clip(packed, 0, 0, + edl->session->labels_follow_edits, + edl->session->autos_follow_edits, + edl->session->plugins_follow_edits); + if( !new_edl ) return; + FileXML file; + new_edl->copy(COPY_EDL, &file, "", 1); + const char *file_string = file.string(); + long file_length = strlen(file_string); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); + new_edl->remove_user(); +} + +void MWindow::paste_clipboard(Track *first_track, double position, int overwrite, + int edit_edits, int edit_labels, int edit_autos, int edit_plugins) { - undo->update_undo_before(); - edl->tracks->move_group(group, first_track, position); + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); + if( !len ) return; + char *string = new char[len]; + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); + FileXML file; + file.read_from_string(string); + delete [] string; + EDL *clip = new EDL(); + clip->create_objects(); + if( !clip->load_xml(&file, LOAD_ALL) ) { + undo_before(); + edl->paste_edits(clip, first_track, position, overwrite, + edit_edits, edit_labels, edit_autos, edit_plugins); + save_backup(); + undo_after(_("paste clip"), LOAD_ALL); + restart_brender(); + cwindow->refresh_frame(CHANGE_EDL); + + update_plugin_guis(); + gui->update(1, NORMAL_DRAW, 1, 0, 0, 0, 0); + } + clip->remove_user(); +} + +void MWindow::move_group(EDL *group, Track *first_track, double position, int overwrite) +{ + undo_before(); +// lockout timebar labels update +// labels can be deleted with tooltip repeater running + cwindow->gui->lock_window("Tracks::move_group"); + + ArrayListedits; + edl->tracks->get_selected_edits(&edits); + if( edl->session->labels_follow_edits ) + edl->delete_edit_labels(&edits, 0); + edl->delete_edits(&edits, 0); + edl->paste_edits(group, first_track, position, overwrite, 1, + edl->session->labels_follow_edits, + edl->session->autos_follow_edits, + edl->session->plugins_follow_edits); + cwindow->gui->timebar->update(1); + cwindow->gui->unlock_window(); +// big debate over whether to do this, must either clear selected, or no tweaking +// edl->tracks->clear_selected_edits(); + save_backup(); - undo->update_undo_after(_("move group"), LOAD_ALL); + undo_after(_("move group"), LOAD_ALL); restart_brender(); cwindow->refresh_frame(CHANGE_EDL); @@ -1078,10 +1142,10 @@ void MWindow::move_group(EDL *group, Track *first_track, double position) void MWindow::move_effect(Plugin *plugin, Track *track, int64_t position) { - undo->update_undo_before(); + undo_before(); edl->tracks->move_effect(plugin, track, position); save_backup(); - undo->update_undo_after(_("paste effect"), LOAD_ALL); + undo_after(_("paste effect"), LOAD_ALL); restart_brender(); cwindow->refresh_frame(CHANGE_EDL); @@ -1091,10 +1155,10 @@ void MWindow::move_effect(Plugin *plugin, Track *track, int64_t position) void MWindow::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t position) { - undo->update_undo_before(); + undo_before(); edl->tracks->move_effect(plugin, plugin_set, position); save_backup(); - undo->update_undo_after(_("move effect"), LOAD_ALL); + undo_after(_("move effect"), LOAD_ALL); restart_brender(); cwindow->refresh_frame(CHANGE_EDL); @@ -1105,11 +1169,11 @@ void MWindow::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t positio void MWindow::move_plugins_up(PluginSet *plugin_set) { - undo->update_undo_before(); + undo_before(); plugin_set->track->move_plugins_up(plugin_set); save_backup(); - undo->update_undo_after(_("move effect up"), LOAD_ALL); + undo_after(_("move effect up"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 0, 0, 0); sync_parameters(CHANGE_EDL); @@ -1117,23 +1181,73 @@ void MWindow::move_plugins_up(PluginSet *plugin_set) void MWindow::move_plugins_down(PluginSet *plugin_set) { - undo->update_undo_before(); + undo_before(); plugin_set->track->move_plugins_down(plugin_set); save_backup(); - undo->update_undo_after(_("move effect down"), LOAD_ALL); + undo_after(_("move effect down"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 0, 0, 0); sync_parameters(CHANGE_EDL); } +void MWindow::roll_track_down(Track *track) +{ + undo_before(); + edl->tracks->roll_track_down(track); + save_backup(); + undo_after(_("move track down"), LOAD_ALL); + + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + sync_parameters(CHANGE_EDL); + save_backup(); +} + +void MWindow::roll_tracks_down() +{ + undo_before(); + edl->tracks->roll_tracks_down(); + save_backup(); + undo_after(_("move tracks down"), LOAD_ALL); + + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + sync_parameters(CHANGE_EDL); + save_backup(); +} + +void MWindow::roll_track_up(Track *track) +{ + undo_before(); + edl->tracks->roll_track_up(track); + save_backup(); + undo_after(_("move track up"), LOAD_ALL); + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + sync_parameters(CHANGE_EDL); + save_backup(); +} + +void MWindow::roll_tracks_up() +{ + undo_before(); + edl->tracks->roll_tracks_up(); + save_backup(); + undo_after(_("move tracks up"), LOAD_ALL); + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + sync_parameters(CHANGE_EDL); +} + + void MWindow::move_track_down(Track *track) { - undo->update_undo_before(); + undo_before(); edl->tracks->move_track_down(track); save_backup(); - undo->update_undo_after(_("move track down"), LOAD_ALL); + undo_after(_("swap track down"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); @@ -1143,10 +1257,10 @@ void MWindow::move_track_down(Track *track) void MWindow::move_tracks_down() { - undo->update_undo_before(); + undo_before(); edl->tracks->move_tracks_down(); save_backup(); - undo->update_undo_after(_("move tracks down"), LOAD_ALL); + undo_after(_("swap tracks down"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); @@ -1156,10 +1270,10 @@ void MWindow::move_tracks_down() void MWindow::move_track_up(Track *track) { - undo->update_undo_before(); + undo_before(); edl->tracks->move_track_up(track); save_backup(); - undo->update_undo_after(_("move track up"), LOAD_ALL); + undo_after(_("swap track up"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); sync_parameters(CHANGE_EDL); @@ -1168,10 +1282,10 @@ void MWindow::move_track_up(Track *track) void MWindow::move_tracks_up() { - undo->update_undo_before(); + undo_before(); edl->tracks->move_tracks_up(); save_backup(); - undo->update_undo_after(_("move tracks up"), LOAD_ALL); + undo_after(_("swap tracks up"), LOAD_ALL); restart_brender(); gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); sync_parameters(CHANGE_EDL); @@ -1183,7 +1297,7 @@ void MWindow::mute_selection() double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); if( start != end ) { - undo->update_undo_before(); + undo_before(); edl->clear(start, end, 0, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); @@ -1194,7 +1308,7 @@ void MWindow::mute_selection() edl->session->autos_follow_edits); save_backup(); - undo->update_undo_after(_("mute"), LOAD_EDITS); + undo_after(_("mute"), LOAD_EDITS); restart_brender(); update_plugin_guis(); @@ -1221,29 +1335,36 @@ void MWindow::overwrite(EDL *source, int all) double dst_start = edl->local_session->get_selectionstart(); double dst_len = edl->local_session->get_selectionend() - dst_start; - undo->update_undo_before(); + undo_before(); if( !EQUIV(dst_len, 0) && (dst_len < overwrite_len) ) { // in/out points or selection present and shorter than overwrite range // shorten the copy range overwrite_len = dst_len; } - source->copy(src_start, src_start + overwrite_len, 0, &file, "", 1); + source->copy(copy_flags(), src_start, src_start + overwrite_len, &file, "", 1); // HACK around paste_edl get_start/endselection on its own // so we need to clear only when not using both io points // FIXME: need to write simple overwrite_edl to be used for overwrite function if( edl->local_session->get_inpoint() < 0 || - edl->local_session->get_outpoint() < 0 ) - edl->clear(dst_start, dst_start + overwrite_len, 0, 0, 0); + edl->local_session->get_outpoint() < 0 ) + edl->clear(dst_start, dst_start + overwrite_len, + edl->session->labels_follow_edits, + edl->session->plugins_follow_edits, + edl->session->autos_follow_edits); - paste(dst_start, dst_start + overwrite_len, &file, 0, 0, 0, 0, 0); + paste(dst_start, dst_start + overwrite_len, &file, + edl->session->labels_follow_edits, + edl->session->plugins_follow_edits, + edl->session->autos_follow_edits, 0, 0); edl->local_session->set_selectionstart(dst_start + overwrite_len); edl->local_session->set_selectionend(dst_start + overwrite_len); save_backup(); - undo->update_undo_after(_("overwrite"), LOAD_EDITS); + undo_after(_("overwrite"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); restart_brender(); update_plugin_guis(); @@ -1279,7 +1400,7 @@ void MWindow::paste(double start, Track *first_track, int clear_selection, int o if( len ) { char *string = new char[len]; - undo->update_undo_before(); + undo_before(); gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; file.read_from_string(string); @@ -1296,7 +1417,8 @@ void MWindow::paste(double start, Track *first_track, int clear_selection, int o save_backup(); - undo->update_undo_after(_("paste"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("paste"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); restart_brender(); update_plugin_guis(); gui->update(1, FORCE_REDRAW, 1, 1, 0, 1, 0); @@ -1309,7 +1431,7 @@ void MWindow::paste(double start, Track *first_track, int clear_selection, int o int MWindow::paste_assets(double position, Track *dest_track, int overwrite) { int result = 0; - undo->update_undo_before(); + undo_before(); if( session->drag_assets->total ) { load_assets(session->drag_assets, @@ -1333,7 +1455,8 @@ int MWindow::paste_assets(double position, Track *dest_track, int overwrite) save_backup(); - undo->update_undo_after(_("paste assets"), LOAD_EDITS); + undo_after(_("paste assets"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); restart_brender(); gui->update(1, FORCE_REDRAW, 1, 0, 0, 1, 0); sync_parameters(CHANGE_EDL); @@ -1348,13 +1471,14 @@ void MWindow::load_assets(ArrayList *new_assets, load_mode = LOADMODE_ASSETSONLY; const int debug = 0; if( debug ) printf("MWindow::load_assets %d\n", __LINE__); - if( position < 0 ) position = edl->local_session->get_selectionstart(); + if( position < 0 ) + position = edl->local_session->get_selectionstart(); ArrayList new_edls; for( int i=0; itotal; ++i ) { Indexable *indexable = new_assets->get(i); if( indexable->is_asset ) { - remove_asset_from_caches((Asset*)indexable); + remove_from_caches(indexable); } EDL *new_edl = new EDL; new_edl->create_objects(); @@ -1394,7 +1518,7 @@ int MWindow::paste_automation() int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { - undo->update_undo_before(); + undo_before(); speed_before(); char *string = new char[len]; gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); @@ -1406,9 +1530,9 @@ int MWindow::paste_automation() edl->tracks->clear_automation(start, end); edl->tracks->paste_automation(start, &file, 0, 1, edl->session->typeless_keyframes); - int changed_edl = speed_after(1); + int changed_edl = speed_after(1, 0); save_backup(); - undo->update_undo_after(_("paste keyframes"), + undo_after(_("paste keyframes"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_gui(changed_edl); @@ -1422,7 +1546,7 @@ int MWindow::paste_default_keyframe() int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { - undo->update_undo_before(); + undo_before(); speed_before(); char *string = new char[len]; gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); @@ -1433,8 +1557,8 @@ int MWindow::paste_default_keyframe() edl->tracks->paste_automation(start, &file, 1, 0, edl->session->typeless_keyframes); // edl->tracks->paste_default_keyframe(&file); - int changed_edl = speed_after(1); - undo->update_undo_after(_("paste default keyframe"), + int changed_edl = speed_after(1, 1); + undo_after(_("paste default keyframe"), !changed_edl ? LOAD_AUTOMATION : LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); save_backup(); @@ -1466,7 +1590,7 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, // Delete current project if( load_mode == LOADMODE_REPLACE || load_mode == LOADMODE_REPLACE_CONCATENATE ) { - reset_caches(); + reset_caches(1); edl->save_defaults(defaults); hide_plugins(); edl->Garbage::remove_user(); @@ -1499,6 +1623,7 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, need_new_tracks = 1; for( int i=0; itotal; ++i ) { EDL *new_edl = new_edls->values[i]; + int first_track = 1; for( Track *current=new_edl->tracks->first; current; current=NEXT ) { switch( current->data_type ) { case TRACK_VIDEO: @@ -1514,6 +1639,13 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, default: continue; } + if( first_track ) { + edl->tracks->last->master = 1; + first_track = 0; + } +// re-label only if not already labeled + if( new_edl->local_session->asset2edl ) + strcpy(current->title, edl->tracks->last->title); destination_tracks.append(edl->tracks->last); } @@ -1525,26 +1657,14 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, else // Recycle existing tracks of master EDL if( load_mode == LOADMODE_CONCATENATE || - load_mode == LOADMODE_PASTE || - load_mode == LOADMODE_NESTED ) { -//PRINT_TRACE - -// The point of this is to shift forward labels after the selection so they can -// then be shifted back to their original locations without recursively -// shifting back every paste. - if( (load_mode == LOADMODE_PASTE || load_mode == LOADMODE_NESTED) && - edl->session->labels_follow_edits ) - edl->labels->clear(edl->local_session->get_selectionstart(), - edl->local_session->get_selectionend(), 1); - + load_mode == LOADMODE_PASTE ) { Track *current = first_track ? first_track : edl->tracks->first; for( ; current; current=NEXT ) { - if( current->record ) { + if( current->is_armed() ) { destination_tracks.append(current); } } //PRINT_TRACE - } //PRINT_TRACE int destination_track = 0; @@ -1574,17 +1694,22 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, // Add assets and prepare index files for( Asset *new_asset=new_edl->assets->first; new_asset; new_asset=new_asset->next ) { - mainindexes->add_next_asset(0, new_asset); + mainindexes->add_indexable(new_asset); } // Capture index file status from mainindex test edl->update_assets(new_edl); //PRINT_TRACE // Get starting point of insertion. Need this to paste labels. switch( load_mode ) { + case LOADMODE_NOTHING: + continue; case LOADMODE_REPLACE: - case LOADMODE_NEW_TRACKS: current_position = 0; break; + case LOADMODE_NEW_TRACKS: + if( !overwrite ) + current_position = 0; + break; case LOADMODE_CONCATENATE: case LOADMODE_REPLACE_CONCATENATE: @@ -1596,7 +1721,6 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, break; case LOADMODE_PASTE: - case LOADMODE_NESTED: destination_track = 0; if( i == 0 ) { for( int j=0; j *new_edls, int load_mode, edl->add_clip(new_edl); break; } -//PRINT_TRACE // Insert edl if( load_mode != LOADMODE_RESOURCESONLY && load_mode != LOADMODE_ASSETSONLY ) { // Insert labels -//printf("MWindow::paste_edls %f %f\n", current_position, edl_length); - if( load_mode == LOADMODE_PASTE || - load_mode == LOADMODE_NESTED ) - edl->labels->insert_labels(new_edl->labels, - destination_tracks.total ? paste_position[0] : 0.0, - edl_length, - edit_labels); - else - edl->labels->insert_labels(new_edl->labels, - current_position, - edl_length, - edit_labels); -//PRINT_TRACE + if( edit_labels ) { + if( load_mode == LOADMODE_PASTE ) + edl->labels->insert_labels(new_edl->labels, + destination_tracks.total ? paste_position[0] : 0.0, + edl_length, 1); + else + edl->labels->insert_labels(new_edl->labels, current_position, + edl_length, 1); + } double total_length = new_edl->tracks->total_length(); for( Track *new_track=new_edl->tracks->first; new_track; new_track=new_track->next ) { @@ -1645,14 +1764,14 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, if( destination_track < destination_tracks.total && destination_tracks.values[destination_track]->data_type == new_track->data_type ) { Track *track = destination_tracks.values[destination_track]; - // Replace default keyframes if first EDL and new tracks were created. // This means data copied from one track and pasted to another won't retain // the camera position unless it's a keyframe. If it did, previous data in the // track might get unknowingly corrupted. Ideally we would detect when differing // default keyframes existed and create discrete keyframes for both. int replace_default = (i == 0) && need_new_tracks; - +// master tracks are the first track in each new edl when new tracks are created + int master = track->master; //printf("MWindow::paste_edls 1 %d\n", replace_default); // Insert new track at current position switch( load_mode ) { @@ -1662,7 +1781,6 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, break; case LOADMODE_PASTE: - case LOADMODE_NESTED: current_position = paste_position[destination_track]; paste_position[destination_track] += new_track->get_length(); break; @@ -1674,12 +1792,12 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, current_position + length, 1, // edit edits edit_labels, edit_plugins, edit_autos, - 1, // convert units 0); // trim edits } //PRINT_TRACE track->insert_track(new_track, current_position, replace_default, edit_plugins, edit_autos, edl_length); + if( master ) track->master = 1; //PRINT_TRACE } @@ -1690,8 +1808,7 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, } } - if( load_mode == LOADMODE_PASTE || - load_mode == LOADMODE_NESTED ) + if( load_mode == LOADMODE_PASTE ) current_position += edl_length; } @@ -1753,14 +1870,15 @@ void MWindow::paste_silence() if( edl->session->frame_rate > 0 ) end += 1./edl->session->frame_rate; } - undo->update_undo_before(_("silence"), this); + undo_before(_("silence"), this); edl->paste_silence(start, end, edl->session->labels_follow_edits, edl->session->plugins_follow_edits, edl->session->autos_follow_edits); edl->optimize(); save_backup(); - undo->update_undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("silence"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_plugin_guis(); restart_brender(); @@ -1771,12 +1889,12 @@ void MWindow::paste_silence() void MWindow::detach_transition(Transition *transition) { - undo->update_undo_before(); + undo_before(); hide_plugin(transition, 1); int is_video = (transition->edit->track->data_type == TRACK_VIDEO); transition->edit->detach_transition(); save_backup(); - undo->update_undo_after(_("detach transition"), LOAD_ALL); + undo_after(_("detach transition"), LOAD_ALL); if( is_video ) restart_brender(); gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0); @@ -1787,13 +1905,13 @@ void MWindow::detach_transitions() { gui->lock_window("MWindow::detach_transitions 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->clear_transitions(start, end); save_backup(); - undo->update_undo_after(_("detach transitions"), LOAD_EDITS); + undo_after(_("detach transitions"), LOAD_EDITS); sync_parameters(CHANGE_EDL); gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0); @@ -1805,10 +1923,10 @@ void MWindow::paste_transition() // Only the first transition gets dropped. PluginServer *server = session->drag_pluginservers->values[0]; - undo->update_undo_before(); + undo_before(); edl->tracks->paste_transition(server, session->edit_highlighted); save_backup(); - undo->update_undo_after(_("transition"), LOAD_EDITS); + undo_after(_("transition"), LOAD_EDITS); if( server->video ) restart_brender(); sync_parameters(CHANGE_ALL); @@ -1818,12 +1936,12 @@ void MWindow::paste_transitions(int track_type, char *title) { gui->lock_window("MWindow::detach_transitions 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->paste_transitions(start, end, track_type, title); save_backup(); - undo->update_undo_after(_("attach transitions"), LOAD_EDITS); + undo_after(_("attach transitions"), LOAD_EDITS); sync_parameters(CHANGE_EDL); gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0); @@ -1833,10 +1951,10 @@ void MWindow::paste_transitions(int track_type, char *title) void MWindow::paste_transition_cwindow(Track *dest_track) { PluginServer *server = session->drag_pluginservers->values[0]; - undo->update_undo_before(); + undo_before(); edl->tracks->paste_video_transition(server, 1); save_backup(); - undo->update_undo_after(_("transition"), LOAD_EDITS); + undo_after(_("transition"), LOAD_EDITS); restart_brender(); gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0); sync_parameters(CHANGE_ALL); @@ -1853,10 +1971,10 @@ void MWindow::paste_audio_transition() return; } - undo->update_undo_before(); + undo_before(); edl->tracks->paste_audio_transition(server); save_backup(); - undo->update_undo_after(_("transition"), LOAD_EDITS); + undo_after(_("transition"), LOAD_EDITS); sync_parameters(CHANGE_EDL); gui->update(0, NORMAL_DRAW, 0, 0, 0, 0, 0); @@ -1873,11 +1991,11 @@ void MWindow::paste_video_transition() return; } - undo->update_undo_before(); + undo_before(); edl->tracks->paste_video_transition(server); save_backup(); - undo->update_undo_after(_("transition"), LOAD_EDITS); + undo_after(_("transition"), LOAD_EDITS); sync_parameters(CHANGE_EDL); restart_brender(); @@ -1888,14 +2006,14 @@ void MWindow::shuffle_edits() { gui->lock_window("MWindow::shuffle_edits 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->shuffle_edits(start, end); save_backup(); - undo->update_undo_after(_("shuffle edits"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("shuffle edits"), LOAD_EDITS | LOAD_TIMEBAR); sync_parameters(CHANGE_EDL); restart_brender(); @@ -1907,14 +2025,14 @@ void MWindow::reverse_edits() { gui->lock_window("MWindow::reverse_edits 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->reverse_edits(start, end); save_backup(); - undo->update_undo_after(_("reverse edits"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("reverse edits"), LOAD_EDITS | LOAD_TIMEBAR); sync_parameters(CHANGE_EDL); restart_brender(); @@ -1926,14 +2044,14 @@ void MWindow::align_edits() { gui->lock_window("MWindow::align_edits 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->align_edits(start, end); save_backup(); - undo->update_undo_after(_("align edits"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("align edits"), LOAD_EDITS | LOAD_TIMEBAR); sync_parameters(CHANGE_EDL); restart_brender(); @@ -1945,14 +2063,14 @@ void MWindow::set_edit_length(double length) { gui->lock_window("MWindow::set_edit_length 1"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->set_edit_length(start, end, length); save_backup(); - undo->update_undo_after(_("edit length"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("edit length"), LOAD_EDITS | LOAD_TIMEBAR); sync_parameters(CHANGE_EDL); restart_brender(); @@ -1965,14 +2083,14 @@ void MWindow::set_transition_length(Transition *transition, double length) { gui->lock_window("MWindow::set_transition_length 1"); - undo->update_undo_before(); + undo_before(); //double start = edl->local_session->get_selectionstart(); //double end = edl->local_session->get_selectionend(); edl->tracks->set_transition_length(transition, length); save_backup(); - undo->update_undo_after(_("transition length"), LOAD_EDITS); + undo_after(_("transition length"), LOAD_EDITS); edl->session->default_transition_length = length; sync_parameters(CHANGE_PARAMS); @@ -1984,14 +2102,14 @@ void MWindow::set_transition_length(double length) { gui->lock_window("MWindow::set_transition_length 2"); - undo->update_undo_before(); + undo_before(); double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); edl->tracks->set_transition_length(start, end, length); save_backup(); - undo->update_undo_after(_("transition length"), LOAD_EDITS); + undo_after(_("transition length"), LOAD_EDITS); edl->session->default_transition_length = length; sync_parameters(CHANGE_PARAMS); @@ -2028,8 +2146,8 @@ void MWindow::redo_entry(BC_WindowBase *calling_window_gui) gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 1); gui->update_proxy_toggle(); gui->unlock_window(); - cwindow->update(1, 1, 1, 1, 1); cwindow->gui->unlock_window(); + cwindow->update(1, 1, 1, 1, 1); for( int i=0; i < vwindows.size(); ++i ) { if( vwindows.get(i)->is_running() ) { @@ -2048,14 +2166,14 @@ void MWindow::redo_entry(BC_WindowBase *calling_window_gui) void MWindow::resize_track(Track *track, int w, int h) { - undo->update_undo_before(); + undo_before(); // We have to move all maskpoints so they do not move in relation to image areas ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks( (w - track->track_w) / 2, (h - track->track_h) / 2); track->track_w = w; track->track_h = h; - undo->update_undo_after(_("resize track"), LOAD_ALL); + undo_after(_("resize track"), LOAD_ALL); save_backup(); restart_brender(); @@ -2063,76 +2181,43 @@ void MWindow::resize_track(Track *track, int w, int h) } -void MWindow::set_inpoint(int is_mwindow) +void MWindow::set_inpoint() { - undo->update_undo_before(); + undo_before(); edl->set_inpoint(edl->local_session->get_selectionstart(1)); save_backup(); - undo->update_undo_after(_("in point"), LOAD_TIMEBAR); - - if( !is_mwindow ) { - gui->lock_window("MWindow::set_inpoint 1"); - } + undo_after(_("in point"), LOAD_TIMEBAR); gui->update_timebar(1); - if( !is_mwindow ) { - gui->unlock_window(); - } - if( is_mwindow ) { - cwindow->gui->lock_window("MWindow::set_inpoint 2"); - } + cwindow->gui->lock_window("MWindow::set_inpoint 2"); cwindow->gui->timebar->update(1); - if( is_mwindow ) { - cwindow->gui->unlock_window(); - } + cwindow->gui->unlock_window(); } -void MWindow::set_outpoint(int is_mwindow) +void MWindow::set_outpoint() { - undo->update_undo_before(); + undo_before(); edl->set_outpoint(edl->local_session->get_selectionend(1)); save_backup(); - undo->update_undo_after(_("out point"), LOAD_TIMEBAR); + undo_after(_("out point"), LOAD_TIMEBAR); - if( !is_mwindow ) { - gui->lock_window("MWindow::set_outpoint 1"); - } gui->update_timebar(1); - if( !is_mwindow ) { - gui->unlock_window(); - } - - if( is_mwindow ) { - cwindow->gui->lock_window("MWindow::set_outpoint 2"); - } + cwindow->gui->lock_window("MWindow::set_outpoint 2"); cwindow->gui->timebar->update(1); - if( is_mwindow ) { - cwindow->gui->unlock_window(); - } + cwindow->gui->unlock_window(); } -void MWindow::unset_inoutpoint(int is_mwindow) +void MWindow::unset_inoutpoint() { - undo->update_undo_before(); + undo_before(); edl->unset_inoutpoint(); save_backup(); - undo->update_undo_after(_("clear in/out"), LOAD_TIMEBAR); + undo_after(_("clear in/out"), LOAD_TIMEBAR); - if( !is_mwindow ) { - gui->lock_window("MWindow::unset_inoutpoint 1"); - } gui->update_timebar(1); - if( !is_mwindow ) { - gui->unlock_window(); - } - - if( is_mwindow ) { - cwindow->gui->lock_window("MWindow::unset_inoutpoint 2"); - } + cwindow->gui->lock_window("MWindow::unset_inoutpoint 2"); cwindow->gui->timebar->update(1); - if( is_mwindow ) { - cwindow->gui->unlock_window(); - } + cwindow->gui->unlock_window(); } void MWindow::splice(EDL *source, int all) @@ -2140,7 +2225,7 @@ void MWindow::splice(EDL *source, int all) FileXML file; LocalSession *src = source->local_session; - undo->update_undo_before(); + undo_before(); double source_start = all ? 0 : src->inpoint_valid() ? src->get_inpoint() : src->outpoint_valid() ? 0 : src->get_selectionstart(); @@ -2148,7 +2233,7 @@ void MWindow::splice(EDL *source, int all) src->outpoint_valid() ? src->get_outpoint() : src->inpoint_valid() ? source->tracks->total_length() : src->get_selectionend(); - source->copy(source_start, source_end, 1, &file, "", 1); + source->copy(COPY_EDL, source_start, source_end, &file, "", 1); //file.dump(); double start = edl->local_session->get_selectionstart(); //double end = edl->local_session->get_selectionend(); @@ -2164,7 +2249,8 @@ void MWindow::splice(EDL *source, int all) edl->local_session->set_selectionend(start + source_end - source_start); save_backup(); - undo->update_undo_after(_("splice"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("splice"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_plugin_guis(); restart_brender(); gui->update(1, NORMAL_DRAW, 1, 1, 0, 1, 0); @@ -2187,7 +2273,7 @@ void MWindow::save_clip(EDL *new_edl, const char *txt) Track *track = new_edl->tracks->first; const char *path = edl->path; for( ; (!path || !*path) && track; track=track->next ) { - if( !track->record ) continue; + if( !track->is_armed() ) continue; Edit *edit = track->edits->first; if( !edit ) continue; Indexable *indexable = edit->get_source(); @@ -2198,28 +2284,24 @@ void MWindow::save_clip(EDL *new_edl, const char *txt) time_t now; time(&now); struct tm dtm; localtime_r(&now, &dtm); char *cp = new_edl->local_session->clip_notes; - int n, sz = sizeof(new_edl->local_session->clip_notes)-1; - if( txt && *txt ) { - n = snprintf(cp, sz, "%s", txt); - cp += n; sz -= n; - } - n = snprintf(cp, sz, + char *ep = cp + sizeof(new_edl->local_session->clip_notes)-1; + if( txt && *txt ) + cp += snprintf(cp, ep-cp, "%s", txt); + cp += snprintf(cp, ep-cp, "%02d/%02d/%02d %02d:%02d:%02d, +%s\n", dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, dtm.tm_hour, dtm.tm_min, dtm.tm_sec, duration); - cp += n; sz -= n; if( path && *path ) { FileSystem fs; char title[BCTEXTLEN]; fs.extract_name(title, path); - n = snprintf(cp, sz, "%s", title); - cp += n; sz -= n; + cp += snprintf(cp, ep-cp, "%s", title); } - cp[n] = 0; sprintf(new_edl->local_session->clip_icon, - "clip_%02d%02d%02d-%02d%02d%02d.png", + "clip_%02d%02d%02d-%02d%02d%02d-%d.png", dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, - dtm.tm_hour, dtm.tm_min, dtm.tm_sec); + dtm.tm_hour, dtm.tm_min, dtm.tm_sec, + new_edl->id); new_edl->folder_no = AW_CLIP_FOLDER; edl->update_assets(new_edl); int cur_x, cur_y; @@ -2252,7 +2334,7 @@ void MWindow::to_clip(EDL *edl, const char *txt, int all) } // Don't copy all since we don't want the clips twice. - edl->copy(start, end, 0, &file, "", 1); + edl->copy(copy_flags(), start, end, &file, "", 1); EDL *new_edl = new EDL(edl); new_edl->create_objects(); @@ -2261,55 +2343,35 @@ void MWindow::to_clip(EDL *edl, const char *txt, int all) gui->unlock_window(); } -int MWindow::toggle_label(int is_mwindow) +int MWindow::toggle_label() { double position1, position2; - undo->update_undo_before(); - - if( cwindow->playback_engine->is_playing_back ) { - position1 = position2 = - cwindow->playback_engine->get_tracking_position(); - } - else { - position1 = edl->local_session->get_selectionstart(1); - position2 = edl->local_session->get_selectionend(1); - } + undo_before(); + position1 = edl->local_session->get_selectionstart(1); + position2 = edl->local_session->get_selectionend(1); position1 = edl->align_to_frame(position1, 0); position2 = edl->align_to_frame(position2, 0); -//printf("MWindow::toggle_label 1\n"); - edl->labels->toggle_label(position1, position2); save_backup(); - if( !is_mwindow ) { - gui->lock_window("MWindow::toggle_label 1"); - } gui->update_timebar(0); gui->activate_timeline(); gui->flush(); - if( !is_mwindow ) { - gui->unlock_window(); - } - if( is_mwindow ) { - cwindow->gui->lock_window("MWindow::toggle_label 2"); - } + cwindow->gui->lock_window("MWindow::toggle_label 2"); cwindow->gui->timebar->update(1); - if( is_mwindow ) { - cwindow->gui->unlock_window(); - } - + cwindow->gui->unlock_window(); awindow->gui->async_update_assets(); - undo->update_undo_after(_("label"), LOAD_TIMEBAR); + undo_after(_("label"), LOAD_TIMEBAR); return 0; } void MWindow::trim_selection() { - undo->update_undo_before(); + undo_before(); edl->trim_selection(edl->local_session->get_selectionstart(), @@ -2319,7 +2381,8 @@ void MWindow::trim_selection() edl->session->autos_follow_edits); save_backup(); - undo->update_undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("trim selection"), + LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR); update_plugin_guis(); gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); cwindow->update(1, 0, 0, 0, 1); @@ -2356,8 +2419,8 @@ void MWindow::undo_entry(BC_WindowBase *calling_window_gui) gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 1); gui->update_proxy_toggle(); gui->unlock_window(); - cwindow->update(1, 1, 1, 1, 1); cwindow->gui->unlock_window(); + cwindow->update(1, 1, 1, 1, 1); for( int i=0; iis_running() ) { @@ -2376,21 +2439,21 @@ void MWindow::undo_entry(BC_WindowBase *calling_window_gui) void MWindow::new_folder(const char *new_folder, int is_clips) { - undo->update_undo_before(); + undo_before(); if( edl->new_folder(new_folder, is_clips) ) { MainError::show_error(_("create new folder failed")); } - undo->update_undo_after(_("new folder"), LOAD_ALL); + undo_after(_("new folder"), LOAD_ALL); awindow->gui->async_update_assets(); } void MWindow::delete_folder(char *folder) { - undo->update_undo_before(); + undo_before(); if( edl->delete_folder(folder) < 0 ) { MainError::show_error(_("delete folder failed")); } - undo->update_undo_after(_("del folder"), LOAD_ALL); + undo_after(_("del folder"), LOAD_ALL); awindow->gui->async_update_assets(); } @@ -2423,9 +2486,9 @@ void MWindow::select_point(double position) void MWindow::map_audio(int pattern) { - undo->update_undo_before(); + undo_before(); remap_audio(pattern); - undo->update_undo_after( + undo_after( pattern == MWindow::AUDIO_1_TO_1 ? _("map 1:1") : _("map 5.1:2"), LOAD_AUTOMATION); sync_parameters(CHANGE_PARAMS); @@ -2438,7 +2501,7 @@ void MWindow::remap_audio(int pattern) int current_track = 0; for( Track *current=edl->tracks->first; current; current=NEXT ) { if( current->data_type == TRACK_AUDIO && - current->record ) { + current->is_armed() ) { Autos *pan_autos = current->automation->autos[AUTOMATION_PAN]; PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1); @@ -2486,20 +2549,58 @@ void MWindow::rescale_proxy(EDL *clip, int orig_scale, int new_scale) edl->rescale_proxy(orig_scale, new_scale); } -void MWindow::add_proxy(int use_scaler, - ArrayList *orig_assets, ArrayList *proxy_assets) +void MWindow::add_proxy(ArrayList *orig_assets, ArrayList *proxy_assets) { - edl->add_proxy(use_scaler, orig_assets, proxy_assets); + edl->add_proxy(orig_assets, proxy_assets); +} + +void MWindow::start_convert(Asset *format_asset, const char *suffix, + float beep, int to_proxy, int remove_originals) +{ + if( !convert_render ) + convert_render = new ConvertRender(this); + convert_render->set_format(format_asset, suffix, to_proxy); + int found = convert_render->find_convertable_assets(edl); + if( convert_render->needed_idxbls.size() > 0 ) + convert_render->start_convert(beep, remove_originals); + else if( found > 0 ) + finish_convert(remove_originals); + else if( found < 0 ) + eprintf(_("convert assets format error")); + else + eprintf(_("No convertable assets found")); +} + +void MWindow::finish_convert(int remove_originals) +{ + gui->lock_window("MWindow::finish_convert"); + undo_before(); + edl->replace_assets( + convert_render->orig_idxbls, + convert_render->orig_copies); + if( remove_originals ) { + remove_assets_from_project(0, 0, 0, + &convert_render->orig_idxbls, 0); + } + save_backup(); + undo_after(_("convert"), LOAD_ALL); + + update_plugin_guis(); + gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0); + cwindow->update(1, 0, 0, 0, 1); + awindow->gui->async_update_assets(); + cwindow->refresh_frame(CHANGE_EDL); + gui->unlock_window(); } void MWindow::cut_commercials() { #ifdef HAVE_COMMERCIAL - undo->update_undo_before(); + undo_before(); commercials->scan_media(); edl->optimize(); save_backup(); - undo->update_undo_after(_("cut ads"), LOAD_EDITS | LOAD_TIMEBAR); + undo_after(_("cut ads"), LOAD_EDITS | LOAD_TIMEBAR); restart_brender(); update_plugin_guis(); @@ -2509,9 +2610,13 @@ void MWindow::cut_commercials() #endif } -int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl) +int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl, int edit_speed) { - int result = 0; + int edit_plugins = edl->session->plugins_follow_edits; + int edit_autos = edl->session->autos_follow_edits; + int edit_labels = edl->session->labels_follow_edits; + if( !edit_autos ) edit_speed = 0; + int result = 0, first_track = 1; Track *old_track = old_edl->tracks->first; Track *new_track = new_edl->tracks->first; for( ; old_track && new_track; old_track=old_track->next, new_track=new_track->next ) { @@ -2525,20 +2630,107 @@ int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl) old_speed = (FloatAuto *)old_speed->next; new_speed = (FloatAuto *)new_speed->next; } - Edit *old_edit = old_track->edits->first; - Edit *new_edit = new_track->edits->first; - for( ; old_edit && new_edit; old_edit=old_edit->next, new_edit=new_edit->next ) { - int64_t edit_start = old_edit->startproject, edit_end = edit_start + old_edit->length; - if( old_speed || new_speed ) { - double orig_start = old_speeds->automation_integral(0, edit_start, PLAY_FORWARD); - double orig_end = old_speeds->automation_integral(0, edit_end, PLAY_FORWARD); - edit_start = new_speeds->speed_position(orig_start); - edit_end = new_speeds->speed_position(orig_end); - result = 1; + if( !old_speed && !new_speed ) continue; + result = 1; + if( edit_speed ) { + Autos *old_autos = old_track->automation->autos[AUTOMATION_SPEED]; + Autos *new_autos = new_track->automation->autos[AUTOMATION_SPEED]; + Auto *old_auto = old_autos ? old_autos->first : 0; + for( ; old_auto; old_auto=old_auto->next ) { + Auto *new_auto = new_autos->get_auto(old_auto->orig_id); + if( !new_auto ) continue; + int64_t auto_pos = old_auto->position; + double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD); + auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1); + new_auto->position = auto_pos; } + } + Edit *old_edit = old_track->edits->first; + for( ; old_edit; old_edit=old_edit->next ) { + Edit *new_edit = new_track->edits->get_edit(old_edit->orig_id); + if( !new_edit ) continue; + int64_t edit_start = old_edit->startproject; + int64_t edit_end = edit_start + old_edit->length; + double orig_start = old_speeds->automation_integral(0, edit_start, PLAY_FORWARD); + double orig_end = old_speeds->automation_integral(0, edit_end, PLAY_FORWARD); + edit_start = new_track->frame_align(new_speeds->speed_position(orig_start), 1); + edit_end = new_track->frame_align(new_speeds->speed_position(orig_end), 1); new_edit->startproject = edit_start; new_edit->length = edit_end - edit_start; } + if( first_track && old_track->is_armed() ) { + Labels *old_labels = old_edl->labels; + Labels *new_labels = new_edl->labels; + if( edit_labels && old_labels && new_labels ) { + Label *old_label = old_labels->first; + for( ; old_label; old_label=old_label->next ) { + Label *new_label = new_labels->get_label(old_label->orig_id); + if( !new_label ) continue; + int64_t label_pos = old_track->to_units(old_label->position, 1); + double orig_pos = old_speeds->automation_integral(0, label_pos, PLAY_FORWARD); + label_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1); + new_label->position = new_track->from_units(label_pos); + } + } + first_track = 0; + } + if( edit_plugins ) { + int old_size = old_track->plugin_set.size(); + int new_size = new_track->plugin_set.size(); + int n = bmin(old_size, new_size); + for( int i=0; iplugin_set[i]; + if( !old_plugin_set ) continue; + PluginSet *new_plugin_set = new_track->plugin_set[i]; + if( !new_plugin_set ) continue; + Plugin *old_plugin = (Plugin *)old_plugin_set->first; + for( ; old_plugin; old_plugin=(Plugin *)old_plugin->next ) { + Plugin *new_plugin = (Plugin *)new_plugin_set->get_edit(old_plugin->orig_id); + if( !new_plugin ) continue; + int64_t plugin_start = old_plugin->startproject; + int64_t plugin_end = plugin_start + old_plugin->length; + double orig_start = old_speeds->automation_integral(0, plugin_start, PLAY_FORWARD); + double orig_end = old_speeds->automation_integral(0, plugin_end, PLAY_FORWARD); + plugin_start = new_track->frame_align(new_speeds->speed_position(orig_start), 1); + plugin_end = new_track->frame_align(new_speeds->speed_position(orig_end), 1); + new_plugin->startproject = plugin_start; + new_plugin->length = plugin_end - plugin_start; + if( edit_autos ) { + KeyFrames *old_keyframes = old_plugin->keyframes; + if( !old_keyframes ) continue; + KeyFrames *new_keyframes = new_plugin->keyframes; + if( !new_keyframes ) continue; + Auto *old_auto = old_keyframes->first; + for( ; old_auto; old_auto=old_auto->next ) { + Auto *new_auto = new_keyframes->get_auto(old_auto->orig_id); + if( !new_auto ) continue; + int64_t auto_pos = old_auto->position; + double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD); + auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1); + new_auto->position = auto_pos; + old_auto = old_auto->next; + } + } + } + } + } + if( edit_autos ) { // speed must be last + for( int i=0; iautomation->autos[i]; + if( !old_autos ) continue; + Autos *new_autos = new_track->automation->autos[i]; + if( !new_autos ) continue; + Auto *old_auto = old_autos->first; + for( ; old_auto; old_auto=old_auto->next ) { + Auto *new_auto = new_autos->get_auto(old_auto->orig_id); + if( !new_auto ) continue; + int64_t auto_pos = old_auto->position; + double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD); + auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1); + new_auto->position = auto_pos; + } + } + } } return result; } @@ -2552,12 +2744,12 @@ void MWindow::speed_before() speed_edl->copy_all(edl); } -int MWindow::speed_after(int done) +int MWindow::speed_after(int done, int edit_speed) { int result = 0; if( speed_edl ) { if( done >= 0 ) - result = normalize_speed(speed_edl, edl); + result = normalize_speed(speed_edl, edl, edit_speed); if( done != 0 ) { speed_edl->remove_user(); speed_edl = 0; @@ -2566,3 +2758,210 @@ int MWindow::speed_after(int done) return result; } +void MWindow::collect_effects() +{ + FileXML file; + const char *file_string = ""; + EDL *group = 0; + int ret = edl->collect_effects(group); + switch( ret ) { + case COLLECT_EFFECTS_RECORD: + eprintf(_("Selected edit track not armed.")); + break; + case COLLECT_EFFECTS_MULTIPLE: + eprintf(_("More than one edit selected on a track.")); + break; + case COLLECT_EFFECTS_MISSING: + eprintf(_("No effects under selected edit.")); + break; + case COLLECT_EFFECTS_EMPTY: + eprintf(_("No edits selected.")); + break; + case COLLECT_EFFECTS_MASTER: + eprintf(_("Shared effect added without master.")); + break; + case 0: + group->save_xml(&file, ""); + file_string = file.string(); + group->remove_user(); + } + long file_length = strlen(file_string); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); +} + +void MWindow::paste_effects() +{ + char *string = 0; + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); + if( len ) { + string = new char[len]; + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); + } + if( !string || !string[0] ) { + eprintf(_("Error clipboard buffer empty.")); + return; + } + FileXML file; + file.read_from_string(string); + EDL *group = new EDL(); + group->create_objects(); + if( !group->load_xml(&file, LOAD_ALL) ) { + undo_before(); + int ret = edl->insert_effects(group); + switch( ret ) { + case INSERT_EFFECTS_RECORD: + eprintf(_("Selected edit track not armed.")); + break; + case INSERT_EFFECTS_TYPE: + eprintf(_("Track type mismatched.")); + break; + case INSERT_EFFECTS_MULTIPLE: + eprintf(_("More than one edit selected on a track.")); + break; + case INSERT_EFFECTS_MISSING: + eprintf(_("Too few target edits to add group effects.")); + break; + case INSERT_EFFECTS_EXTRA: + eprintf(_("Too many target edits to add group effects.")); + break; + case INSERT_EFFECTS_MASTER: + eprintf(_("Shared effect added without master.")); + break; + case 0: + break; + } + save_backup(); + undo_after(_("paste effects"), LOAD_ALL); + restart_brender(); + cwindow->refresh_frame(CHANGE_EDL); + update_plugin_guis(); + gui->update(1, NORMAL_DRAW, 1, 0, 0, 0, 0); + } + else + eprintf(_("Error loading clip from clipboard buffer.")); + delete [] string; + group->remove_user(); +} + +void MWindow::align_timecodes() +{ + undo_before(); + double offset = edl->tracks->align_timecodes(); + set_timecode_offset(offset); + save_backup(); + undo_after(_("align timecodes"), LOAD_ALL); + restart_brender(); + cwindow->refresh_frame(CHANGE_EDL); + update_plugin_guis(); +} + + +int MWindow::masters_to_mixers() +{ + Track *master_track = edl->tracks->first; + while( master_track && !master_track->master ) + master_track = master_track->next; + while( master_track ) { // test for track/mixer conflicts + int failed = 0; + Track *mixer_last = master_track; + Track *track = master_track->next; + for( ; track && !track->master; track=track->next ) + mixer_last = track; + Track *next_track = track; + if( !master_track->armed ) { + master_track = next_track; + continue; + } + Mixer *master_mixer = 0; + for( int i=0, n=edl->mixers.size(); iindex_in(edl->mixers[i]) >= 0 ) { + master_mixer = edl->mixers[i]; + break; + } + } + if( master_mixer ) { // existing mixer track group + for( track=master_track; !failed && track; track=track->next ) { + if( track->index_in(master_mixer) < 0 ) { + eprintf("Mixer: %s missing track: %s", + master_mixer->title, track->title); + failed = 1; + } + if( track == mixer_last ) break; + } + for( int i=0, n=master_mixer->mixer_ids.size(); !failed && imixer_ids[i], found = 0; + for( track=master_track; track; track=track->next ) { + if( track->mixer_id == mixer_id ) { + found = 1; + break; + } + if( track == mixer_last ) break; + } + if( !found ) { + eprintf("Mixer: %s track missing: %s", + master_mixer->title, track->title); + failed = 1; + } + } + } + else { // create mixer + for( track=master_track->next; !failed && track; track=track->next ) { + for( int i=0, n=edl->mixers.size(); !failed && imixers[i]; + if( track->index_in(mixer) >= 0 ) { + eprintf("Track: %s already exists in mixer: %s", + track->title, mixer->title); + failed = 1; + break; + } + } + if( track == mixer_last ) break; + } + if( !failed ) { // new mixer + ZWindow *zwindow = get_mixer(master_mixer); + zwindow->set_title(master_track->title); + sprintf(master_track->title, _("Mixer %d"), zwindow->idx); + for( track=master_track; track; track=track->next ) { + track->play = track->armed = 0; + master_mixer->mixer_ids.append(track->get_mixer_id()); + if( track == mixer_last ) break; + } + zwindow->start(); + } + } + master_track = next_track; + } + return 0; +} + +void MWindow::mix_masters() +{ + undo_before(); + masters_to_mixers(); + undo_after(_("mix masters"), LOAD_ALL); + + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + gui->activate_timeline(); + cwindow->refresh_frame(CHANGE_EDL); + save_backup(); +} + +void MWindow::create_keyframes(int mask, int mode) +{ + undo_before(); + double start = edl->local_session->get_selectionstart(); + edl->tracks->create_keyframes(start, mask, mode); + double end = edl->local_session->get_selectionend(); + if( end != start ) + edl->tracks->create_keyframes(end, mask, mode); + undo_after(_("create kyfrms"), LOAD_AUTOMATION); + + restart_brender(); + gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0); + gui->activate_timeline(); + cwindow->refresh_frame(CHANGE_EDL); + save_backup(); +} +