X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindowedit.C;h=5e4b797be1f96ead14415d179af9467b3f04116b;hp=82c4f1e4471479b98797d79bc9d3ff09a0a22a19;hb=26d01a213db5d4f6ee57224cc9a9ea37bd74318c;hpb=e620b69f6d3f1de30d8b2a16c46d7729462e5211 diff --git a/cinelerra-5.1/cinelerra/mwindowedit.C b/cinelerra-5.1/cinelerra/mwindowedit.C index 82c4f1e4..5e4b797b 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" @@ -84,86 +85,70 @@ void MWindow::add_audio_track_entry(int above, Track *dst) { undo_before(); - add_audio_track(above, dst); + Track *track = add_audio_track(above, dst); + track->master = 1; save_backup(); 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_before(); - add_video_track(1, dst); + 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_before(); - add_subttl_track(1, dst); + 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() @@ -197,7 +182,7 @@ 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; } @@ -779,19 +764,40 @@ 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(); - 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); + ArrayList shared_locations; + PluginSet *pluginset = session->pluginset_highlighted; + int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0; + int data_type = dest_track->data_type; + int first_track = 1; + + 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(); @@ -805,8 +811,6 @@ void MWindow::insert_effects_cwindow(Track *dest_track) { if( !dest_track ) return; - undo_before(); - double start = 0; double length = dest_track->get_length(); @@ -817,55 +821,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_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(1); + double end_pos = edl->local_session->get_selectionend(1); 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; @@ -878,9 +872,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 ) { @@ -1268,10 +1261,16 @@ void MWindow::overwrite(EDL *source, int all) // 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); @@ -1389,7 +1388,7 @@ if( debug ) printf("MWindow::load_assets %d\n", __LINE__); 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(); @@ -1534,6 +1533,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: @@ -1549,6 +1549,10 @@ 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); @@ -1563,11 +1567,10 @@ 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 ) { + 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); } } @@ -1601,13 +1604,15 @@ 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: current_position = 0; break; @@ -1626,7 +1631,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, load_mode != LOADMODE_ASSETSONLY ) { // Insert labels if( edit_labels ) { - if( load_mode == LOADMODE_PASTE || load_mode == LOADMODE_NESTED ) + if( load_mode == LOADMODE_PASTE ) edl->labels->insert_labels(new_edl->labels, destination_tracks.total ? paste_position[0] : 0.0, edl_length, 1); @@ -1670,14 +1674,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 ) { @@ -1687,7 +1691,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; @@ -1704,6 +1707,7 @@ int MWindow::paste_edls(ArrayList *new_edls, int load_mode, //PRINT_TRACE track->insert_track(new_track, current_position, replace_default, edit_plugins, edit_autos, edl_length); + if( master ) track->master = 1; //PRINT_TRACE } @@ -1714,8 +1718,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; } @@ -2178,7 +2181,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(); @@ -2189,28 +2192,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; @@ -2409,7 +2408,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); @@ -2457,10 +2456,48 @@ 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() @@ -2537,3 +2574,89 @@ 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(); +} +