3 #include "awindowgui.h"
12 #include "cwindowgui.h"
15 #include "edlsession.h"
18 #include "gwindowgui.h"
22 #include "levelwindow.h"
23 #include "localsession.h"
24 #include "mainclock.h"
25 #include "maincursor.h"
26 #include "mainindexes.h"
28 #include "mainsession.h"
30 #include "maskautos.h"
32 #include "mwindowgui.h"
35 #include "playbackengine.h"
36 #include "pluginset.h"
37 #include "recordlabel.h"
38 #include "samplescroll.h"
39 #include "trackcanvas.h"
41 #include "trackscroll.h"
43 #include "transition.h"
44 #include "transportque.h"
46 #include "undostackitem.h"
47 #include "vplayback.h"
49 #include "vwindowgui.h"
51 #include "automation.h"
52 #include "maskautos.h"
62 void MWindow::add_audio_track_entry(int above, Track *dst)
64 add_audio_track(above, dst);
66 undo->update_undo(_("add track"), LOAD_ALL);
69 gui->get_scrollbars();
71 gui->patchbay->update();
74 gui->canvas->activate();
75 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
81 void MWindow::add_video_track_entry(Track *dst)
83 add_video_track(1, dst);
84 undo->update_undo(_("add track"), LOAD_ALL);
87 gui->get_scrollbars();
89 gui->patchbay->update();
92 gui->canvas->activate();
93 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
101 int MWindow::add_audio_track(int above, Track *dst)
103 edl->tracks->add_audio_track(above, dst);
104 edl->tracks->update_y_pixels(theme);
109 int MWindow::add_video_track(int above, Track *dst)
111 edl->tracks->add_video_track(above, dst);
112 edl->tracks->update_y_pixels(theme);
121 void MWindow::asset_to_size()
123 if(session->drag_assets->total &&
124 session->drag_assets->values[0]->video_data)
129 w = session->drag_assets->values[0]->width;
130 h = session->drag_assets->values[0]->height;
133 edl->session->output_w = w;
134 edl->session->output_h = h;
137 if(defaults->get("AUTOASPECT", 0))
139 create_aspect_ratio(edl->session->aspect_w,
140 edl->session->aspect_h,
147 undo->update_undo(_("asset to size"), LOAD_ALL);
149 sync_parameters(CHANGE_ALL);
155 void MWindow::clear_entry()
161 undo->update_undo(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
164 update_plugin_guis();
165 gui->update(1, 2, 1, 1, 1, 1, 0);
166 cwindow->update(1, 0, 0, 0, 1);
167 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
173 void MWindow::clear(int clear_handle)
175 double start = edl->local_session->get_selectionstart();
176 double end = edl->local_session->get_selectionend();
177 if(clear_handle || !EQUIV(start, end))
181 edl->session->labels_follow_edits,
182 edl->session->plugins_follow_edits);
186 void MWindow::clear_automation()
188 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
189 edl->local_session->get_selectionend());
191 undo->update_undo(_("clear keyframes"), LOAD_AUTOMATION);
194 update_plugin_guis();
195 gui->canvas->draw_overlays();
196 gui->canvas->flash();
197 sync_parameters(CHANGE_PARAMS);
198 gui->patchbay->update();
199 cwindow->update(1, 0, 0);
202 int MWindow::clear_default_keyframe()
204 edl->tracks->clear_default_keyframe();
206 undo->update_undo(_("clear default keyframe"), LOAD_AUTOMATION);
209 gui->canvas->draw_overlays();
210 gui->canvas->flash();
211 sync_parameters(CHANGE_PARAMS);
212 gui->patchbay->update();
213 cwindow->update(1, 0, 0);
218 void MWindow::clear_labels()
220 clear_labels(edl->local_session->get_selectionstart(),
221 edl->local_session->get_selectionend());
222 undo->update_undo(_("clear labels"), LOAD_TIMEBAR);
224 gui->timebar->update();
225 cwindow->update(0, 0, 0, 0, 1);
229 int MWindow::clear_labels(double start, double end)
231 edl->labels->clear(start, end, 0);
235 void MWindow::concatenate_tracks()
237 edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
239 undo->update_undo(_("concatenate tracks"), LOAD_EDITS);
242 gui->update(1, 1, 0, 0, 1, 0, 0);
243 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
252 copy(edl->local_session->get_selectionstart(),
253 edl->local_session->get_selectionend());
256 int MWindow::copy(double start, double end)
258 if(start == end) return 1;
260 //printf("MWindow::copy 1\n");
262 //printf("MWindow::copy 1\n");
272 //printf("MWindow::copy 1\n");
274 // File is now terminated and rewound
276 //printf("MWindow::copy 1\n");
277 gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
278 //printf("MWindow::copy\n%s\n", file.string);
279 //printf("MWindow::copy 2\n");
284 int MWindow::copy_automation()
287 edl->tracks->copy_automation(edl->local_session->get_selectionstart(),
288 edl->local_session->get_selectionend(),
292 gui->get_clipboard()->to_clipboard(file.string,
294 SECONDARY_SELECTION);
298 int MWindow::copy_default_keyframe()
301 edl->tracks->copy_default_keyframe(&file);
302 gui->get_clipboard()->to_clipboard(file.string,
304 SECONDARY_SELECTION);
309 // Uses cropping coordinates in edl session to crop and translate video.
310 // We modify the projector since camera automation depends on the track size.
311 void MWindow::crop_video()
314 // Clamp EDL crop region
315 if(edl->session->crop_x1 > edl->session->crop_x2)
317 edl->session->crop_x1 ^= edl->session->crop_x2;
318 edl->session->crop_x2 ^= edl->session->crop_x1;
319 edl->session->crop_x1 ^= edl->session->crop_x2;
321 if(edl->session->crop_y1 > edl->session->crop_y2)
323 edl->session->crop_y1 ^= edl->session->crop_y2;
324 edl->session->crop_y2 ^= edl->session->crop_y1;
325 edl->session->crop_y1 ^= edl->session->crop_y2;
328 float old_projector_x = (float)edl->session->output_w / 2;
329 float old_projector_y = (float)edl->session->output_h / 2;
330 float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
331 float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
332 float projector_offset_x = -(new_projector_x - old_projector_x);
333 float projector_offset_y = -(new_projector_y - old_projector_y);
335 edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
337 edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
338 edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
339 edl->session->crop_x1 = 0;
340 edl->session->crop_y1 = 0;
341 edl->session->crop_x2 = edl->session->output_w;
342 edl->session->crop_y2 = edl->session->output_h;
344 // Recalculate aspect ratio
345 if(defaults->get("AUTOASPECT", 0))
347 create_aspect_ratio(edl->session->aspect_w,
348 edl->session->aspect_h,
349 edl->session->output_w,
350 edl->session->output_h);
353 undo->update_undo(_("crop"), LOAD_ALL);
356 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
366 double start = edl->local_session->get_selectionstart();
367 double end = edl->local_session->get_selectionend();
372 edl->session->labels_follow_edits,
373 edl->session->plugins_follow_edits);
378 undo->update_undo(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
381 update_plugin_guis();
382 gui->update(1, 2, 1, 1, 1, 1, 0);
383 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
389 int MWindow::cut_automation()
394 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
395 edl->local_session->get_selectionend());
397 undo->update_undo(_("cut keyframes"), LOAD_AUTOMATION);
401 update_plugin_guis();
402 gui->canvas->draw_overlays();
403 gui->canvas->flash();
404 sync_parameters(CHANGE_PARAMS);
405 gui->patchbay->update();
406 cwindow->update(1, 0, 0);
410 int MWindow::cut_default_keyframe()
413 copy_default_keyframe();
414 edl->tracks->clear_default_keyframe();
415 undo->update_undo(_("cut default keyframe"), LOAD_AUTOMATION);
418 gui->canvas->draw_overlays();
419 gui->canvas->flash();
420 sync_parameters(CHANGE_PARAMS);
421 gui->patchbay->update();
422 cwindow->update(1, 0, 0);
429 void MWindow::delete_inpoint()
431 edl->local_session->unset_inpoint();
435 void MWindow::delete_outpoint()
437 edl->local_session->unset_outpoint();
441 void MWindow::delete_track()
443 if (edl->tracks->last)
444 delete_track(edl->tracks->last);
447 void MWindow::delete_tracks()
449 edl->tracks->delete_tracks();
450 undo->update_undo(_("delete tracks"), LOAD_ALL);
454 update_plugin_states();
455 gui->update(1, 1, 1, 0, 1, 0, 0);
456 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
462 void MWindow::delete_track(Track *track)
464 edl->tracks->delete_track(track);
465 undo->update_undo(_("delete track"), LOAD_ALL);
468 update_plugin_states();
469 gui->update(1, 1, 1, 0, 1, 0, 0);
470 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
477 void MWindow::detach_transition(Transition *transition)
479 hide_plugin(transition, 1);
480 int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
481 transition->edit->detach_transition();
483 undo->update_undo(_("detach transition"), LOAD_ALL);
485 if(is_video) restart_brender();
493 sync_parameters(CHANGE_EDL);
500 // Insert data from clipboard
501 void MWindow::insert(double position,
507 // For clipboard pasting make the new edl use a separate session
508 // from the master EDL. Then it can be resampled to the master rates.
509 // For splice, overwrite, and dragging need same session to get the assets.
511 ArrayList<EDL*> new_edls;
512 uint32_t load_flags = LOAD_ALL;
515 new_edls.append(&edl);
516 edl.create_objects();
521 if(parent_edl) load_flags &= ~LOAD_SESSION;
522 if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
523 if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
525 edl.load_xml(plugindb, file, load_flags);
532 paste_edls(&new_edls,
539 // printf("MWindow::insert 5 %f %f\n",
540 // vwindow->edl->local_session->in_point,
541 // vwindow->edl->local_session->out_point);
542 new_edls.remove_all();
543 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
546 void MWindow::insert_effects_canvas(double start,
549 Track *dest_track = session->track_highlighted;
550 if(!dest_track) return;
553 for(int i = 0; i < session->drag_pluginservers->total; i++)
555 PluginServer *plugin = session->drag_pluginservers->values[i];
557 insert_effect(plugin->title,
560 i == 0 ? session->pluginset_highlighted : 0,
567 undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
569 sync_parameters(CHANGE_EDL);
570 // GUI updated in TrackCanvas, after current_operations are reset
573 void MWindow::insert_effects_cwindow(Track *dest_track)
575 if(!dest_track) return;
579 double length = dest_track->get_length();
581 if(edl->local_session->get_selectionend() >
582 edl->local_session->get_selectionstart())
584 start = edl->local_session->get_selectionstart();
585 length = edl->local_session->get_selectionend() -
586 edl->local_session->get_selectionstart();
589 for(int i = 0; i < session->drag_pluginservers->total; i++)
591 PluginServer *plugin = session->drag_pluginservers->values[i];
594 insert_effect(plugin->title,
604 undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
606 sync_parameters(CHANGE_EDL);
618 void MWindow::insert_effect(char *title,
619 SharedLocation *shared_location,
621 PluginSet *plugin_set,
626 KeyFrame *default_keyframe = 0;
627 PluginServer *server = 0;
634 // Get default keyframe
635 if(plugin_type == PLUGIN_STANDALONE)
637 default_keyframe = new KeyFrame;
638 server = new PluginServer(*scan_plugindb(title, track->data_type));
640 server->open_plugin(0, preferences, edl, 0, -1);
641 server->save_data(default_keyframe);
646 // Insert plugin object
647 track->insert_effect(title,
658 if(plugin_type == PLUGIN_STANDALONE)
660 server->close_plugin();
662 delete default_keyframe;
666 int MWindow::modify_edithandles()
673 edl->modify_edithandles(session->drag_start,
674 session->drag_position,
675 session->drag_handle,
676 edl->session->edit_handle_mode[session->drag_button],
677 edl->session->labels_follow_edits,
678 edl->session->plugins_follow_edits);
680 finish_modify_handles();
683 //printf("MWindow::modify_handles 1\n");
687 int MWindow::modify_pluginhandles()
690 edl->modify_pluginhandles(session->drag_start,
691 session->drag_position,
692 session->drag_handle,
693 edl->session->edit_handle_mode[session->drag_button],
694 edl->session->labels_follow_edits,
695 session->trim_edits);
697 finish_modify_handles();
703 // Common to edithandles and plugin handles
704 void MWindow::finish_modify_handles()
706 int edit_mode = edl->session->edit_handle_mode[session->drag_button];
708 if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
709 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
711 edl->local_session->set_selectionstart(session->drag_position);
712 edl->local_session->set_selectionend(session->drag_position);
715 if(edit_mode != MOVE_NO_EDITS)
717 edl->local_session->set_selectionstart(session->drag_start);
718 edl->local_session->set_selectionend(session->drag_start);
721 if(edl->local_session->get_selectionstart(1) < 0)
723 edl->local_session->set_selectionstart(0);
724 edl->local_session->set_selectionend(0);
728 undo->update_undo(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
730 sync_parameters(CHANGE_EDL);
731 update_plugin_guis();
732 gui->update(1, 2, 1, 1, 1, 1, 0);
733 cwindow->update(1, 0, 0, 0, 1);
736 void MWindow::match_output_size(Track *track)
738 track->track_w = edl->session->output_w;
739 track->track_h = edl->session->output_h;
741 undo->update_undo(_("match output size"), LOAD_ALL);
744 sync_parameters(CHANGE_EDL);
748 void MWindow::move_edits(ArrayList<Edit*> *edits,
754 edl->tracks->move_edits(edits,
757 edl->session->labels_follow_edits,
758 edl->session->plugins_follow_edits,
762 undo->update_undo(_("move edit"), LOAD_ALL);
765 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
770 update_plugin_guis();
772 1, // 1 for incremental drawing. 2 for full refresh
780 void MWindow::move_effect(Plugin *plugin,
781 PluginSet *dest_plugin_set,
783 int64_t dest_position)
786 edl->tracks->move_effect(plugin,
792 undo->update_undo(_("move effect"), LOAD_ALL);
795 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
800 update_plugin_guis();
802 1, // 1 for incremental drawing. 2 for full refresh
810 void MWindow::move_plugins_up(PluginSet *plugin_set)
813 plugin_set->track->move_plugins_up(plugin_set);
816 undo->update_undo(_("move effect up"), LOAD_ALL);
819 1, // 1 for incremental drawing. 2 for full refresh
825 sync_parameters(CHANGE_EDL);
828 void MWindow::move_plugins_down(PluginSet *plugin_set)
831 plugin_set->track->move_plugins_down(plugin_set);
834 undo->update_undo(_("move effect down"), LOAD_ALL);
837 1, // 1 for incremental drawing. 2 for full refresh
843 sync_parameters(CHANGE_EDL);
846 void MWindow::move_track_down(Track *track)
848 edl->tracks->move_track_down(track);
850 undo->update_undo(_("move track down"), LOAD_ALL);
853 gui->update(1, 1, 0, 0, 1, 0, 0);
854 sync_parameters(CHANGE_EDL);
858 void MWindow::move_tracks_down()
860 edl->tracks->move_tracks_down();
862 undo->update_undo(_("move tracks down"), LOAD_ALL);
865 gui->update(1, 1, 0, 0, 1, 0, 0);
866 sync_parameters(CHANGE_EDL);
870 void MWindow::move_track_up(Track *track)
872 edl->tracks->move_track_up(track);
874 undo->update_undo(_("move track up"), LOAD_ALL);
876 gui->update(1, 1, 0, 0, 1, 0, 0);
877 sync_parameters(CHANGE_EDL);
881 void MWindow::move_tracks_up()
883 edl->tracks->move_tracks_up();
885 undo->update_undo(_("move tracks up"), LOAD_ALL);
887 gui->update(1, 1, 0, 0, 1, 0, 0);
888 sync_parameters(CHANGE_EDL);
892 void MWindow::mute_selection()
894 double start = edl->local_session->get_selectionstart();
895 double end = edl->local_session->get_selectionend();
901 edl->session->plugins_follow_edits);
902 edl->local_session->set_selectionend(end);
903 edl->local_session->set_selectionstart(start);
904 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
906 undo->update_undo(_("mute"), LOAD_EDITS);
909 update_plugin_guis();
910 gui->update(1, 2, 1, 1, 1, 1, 0);
911 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
920 void MWindow::overwrite(EDL *source)
924 double src_start = source->local_session->get_selectionstart();
925 double overwrite_len = source->local_session->get_selectionend() - src_start;
926 double dst_start = edl->local_session->get_selectionstart();
927 double dst_len = edl->local_session->get_selectionend() - dst_start;
929 if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
931 // in/out points or selection present and shorter than overwrite range
932 // shorten the copy range
933 overwrite_len = dst_len;
936 source->copy(src_start,
937 src_start + overwrite_len,
946 // HACK around paste_edl get_start/endselection on its own
947 // so we need to clear only when not using both io points
948 // FIXME: need to write simple overwrite_edl to be used for overwrite function
949 if (edl->local_session->get_inpoint() < 0 ||
950 edl->local_session->get_outpoint() < 0)
951 edl->clear(dst_start,
952 dst_start + overwrite_len,
957 dst_start + overwrite_len,
962 edl->local_session->set_selectionstart(dst_start + overwrite_len);
963 edl->local_session->set_selectionend(dst_start + overwrite_len);
966 undo->update_undo(_("overwrite"), LOAD_EDITS);
969 update_plugin_guis();
970 gui->update(1, 1, 1, 1, 0, 1, 0);
971 sync_parameters(CHANGE_EDL);
974 // For splice and overwrite
975 int MWindow::paste(double start,
983 // Want to insert with assets shared with the master EDL.
993 // For editing use insertion point position
994 void MWindow::paste()
997 double start = edl->local_session->get_selectionstart();
998 double end = edl->local_session->get_selectionend();
999 int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1003 char *string = new char[len + 1];
1007 gui->get_clipboard()->from_clipboard(string,
1009 SECONDARY_SELECTION);
1011 file.read_from_string(string);
1020 edl->session->labels_follow_edits,
1021 edl->session->plugins_follow_edits);
1033 undo->update_undo(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1035 update_plugin_guis();
1036 gui->update(1, 2, 1, 1, 0, 1, 0);
1037 awindow->gui->update_assets();
1038 sync_parameters(CHANGE_EDL);
1043 int MWindow::paste_assets(double position, Track *dest_track)
1050 if(session->drag_assets->total)
1052 load_assets(session->drag_assets,
1057 edl->session->labels_follow_edits,
1058 edl->session->plugins_follow_edits);
1063 if(session->drag_clips->total)
1065 paste_edls(session->drag_clips,
1069 edl->session->labels_follow_edits,
1070 edl->session->plugins_follow_edits);
1077 undo->update_undo(_("paste assets"), LOAD_EDITS);
1086 sync_parameters(CHANGE_EDL);
1090 void MWindow::load_assets(ArrayList<Asset*> *new_assets,
1094 RecordLabels *labels,
1098 //printf("MWindow::load_assets 1\n");
1099 if(position < 0) position = edl->local_session->get_selectionstart();
1101 ArrayList<EDL*> new_edls;
1102 for(int i = 0; i < new_assets->total; i++)
1104 EDL *new_edl = new EDL;
1105 new_edl->create_objects();
1106 new_edl->copy_session(edl);
1107 new_edls.append(new_edl);
1110 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1111 asset_to_edl(new_edl, new_assets->values[i]);
1115 for(RecordLabel *label = labels->first; label; label = label->next)
1117 new_edl->labels->toggle_label(label->position, label->position);
1120 //printf("MWindow::load_assets 3\n");
1122 paste_edls(&new_edls,
1128 //printf("MWindow::load_assets 4\n");
1132 new_edls.remove_all_objects();
1136 int MWindow::paste_automation()
1138 int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1142 char *string = new char[len + 1];
1143 gui->get_clipboard()->from_clipboard(string,
1145 SECONDARY_SELECTION);
1147 file.read_from_string(string);
1149 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
1150 edl->local_session->get_selectionend());
1151 edl->tracks->paste_automation(edl->local_session->get_selectionstart(),
1155 undo->update_undo(_("paste keyframes"), LOAD_AUTOMATION);
1160 update_plugin_guis();
1161 gui->canvas->draw_overlays();
1162 gui->canvas->flash();
1163 sync_parameters(CHANGE_PARAMS);
1164 gui->patchbay->update();
1165 cwindow->update(1, 0, 0);
1171 int MWindow::paste_default_keyframe()
1173 int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1177 char *string = new char[len + 1];
1178 gui->get_clipboard()->from_clipboard(string,
1180 SECONDARY_SELECTION);
1182 file.read_from_string(string);
1183 edl->tracks->paste_default_keyframe(&file);
1184 undo->update_undo(_("paste default keyframe"), LOAD_AUTOMATION);
1188 update_plugin_guis();
1189 gui->canvas->draw_overlays();
1190 gui->canvas->flash();
1191 sync_parameters(CHANGE_PARAMS);
1192 gui->patchbay->update();
1193 cwindow->update(1, 0, 0);
1202 // Insert edls with project deletion and index file generation.
1203 int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
1206 double current_position,
1211 ArrayList<Track*> destination_tracks;
1212 int need_new_tracks = 0;
1214 if(!new_edls->total) return 0;
1216 //printf("MWindow::paste_edls 1\n");
1218 // Delete current project
1219 if(load_mode == LOAD_REPLACE ||
1220 load_mode == LOAD_REPLACE_CONCATENATE)
1223 edl->save_defaults(defaults);
1231 edl->create_objects();
1233 edl->copy_session(new_edls->values[0]);
1235 gui->mainmenu->update_toggles(0);
1238 gui->unlock_window();
1240 gwindow->gui->update_toggles(1);
1242 gui->lock_window("MWindow::paste_edls");
1245 // Insert labels for certain modes constitutively
1252 // Create new tracks in master EDL
1253 if(load_mode == LOAD_REPLACE ||
1254 load_mode == LOAD_REPLACE_CONCATENATE ||
1255 load_mode == LOAD_NEW_TRACKS)
1258 need_new_tracks = 1;
1259 for(int i = 0; i < new_edls->total; i++)
1261 EDL *new_edl = new_edls->values[i];
1262 for(Track *current = new_edl->tracks->first;
1266 if(current->data_type == TRACK_VIDEO)
1268 edl->tracks->add_video_track(0, 0);
1269 if(current->draw) edl->tracks->last->draw = 1;
1270 destination_tracks.append(edl->tracks->last);
1273 if(current->data_type == TRACK_AUDIO)
1275 edl->tracks->add_audio_track(0, 0);
1276 destination_tracks.append(edl->tracks->last);
1278 edl->session->highlighted_track = edl->tracks->total() - 1;
1281 // Base track count on first EDL only for concatenation
1282 if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1287 // Recycle existing tracks of master EDL
1288 if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1291 // The point of this is to shift forward labels after the selection so they can
1292 // then be shifted back to their original locations without recursively
1293 // shifting back every paste.
1294 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1295 edl->labels->clear(edl->local_session->get_selectionstart(),
1296 edl->local_session->get_selectionend(),
1299 Track *current = first_track ? first_track : edl->tracks->first;
1300 for( ; current; current = NEXT)
1304 destination_tracks.append(current);
1306 // This should be done in the caller so we don't get recursive clear disease.
1307 // if(load_mode == LOAD_PASTE)
1308 // current->clear(edl->local_session->get_selectionstart(),
1309 // edl->local_session->get_selectionend(),
1311 // edl->session->labels_follow_edits,
1312 // edl->session->plugins_follow_edits,
1322 int destination_track = 0;
1323 double *paste_position = new double[destination_tracks.total];
1329 // Iterate through the edls
1330 for(int i = 0; i < new_edls->total; i++)
1333 EDL *new_edl = new_edls->values[i];
1334 double edl_length = new_edl->local_session->clipboard_length ?
1335 new_edl->local_session->clipboard_length :
1336 new_edl->tracks->total_length();
1337 // printf("MWindow::paste_edls 2\n");
1343 // Resample EDL to master rates
1344 new_edl->resample(new_edl->session->sample_rate,
1345 edl->session->sample_rate,
1347 new_edl->resample(new_edl->session->frame_rate,
1348 edl->session->frame_rate,
1354 // Add assets and prepare index files
1355 for(Asset *new_asset = new_edl->assets->first;
1357 new_asset = new_asset->next)
1359 mainindexes->add_next_asset(0, new_asset);
1361 // Capture index file status from mainindex test
1362 edl->update_assets(new_edl);
1366 // Get starting point of insertion. Need this to paste labels.
1370 case LOAD_NEW_TRACKS:
1371 current_position = 0;
1374 case LOAD_CONCATENATE:
1375 case LOAD_REPLACE_CONCATENATE:
1376 destination_track = 0;
1377 if(destination_tracks.total)
1378 current_position = destination_tracks.values[0]->get_length();
1380 current_position = 0;
1384 destination_track = 0;
1387 for(int j = 0; j < destination_tracks.total; j++)
1389 paste_position[j] = (current_position >= 0) ?
1391 edl->local_session->get_selectionstart();
1396 case LOAD_RESOURCESONLY:
1397 edl->add_clip(new_edl);
1406 if(load_mode != LOAD_RESOURCESONLY)
1409 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1410 if(load_mode == LOAD_PASTE)
1411 edl->labels->insert_labels(new_edl->labels,
1412 destination_tracks.total ? paste_position[0] : 0.0,
1416 edl->labels->insert_labels(new_edl->labels,
1421 for(Track *new_track = new_edl->tracks->first;
1423 new_track = new_track->next)
1425 // Get destination track of same type as new_track
1427 k < destination_tracks.total &&
1428 destination_tracks.values[destination_track]->data_type != new_track->data_type;
1429 k++, destination_track++)
1431 if(destination_track >= destination_tracks.total - 1)
1432 destination_track = 0;
1435 // Insert data into destination track
1436 if(destination_track < destination_tracks.total &&
1437 destination_tracks.values[destination_track]->data_type == new_track->data_type)
1439 Track *track = destination_tracks.values[destination_track];
1441 // Replace default keyframes if first EDL and new tracks were created.
1442 // This means data copied from one track and pasted to another won't retain
1443 // the camera position unless it's a keyframe. If it did, previous data in the
1444 // track might get unknowingly corrupted. Ideally we would detect when differing
1445 // default keyframes existed and create discrete keyframes for both.
1446 int replace_default = (i == 0) && need_new_tracks;
1448 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1449 // Insert new track at current position
1452 case LOAD_REPLACE_CONCATENATE:
1453 case LOAD_CONCATENATE:
1454 current_position = track->get_length();
1458 current_position = paste_position[destination_track];
1459 paste_position[destination_track] += new_track->get_length();
1463 track->insert_track(new_track,
1469 // Get next destination track
1470 destination_track++;
1471 if(destination_track >= destination_tracks.total)
1472 destination_track = 0;
1476 if(load_mode == LOAD_PASTE)
1477 current_position += edl_length;
1480 // Move loading of clips and vwindow to the end - this fixes some strange issue, for index not being shown
1481 // Assume any paste operation from the same EDL won't contain any clips.
1482 // If it did it would duplicate every clip here.
1483 for(int i = 0; i < new_edls->total; i++)
1485 EDL *new_edl = new_edls->values[i];
1487 for(int j = 0; j < new_edl->clips.total; j++)
1489 edl->add_clip(new_edl->clips.values[j]);
1492 if(new_edl->vwindow_edl)
1494 if(edl->vwindow_edl) delete edl->vwindow_edl;
1495 edl->vwindow_edl = new EDL(edl);
1496 edl->vwindow_edl->create_objects();
1497 edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1504 if(paste_position) delete [] paste_position;
1507 // This is already done in load_filenames and everything else that uses paste_edls
1508 // update_project(load_mode);
1512 // Start examining next batch of index files
1513 mainindexes->start_build();
1516 // Don't save a backup after loading since the loaded file is on disk already.
1522 void MWindow::paste_silence()
1524 double start = edl->local_session->get_selectionstart();
1525 double end = edl->local_session->get_selectionend();
1526 edl->paste_silence(start,
1528 edl->session->labels_follow_edits,
1529 edl->session->plugins_follow_edits);
1532 undo->update_undo(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1534 update_plugin_guis();
1536 gui->update(1, 2, 1, 1, 1, 1, 0);
1537 cwindow->update(1, 0, 0, 0, 1);
1538 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1544 void MWindow::paste_transition()
1546 // Only the first transition gets dropped.
1547 PluginServer *server = session->drag_pluginservers->values[0];
1549 strcpy(edl->session->default_atransition, server->title);
1551 strcpy(edl->session->default_vtransition, server->title);
1553 edl->tracks->paste_transition(server, session->edit_highlighted);
1555 undo->update_undo(_("transition"), LOAD_EDITS);
1557 if(server->video) restart_brender();
1558 sync_parameters(CHANGE_ALL);
1561 void MWindow::paste_transition_cwindow(Track *dest_track)
1563 PluginServer *server = session->drag_pluginservers->values[0];
1564 edl->tracks->paste_video_transition(server, 1);
1566 undo->update_undo(_("transition"), LOAD_EDITS);
1568 gui->update(0, 1, 0, 0, 0, 0, 0);
1569 sync_parameters(CHANGE_ALL);
1572 void MWindow::paste_audio_transition()
1574 PluginServer *server = scan_plugindb(edl->session->default_atransition,
1578 char string[BCTEXTLEN];
1579 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1580 gui->show_message(string);
1584 edl->tracks->paste_audio_transition(server);
1586 undo->update_undo(_("transition"), LOAD_EDITS);
1588 sync_parameters(CHANGE_ALL);
1589 gui->update(0, 1, 0, 0, 0, 0, 0);
1592 void MWindow::paste_video_transition()
1594 PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1598 char string[BCTEXTLEN];
1599 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1600 gui->show_message(string);
1605 edl->tracks->paste_video_transition(server);
1607 undo->update_undo(_("transition"), LOAD_EDITS);
1609 sync_parameters(CHANGE_ALL);
1611 gui->update(0, 1, 0, 0, 0, 0, 0);
1615 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1618 calling_window_gui->unlock_window();
1620 cwindow->playback_engine->que->send_command(STOP,
1624 vwindow->playback_engine->que->send_command(STOP,
1628 cwindow->playback_engine->interrupt_playback(0);
1629 vwindow->playback_engine->interrupt_playback(0);
1632 cwindow->gui->lock_window("MWindow::redo_entry");
1633 vwindow->gui->lock_window("MWindow::undo_entry 2");
1639 update_plugin_states();
1640 update_plugin_guis();
1642 gui->update(1, 2, 1, 1, 1, 1, 1);
1643 cwindow->update(1, 1, 1, 1, 1);
1645 if (calling_window_gui != cwindow->gui)
1646 cwindow->gui->unlock_window();
1647 if (calling_window_gui != gui)
1648 gui->unlock_window();
1649 if (calling_window_gui != vwindow->gui)
1650 vwindow->gui->unlock_window();
1652 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1660 void MWindow::resize_track(Track *track, int w, int h)
1662 // We have to move all maskpoints so they do not move in relation to image areas
1663 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1664 (w - track->track_w) / 2,
1665 (h - track->track_h) / 2);
1668 undo->update_undo(_("resize track"), LOAD_ALL);
1672 sync_parameters(CHANGE_EDL);
1676 class InPointUndoItem : public UndoStackItem
1679 InPointUndoItem(double old_position, double new_position, EDL *edl);
1683 double old_position;
1684 double new_position;
1688 InPointUndoItem::InPointUndoItem(
1689 double old_position, double new_position, EDL *edl)
1691 set_description(_("in point"));
1692 this->old_position = old_position;
1693 this->new_position = new_position;
1697 void InPointUndoItem::undo()
1699 edl->set_inpoint(old_position);
1700 // prepare to undo the undo
1701 double tmp = new_position;
1702 new_position = old_position;
1706 int InPointUndoItem::get_size()
1711 void MWindow::set_inpoint(int is_mwindow)
1713 InPointUndoItem *undo_item;
1715 undo_item = new InPointUndoItem(edl->local_session->get_inpoint(),
1716 edl->local_session->get_selectionstart(1), edl);
1717 undo->push_undo_item(undo_item);
1719 edl->set_inpoint(edl->local_session->get_selectionstart(1));
1724 gui->lock_window("MWindow::set_inpoint 1");
1726 gui->timebar->update();
1730 gui->unlock_window();
1735 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1737 cwindow->gui->timebar->update();
1738 cwindow->gui->flush();
1741 cwindow->gui->unlock_window();
1745 class OutPointUndoItem : public UndoStackItem
1748 OutPointUndoItem(double old_position, double new_position, EDL *edl);
1752 double old_position;
1753 double new_position;
1757 OutPointUndoItem::OutPointUndoItem(
1758 double old_position, double new_position, EDL *edl)
1760 set_description(_("out point"));
1761 this->old_position = old_position;
1762 this->new_position = new_position;
1766 void OutPointUndoItem::undo()
1768 edl->set_outpoint(old_position);
1769 // prepare to undo the undo
1770 double tmp = new_position;
1771 new_position = old_position;
1775 int OutPointUndoItem::get_size()
1780 void MWindow::set_outpoint(int is_mwindow)
1782 OutPointUndoItem *undo_item;
1784 undo_item = new OutPointUndoItem(edl->local_session->get_outpoint(),
1785 edl->local_session->get_selectionend(1), edl);
1786 undo->push_undo_item(undo_item);
1788 edl->set_outpoint(edl->local_session->get_selectionend(1));
1793 gui->lock_window("MWindow::set_outpoint 1");
1795 gui->timebar->update();
1799 gui->unlock_window();
1804 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1806 cwindow->gui->timebar->update();
1807 cwindow->gui->flush();
1810 cwindow->gui->unlock_window();
1814 void MWindow::splice(EDL *source)
1818 source->copy(source->local_session->get_selectionstart(),
1819 source->local_session->get_selectionend(),
1831 double start = edl->local_session->get_selectionstart();
1832 double end = edl->local_session->get_selectionend();
1833 double source_start = source->local_session->get_selectionstart();
1834 double source_end = source->local_session->get_selectionend();
1839 edl->session->labels_follow_edits,
1840 edl->session->plugins_follow_edits);
1842 // Position at end of clip
1843 edl->local_session->set_selectionstart(start +
1846 edl->local_session->set_selectionend(start +
1851 undo->update_undo(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1852 update_plugin_guis();
1854 gui->update(1, 1, 1, 1, 0, 1, 0);
1855 sync_parameters(CHANGE_EDL);
1858 void MWindow::to_clip()
1863 start = edl->local_session->get_selectionstart();
1864 end = edl->local_session->get_selectionend();
1866 if(EQUIV(end, start))
1869 end = edl->tracks->total_length();
1872 // Don't copy all since we don't want the clips twice.
1884 EDL *new_edl = new EDL(edl);
1885 new_edl->create_objects();
1886 new_edl->load_xml(plugindb, &file, LOAD_ALL);
1887 sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1888 new_edl->local_session->set_selectionstart(0);
1889 new_edl->local_session->set_selectionend(0);
1891 awindow->clip_edit->create_clip(new_edl);
1895 class LabelUndoItem : public UndoStackItem
1898 LabelUndoItem(double position1, double position2, EDL *edl);
1907 LabelUndoItem::LabelUndoItem(
1908 double position1, double position2, EDL *edl)
1910 set_description(_("label"));
1911 this->position1 = position1;
1912 this->position2 = position2;
1916 void LabelUndoItem::undo()
1918 edl->labels->toggle_label(position1, position2);
1921 int LabelUndoItem::get_size()
1926 int MWindow::toggle_label(int is_mwindow)
1928 LabelUndoItem *undo_item;
1929 double position1, position2;
1931 if(cwindow->playback_engine->is_playing_back)
1933 position1 = position2 =
1934 cwindow->playback_engine->get_tracking_position();
1938 position1 = edl->local_session->get_selectionstart(1);
1939 position2 = edl->local_session->get_selectionend(1);
1942 position1 = edl->align_to_frame(position1, 0);
1943 position2 = edl->align_to_frame(position2, 0);
1945 //printf("MWindow::toggle_label 1\n");
1946 undo_item = new LabelUndoItem(position1, position2, edl);
1947 undo->push_undo_item(undo_item);
1949 edl->labels->toggle_label(position1, position2);
1954 gui->lock_window("MWindow::toggle_label 1");
1956 gui->timebar->update();
1957 gui->canvas->activate();
1961 gui->unlock_window();
1966 cwindow->gui->lock_window("MWindow::toggle_label 2");
1968 cwindow->gui->timebar->update();
1969 cwindow->gui->flush();
1972 cwindow->gui->unlock_window();
1978 void MWindow::trim_selection()
1982 edl->trim_selection(edl->local_session->get_selectionstart(),
1983 edl->local_session->get_selectionend(),
1984 edl->session->labels_follow_edits,
1985 edl->session->plugins_follow_edits);
1988 undo->update_undo(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
1989 update_plugin_guis();
1990 gui->update(1, 2, 1, 1, 1, 1, 0);
1992 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
2000 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2003 // gui->unlock_window();
2005 // cwindow->gui->unlock_window();
2006 calling_window_gui->unlock_window();
2008 cwindow->playback_engine->que->send_command(STOP,
2012 vwindow->playback_engine->que->send_command(STOP,
2016 cwindow->playback_engine->interrupt_playback(0);
2017 vwindow->playback_engine->interrupt_playback(0);
2019 cwindow->gui->lock_window("MWindow::undo_entry 1");
2020 vwindow->gui->lock_window("MWindow::undo_entry 4");
2021 gui->lock_window("MWindow::undo_entry 2");
2027 update_plugin_states();
2028 update_plugin_guis();
2029 gui->update(1, 2, 1, 1, 1, 1, 1);
2030 cwindow->update(1, 1, 1, 1, 1);
2033 // cwindow->gui->unlock_window();
2035 // gui->unlock_window();
2036 if (calling_window_gui != cwindow->gui)
2037 cwindow->gui->unlock_window();
2038 if (calling_window_gui != gui)
2039 gui->unlock_window();
2040 if (calling_window_gui != vwindow->gui)
2041 vwindow->gui->unlock_window();
2044 awindow->gui->lock_window("MWindow::undo_entry 3");
2045 awindow->gui->update_assets();
2046 awindow->gui->flush();
2047 awindow->gui->unlock_window();
2048 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
2056 void MWindow::new_folder(char *new_folder)
2058 edl->new_folder(new_folder);
2059 undo->update_undo(_("new folder"), LOAD_ALL);
2060 awindow->gui->lock_window("MWindow::new_folder");
2061 awindow->gui->update_assets();
2062 awindow->gui->unlock_window();
2065 void MWindow::delete_folder(char *folder)
2067 // undo->update_undo(_("delete folder"), LOAD_ALL);
2070 void MWindow::select_point(double position)
2072 edl->local_session->set_selectionstart(position);
2073 edl->local_session->set_selectionend(position);
2076 cwindow->update(1, 0, 0, 0, 1);
2077 update_plugin_guis();
2078 gui->patchbay->update();
2079 gui->cursor->hide();
2080 gui->cursor->draw();
2081 gui->mainclock->update(edl->local_session->get_selectionstart(1));
2082 gui->zoombar->update();
2083 gui->canvas->flash();