3 * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "awindowgui.h"
25 #include "bcsignals.h"
29 #include "commercials.h"
30 #include "cplayback.h"
33 #include "cwindowgui.h"
36 #include "edlsession.h"
37 #include "filesystem.h"
39 #include "floatauto.h"
40 #include "floatautos.h"
42 #include "gwindowgui.h"
46 #include "levelwindow.h"
47 #include "localsession.h"
48 #include "mainclock.h"
49 #include "maincursor.h"
50 #include "mainerror.h"
51 #include "mainindexes.h"
53 #include "mainsession.h"
55 #include "maskautos.h"
57 #include "mwindowgui.h"
61 #include "playbackengine.h"
62 #include "pluginset.h"
63 #include "recordlabel.h"
64 #include "samplescroll.h"
65 #include "trackcanvas.h"
67 #include "trackscroll.h"
69 #include "transition.h"
70 #include "transportque.h"
72 #include "undostackitem.h"
73 #include "vplayback.h"
75 #include "vwindowgui.h"
77 #include "automation.h"
78 #include "maskautos.h"
82 void MWindow::add_audio_track_entry(int above, Track *dst)
84 undo->update_undo_before();
85 add_audio_track(above, dst);
87 undo->update_undo_after(_("add track"), LOAD_ALL);
90 gui->update(1, 1, 0, 0, 1, 0, 0);
91 gui->activate_timeline();
93 // gui->get_scrollbars(0);
94 // gui->canvas->draw();
95 // gui->patchbay->update();
96 // gui->cursor->draw(1);
97 // gui->canvas->flash();
98 // gui->canvas->activate();
99 cwindow->playback_engine->que->
100 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
103 void MWindow::add_video_track_entry(Track *dst)
105 undo->update_undo_before();
106 add_video_track(1, dst);
107 undo->update_undo_after(_("add track"), LOAD_ALL);
111 gui->update(1, 1, 0, 0, 1, 0, 0);
112 gui->activate_timeline();
113 // gui->get_scrollbars(0);
114 // gui->canvas->draw();
115 // gui->patchbay->update();
116 // gui->cursor->draw(1);
117 // gui->canvas->flash();
118 // gui->canvas->activate();
119 cwindow->playback_engine->que->
120 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
124 void MWindow::add_subttl_track_entry(Track *dst)
126 undo->update_undo_before();
127 add_subttl_track(1, dst);
128 undo->update_undo_after(_("add track"), LOAD_ALL);
132 gui->update(1, 1, 0, 0, 1, 0, 0);
133 gui->activate_timeline();
134 // gui->get_scrollbars(0);
135 // gui->canvas->draw();
136 // gui->patchbay->update();
137 // gui->cursor->draw(1);
138 // gui->canvas->flash();
139 // gui->canvas->activate();
140 cwindow->playback_engine->que->
141 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
146 int MWindow::add_audio_track(int above, Track *dst)
148 edl->tracks->add_audio_track(above, dst);
149 edl->tracks->update_y_pixels(theme);
154 int MWindow::add_video_track(int above, Track *dst)
156 edl->tracks->add_video_track(above, dst);
157 edl->tracks->update_y_pixels(theme);
162 int MWindow::add_subttl_track(int above, Track *dst)
164 edl->tracks->add_subttl_track(above, dst);
165 edl->tracks->update_y_pixels(theme);
170 void MWindow::asset_to_all()
172 if( !session->drag_assets->size() ) return;
173 Indexable *indexable = session->drag_assets->get(0);
175 // if( indexable->have_video() )
179 undo->update_undo_before();
182 w = indexable->get_w();
183 h = indexable->get_h();
184 double new_framerate = session->drag_assets->get(0)->get_frame_rate();
185 double old_framerate = edl->session->frame_rate;
186 int old_samplerate = edl->session->sample_rate;
187 int new_samplerate = session->drag_assets->get(0)->get_sample_rate();
190 if( indexable->have_video() ) {
191 edl->session->output_w = w;
192 edl->session->output_h = h;
193 edl->session->frame_rate = new_framerate;
195 edl->session->aspect_w,
196 edl->session->aspect_h,
199 for( Track *current = edl->tracks->first; current; current = NEXT ) {
200 if( current->data_type == TRACK_VIDEO /* &&
201 current->record */ ) {
202 current->track_w = w;
203 current->track_h = h;
208 if( ((edl->session->output_w % 4) ||
209 (edl->session->output_h % 4)) &&
210 edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) {
211 MainError::show_error(
212 _("This project's dimensions are not multiples of 4 so\n"
213 "it can't be rendered by OpenGL."));
217 if( defaults->get("AUTOASPECT", 0) ) {
219 edl->session->aspect_w,
220 edl->session->aspect_h,
225 if( indexable->have_audio() ) {
226 edl->session->sample_rate = new_samplerate;
227 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
228 edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
233 undo->update_undo_after(_("asset to all"), LOAD_ALL);
235 gui->update(1, 2, 1, 1, 1, 1, 0);
236 sync_parameters(CHANGE_ALL);
240 void MWindow::asset_to_size()
242 if( !session->drag_assets->size() ) return;
243 Indexable *indexable = session->drag_assets->get(0);
245 if( indexable->have_video() ) {
247 undo->update_undo_before();
250 w = indexable->get_w();
251 h = indexable->get_h();
252 edl->session->output_w = w;
253 edl->session->output_h = h;
255 if( ((edl->session->output_w % 4) ||
256 (edl->session->output_h % 4)) &&
257 edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) {
258 MainError::show_error(
259 _("This project's dimensions are not multiples of 4 so\n"
260 "it can't be rendered by OpenGL."));
264 if( defaults->get("AUTOASPECT", 0) ) {
265 create_aspect_ratio(edl->session->aspect_w,
266 edl->session->aspect_h,
273 undo->update_undo_after(_("asset to size"), LOAD_ALL);
275 sync_parameters(CHANGE_ALL);
280 void MWindow::asset_to_rate()
282 if( session->drag_assets->size() &&
283 session->drag_assets->get(0)->have_video() ) {
284 double new_framerate = session->drag_assets->get(0)->get_frame_rate();
285 double old_framerate = edl->session->frame_rate;
286 undo->update_undo_before();
288 edl->session->frame_rate = new_framerate;
289 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
293 undo->update_undo_after(_("asset to rate"), LOAD_ALL);
295 gui->update(1, 2, 1, 1, 1, 1, 0);
296 sync_parameters(CHANGE_ALL);
301 void MWindow::clear_entry()
303 undo->update_undo_before();
308 undo->update_undo_after(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
311 update_plugin_guis();
312 gui->update(1, 2, 1, 1, 1, 1, 0);
313 cwindow->update(1, 0, 0, 0, 1);
314 cwindow->playback_engine->que->
315 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
318 void MWindow::clear(int clear_handle)
320 double start = edl->local_session->get_selectionstart();
321 double end = edl->local_session->get_selectionend();
322 if( clear_handle || !EQUIV(start, end) ) {
325 edl->session->labels_follow_edits,
326 edl->session->plugins_follow_edits,
327 edl->session->autos_follow_edits);
331 void MWindow::set_automation_mode(int mode)
333 undo->update_undo_before();
334 edl->tracks->set_automation_mode(
335 edl->local_session->get_selectionstart(),
336 edl->local_session->get_selectionend(),
339 char string[BCSTRLEN];
340 sprintf(string,"set %s", FloatAuto::curve_name(mode));
341 undo->update_undo_after(string, LOAD_AUTOMATION);
344 update_plugin_guis();
345 gui->draw_overlays(1);
346 sync_parameters(CHANGE_PARAMS);
347 gui->update_patchbay();
348 cwindow->update(1, 0, 0);
351 void MWindow::clear_automation()
353 undo->update_undo_before();
354 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
355 edl->local_session->get_selectionend());
357 undo->update_undo_after(_("clear keyframes"), LOAD_AUTOMATION);
360 update_plugin_guis();
361 gui->draw_overlays(1);
362 sync_parameters(CHANGE_PARAMS);
363 gui->update_patchbay();
364 cwindow->update(1, 0, 0);
367 int MWindow::clear_default_keyframe()
369 undo->update_undo_before();
370 edl->tracks->clear_default_keyframe();
372 undo->update_undo_after(_("clear default keyframe"), LOAD_AUTOMATION);
375 gui->draw_overlays(1);
376 sync_parameters(CHANGE_PARAMS);
377 gui->update_patchbay();
378 cwindow->update(1, 0, 0);
383 void MWindow::clear_labels()
385 undo->update_undo_before();
386 clear_labels(edl->local_session->get_selectionstart(),
387 edl->local_session->get_selectionend());
388 undo->update_undo_after(_("clear labels"), LOAD_TIMEBAR);
390 gui->update_timebar(1);
391 cwindow->update(0, 0, 0, 0, 1);
395 int MWindow::clear_labels(double start, double end)
397 edl->labels->clear(start, end, 0);
401 void MWindow::concatenate_tracks()
403 undo->update_undo_before();
404 edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits,
405 edl->session->autos_follow_edits);
407 undo->update_undo_after(_("concatenate tracks"), LOAD_EDITS);
410 gui->update(1, 1, 0, 0, 1, 0, 0);
411 cwindow->playback_engine->que->
412 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
418 copy(edl->local_session->get_selectionstart(),
419 edl->local_session->get_selectionend());
422 int MWindow::copy(double start, double end)
424 if( start == end ) return 1;
427 edl->copy(start, end, 0, 0, 0, &file, "", 1);
428 const char *file_string = file.string();
429 long file_length = strlen(file_string);
430 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
431 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
436 int MWindow::copy_automation()
439 double start = edl->local_session->get_selectionstart();
440 double end = edl->local_session->get_selectionend();
441 edl->tracks->copy_automation(start, end, &file, 0, 1);
442 const char *file_string = file.string();
443 long file_length = strlen(file_string);
444 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
445 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
449 int MWindow::copy_default_keyframe()
452 double start = edl->local_session->get_selectionstart();
453 double end = edl->local_session->get_selectionend();
454 edl->tracks->copy_automation(start, end, &file, 1, 0);
455 const char *file_string = file.string();
456 long file_length = strlen(file_string);
457 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
458 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
463 // Uses cropping coordinates in edl session to crop and translate video.
464 // We modify the projector since camera automation depends on the track size.
465 void MWindow::crop_video()
468 undo->update_undo_before();
469 // Clamp EDL crop region
470 if( edl->session->crop_x1 > edl->session->crop_x2 ) {
471 edl->session->crop_x1 ^= edl->session->crop_x2;
472 edl->session->crop_x2 ^= edl->session->crop_x1;
473 edl->session->crop_x1 ^= edl->session->crop_x2;
475 if( edl->session->crop_y1 > edl->session->crop_y2 ) {
476 edl->session->crop_y1 ^= edl->session->crop_y2;
477 edl->session->crop_y2 ^= edl->session->crop_y1;
478 edl->session->crop_y1 ^= edl->session->crop_y2;
481 float old_projector_x = (float)edl->session->output_w / 2;
482 float old_projector_y = (float)edl->session->output_h / 2;
483 float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
484 float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
485 float projector_offset_x = -(new_projector_x - old_projector_x);
486 float projector_offset_y = -(new_projector_y - old_projector_y);
488 edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
490 edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
491 edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
492 edl->session->crop_x1 = 0;
493 edl->session->crop_y1 = 0;
494 edl->session->crop_x2 = edl->session->output_w;
495 edl->session->crop_y2 = edl->session->output_h;
497 // Recalculate aspect ratio
498 if( defaults->get("AUTOASPECT", 0) ) {
499 create_aspect_ratio(edl->session->aspect_w,
500 edl->session->aspect_h,
501 edl->session->output_w,
502 edl->session->output_h);
505 undo->update_undo_after(_("crop"), LOAD_ALL);
508 cwindow->playback_engine->que->
509 send_command(CURRENT_FRAME, CHANGE_ALL, edl, 1);
515 undo->update_undo_before();
517 double start = edl->local_session->get_selectionstart();
518 double end = edl->local_session->get_selectionend();
521 edl->clear(start, end,
522 edl->session->labels_follow_edits,
523 edl->session->plugins_follow_edits,
524 edl->session->autos_follow_edits);
529 undo->update_undo_after(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
532 update_plugin_guis();
533 gui->update(1, 2, 1, 1, 1, 1, 0);
534 cwindow->update(1, 0, 0, 0, 1);
535 cwindow->playback_engine->que->
536 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
539 int MWindow::cut_automation()
541 undo->update_undo_before();
545 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
546 edl->local_session->get_selectionend());
548 undo->update_undo_after(_("cut keyframes"), LOAD_AUTOMATION);
552 update_plugin_guis();
553 gui->draw_overlays(1);
554 sync_parameters(CHANGE_PARAMS);
555 gui->update_patchbay();
556 cwindow->update(1, 0, 0);
560 int MWindow::cut_default_keyframe()
563 undo->update_undo_before();
564 copy_default_keyframe();
565 edl->tracks->clear_default_keyframe();
566 undo->update_undo_after(_("cut default keyframe"), LOAD_AUTOMATION);
569 gui->draw_overlays(1);
570 sync_parameters(CHANGE_PARAMS);
571 gui->update_patchbay();
572 cwindow->update(1, 0, 0);
580 void MWindow::delete_inpoint()
582 edl->local_session->unset_inpoint();
586 void MWindow::delete_outpoint()
588 edl->local_session->unset_outpoint();
593 void MWindow::delete_track()
595 if( edl->tracks->last )
596 delete_track(edl->tracks->last);
599 void MWindow::delete_tracks()
601 undo->update_undo_before();
602 edl->tracks->delete_tracks();
603 undo->update_undo_after(_("delete tracks"), LOAD_ALL);
607 update_plugin_states();
609 gui->update(1, 1, 1, 0, 1, 0, 0);
610 cwindow->playback_engine->que->
611 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
614 void MWindow::delete_track(Track *track)
616 undo->update_undo_before();
617 edl->tracks->delete_track(track);
618 undo->update_undo_after(_("delete track"), LOAD_ALL);
621 update_plugin_states();
623 gui->update(1, 1, 1, 0, 1, 0, 0);
624 cwindow->playback_engine->que->
625 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
630 // Insert data from clipboard
631 void MWindow::insert(double position, FileXML *file,
632 int edit_labels, int edit_plugins, int edit_autos,
635 // For clipboard pasting make the new edl use a separate session
636 // from the master EDL. Then it can be resampled to the master rates.
637 // For splice, overwrite, and dragging need same session to get the assets.
638 EDL *edl = new EDL(parent_edl);
639 ArrayList<EDL*> new_edls;
640 uint32_t load_flags = LOAD_ALL;
643 new_edls.append(edl);
644 edl->create_objects();
649 if( parent_edl ) load_flags &= ~LOAD_SESSION;
650 if( !edl->session->autos_follow_edits ) load_flags &= ~LOAD_AUTOMATION;
651 if( !edl->session->labels_follow_edits ) load_flags &= ~LOAD_TIMEBAR;
653 edl->load_xml(file, load_flags);
656 //printf("MWindow::insert %f\n", edl->local_session->clipboard_length);
660 paste_edls(&new_edls, LOADMODE_PASTE, 0, position,
661 edit_labels, edit_plugins, edit_autos, 0); // overwrite
662 // if( vwindow->edl )
663 // printf("MWindow::insert 5 %f %f\n",
664 // vwindow->edl->local_session->in_point,
665 // vwindow->edl->local_session->out_point);
666 new_edls.remove_all();
667 edl->Garbage::remove_user();
668 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
671 void MWindow::insert_effects_canvas(double start,
674 Track *dest_track = session->track_highlighted;
675 if( !dest_track ) return;
677 undo->update_undo_before();
679 for( int i = 0; i < session->drag_pluginservers->total; i++ ) {
680 PluginServer *plugin = session->drag_pluginservers->values[i];
681 insert_effect(plugin->title, 0, dest_track,
682 i == 0 ? session->pluginset_highlighted : 0,
683 start, length, PLUGIN_STANDALONE);
687 undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
689 sync_parameters(CHANGE_EDL);
690 // GUI updated in TrackCanvas, after current_operations are reset
693 void MWindow::insert_effects_cwindow(Track *dest_track)
695 if( !dest_track ) return;
697 undo->update_undo_before();
700 double length = dest_track->get_length();
702 if( edl->local_session->get_selectionend() >
703 edl->local_session->get_selectionstart() ) {
704 start = edl->local_session->get_selectionstart();
705 length = edl->local_session->get_selectionend() -
706 edl->local_session->get_selectionstart();
709 for( int i = 0; i < session->drag_pluginservers->total; i++ ) {
710 PluginServer *plugin = session->drag_pluginservers->values[i];
711 insert_effect(plugin->title, 0, dest_track, 0,
712 start, length, PLUGIN_STANDALONE);
716 undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
718 sync_parameters(CHANGE_EDL);
719 gui->update(1, 1, 0, 0, 1, 0, 0);
722 void MWindow::insert_effect(char *title,
723 SharedLocation *shared_location,
726 int single_standalone)
728 Track *current = edl->tracks->first;
729 SharedLocation shared_location_local;
730 shared_location_local.copy_from(shared_location);
732 for( ; current; current = NEXT) {
733 if( current->data_type == data_type &&
735 insert_effect(title, &shared_location_local,
736 current, 0, 0, 0, plugin_type);
739 if( plugin_type == PLUGIN_STANDALONE && single_standalone ) {
740 plugin_type = PLUGIN_SHAREDPLUGIN;
741 shared_location_local.module = edl->tracks->number_of(current);
742 shared_location_local.plugin = current->plugin_set.total - 1;
751 void MWindow::insert_effect(char *title,
752 SharedLocation *shared_location,
754 PluginSet *plugin_set,
759 KeyFrame *default_keyframe = 0;
760 PluginServer *server = 0;
761 // Get default keyframe
762 if( plugin_type == PLUGIN_STANDALONE ) {
763 default_keyframe = new KeyFrame;
764 server = new PluginServer(*scan_plugindb(title, track->data_type));
766 server->open_plugin(0, preferences, edl, 0);
767 server->save_data(default_keyframe);
769 // Insert plugin object
770 track->insert_effect(title, shared_location,
771 default_keyframe, plugin_set,
772 start, length, plugin_type);
775 if( plugin_type == PLUGIN_STANDALONE ) {
776 server->close_plugin();
778 delete default_keyframe;
782 int MWindow::modify_edithandles()
784 undo->update_undo_before();
785 edl->modify_edithandles(session->drag_start,
786 session->drag_position,
787 session->drag_handle,
788 edl->session->edit_handle_mode[session->drag_button],
789 edl->session->labels_follow_edits,
790 edl->session->plugins_follow_edits,
791 edl->session->autos_follow_edits);
793 finish_modify_handles();
794 //printf("MWindow::modify_handles 1\n");
798 int MWindow::modify_pluginhandles()
800 undo->update_undo_before();
802 edl->modify_pluginhandles(session->drag_start,
803 session->drag_position,
804 session->drag_handle,
805 edl->session->edit_handle_mode[session->drag_button],
806 edl->session->labels_follow_edits,
807 edl->session->autos_follow_edits,
808 session->trim_edits);
810 finish_modify_handles();
816 // Common to edithandles and plugin handles
817 void MWindow::finish_modify_handles()
819 int edit_mode = edl->session->edit_handle_mode[session->drag_button];
821 if( (session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
822 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT) ) {
823 edl->local_session->set_selectionstart(session->drag_position);
824 edl->local_session->set_selectionend(session->drag_position);
827 if( edit_mode != MOVE_NO_EDITS ) {
828 edl->local_session->set_selectionstart(session->drag_start);
829 edl->local_session->set_selectionend(session->drag_start);
832 if( edl->local_session->get_selectionstart(1) < 0 ) {
833 edl->local_session->set_selectionstart(0);
834 edl->local_session->set_selectionend(0);
836 undo->update_undo_after(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
840 sync_parameters(CHANGE_EDL);
841 update_plugin_guis();
842 gui->update(1, 2, 1, 1, 1, 1, 0);
843 cwindow->update(1, 0, 0, 0, 1);
846 void MWindow::match_output_size(Track *track)
848 undo->update_undo_before();
849 track->track_w = edl->session->output_w;
850 track->track_h = edl->session->output_h;
852 undo->update_undo_after(_("match output size"), LOAD_ALL);
855 sync_parameters(CHANGE_EDL);
859 void MWindow::move_edits(ArrayList<Edit*> *edits,
864 undo->update_undo_before();
866 edl->tracks->move_edits(edits,
869 edl->session->labels_follow_edits,
870 edl->session->plugins_follow_edits,
871 edl->session->autos_follow_edits,
875 undo->update_undo_after(_("move edit"), LOAD_ALL);
878 cwindow->playback_engine->que->
879 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
881 update_plugin_guis();
882 gui->update(1, 1, // 1 for incremental drawing. 2 for full refresh
886 void MWindow::move_effect(Plugin *plugin, Track *track, int64_t position)
888 undo->update_undo_before();
889 edl->tracks->move_effect(plugin, track, position);
891 undo->update_undo_after(_("paste effect"), LOAD_ALL);
894 cwindow->playback_engine->que->
895 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
896 update_plugin_guis();
897 gui->update(1, 1, // 1 for incremental drawing. 2 for full refresh
901 void MWindow::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t position)
903 undo->update_undo_before();
904 edl->tracks->move_effect(plugin, plugin_set, position);
906 undo->update_undo_after(_("move effect"), LOAD_ALL);
909 cwindow->playback_engine->que->
910 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
911 update_plugin_guis();
912 gui->update(1, 1, // 1 for incremental drawing. 2 for full refresh
916 void MWindow::move_plugins_up(PluginSet *plugin_set)
919 undo->update_undo_before();
920 plugin_set->track->move_plugins_up(plugin_set);
923 undo->update_undo_after(_("move effect up"), LOAD_ALL);
925 gui->update(1, 1, // 1 for incremental drawing. 2 for full refresh
927 sync_parameters(CHANGE_EDL);
930 void MWindow::move_plugins_down(PluginSet *plugin_set)
932 undo->update_undo_before();
934 plugin_set->track->move_plugins_down(plugin_set);
937 undo->update_undo_after(_("move effect down"), LOAD_ALL);
939 gui->update(1, 1, // 1 for incremental drawing. 2 for full refresh
941 sync_parameters(CHANGE_EDL);
944 void MWindow::move_track_down(Track *track)
946 undo->update_undo_before();
947 edl->tracks->move_track_down(track);
949 undo->update_undo_after(_("move track down"), LOAD_ALL);
952 gui->update(1, 1, 0, 0, 1, 0, 0);
953 sync_parameters(CHANGE_EDL);
957 void MWindow::move_tracks_down()
959 undo->update_undo_before();
960 edl->tracks->move_tracks_down();
962 undo->update_undo_after(_("move tracks down"), LOAD_ALL);
965 gui->update(1, 1, 0, 0, 1, 0, 0);
966 sync_parameters(CHANGE_EDL);
970 void MWindow::move_track_up(Track *track)
972 undo->update_undo_before();
973 edl->tracks->move_track_up(track);
975 undo->update_undo_after(_("move track up"), LOAD_ALL);
977 gui->update(1, 1, 0, 0, 1, 0, 0);
978 sync_parameters(CHANGE_EDL);
982 void MWindow::move_tracks_up()
984 undo->update_undo_before();
985 edl->tracks->move_tracks_up();
987 undo->update_undo_after(_("move tracks up"), LOAD_ALL);
989 gui->update(1, 1, 0, 0, 1, 0, 0);
990 sync_parameters(CHANGE_EDL);
994 void MWindow::mute_selection()
996 double start = edl->local_session->get_selectionstart();
997 double end = edl->local_session->get_selectionend();
999 undo->update_undo_before();
1000 edl->clear(start, end, 0,
1001 edl->session->plugins_follow_edits,
1002 edl->session->autos_follow_edits);
1003 edl->local_session->set_selectionend(end);
1004 edl->local_session->set_selectionstart(start);
1005 edl->paste_silence(start, end, 0,
1006 edl->session->plugins_follow_edits,
1007 edl->session->autos_follow_edits);
1009 undo->update_undo_after(_("mute"), LOAD_EDITS);
1012 update_plugin_guis();
1013 gui->update(1, 2, 1, 1, 1, 1, 0);
1014 cwindow->playback_engine->que->
1015 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
1020 void MWindow::overwrite(EDL *source)
1024 double src_start = source->local_session->get_selectionstart();
1025 double overwrite_len = source->local_session->get_selectionend() - src_start;
1026 double dst_start = edl->local_session->get_selectionstart();
1027 double dst_len = edl->local_session->get_selectionend() - dst_start;
1029 undo->update_undo_before();
1030 if( !EQUIV(dst_len, 0) && (dst_len < overwrite_len) ) {
1031 // in/out points or selection present and shorter than overwrite range
1032 // shorten the copy range
1033 overwrite_len = dst_len;
1036 source->copy(src_start, src_start + overwrite_len,
1037 1, 0, 0, &file, "", 1);
1039 // HACK around paste_edl get_start/endselection on its own
1040 // so we need to clear only when not using both io points
1041 // FIXME: need to write simple overwrite_edl to be used for overwrite function
1042 if( edl->local_session->get_inpoint() < 0 ||
1043 edl->local_session->get_outpoint() < 0 )
1044 edl->clear(dst_start, dst_start + overwrite_len, 0, 0, 0);
1046 paste(dst_start, dst_start + overwrite_len,
1049 edl->local_session->set_selectionstart(dst_start + overwrite_len);
1050 edl->local_session->set_selectionend(dst_start + overwrite_len);
1053 undo->update_undo_after(_("overwrite"), LOAD_EDITS);
1056 update_plugin_guis();
1057 gui->update(1, 1, 1, 1, 0, 1, 0);
1058 sync_parameters(CHANGE_EDL);
1061 // For splice and overwrite
1062 int MWindow::paste(double start,
1071 // Want to insert with assets shared with the master EDL.
1073 edit_labels, edit_plugins, edit_autos,
1079 // For editing using insertion point
1080 void MWindow::paste()
1082 double start = edl->local_session->get_selectionstart();
1083 //double end = edl->local_session->get_selectionend();
1084 int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
1087 char *string = new char[len];
1088 undo->update_undo_before();
1089 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
1091 file.read_from_string(string);
1094 insert(start, &file,
1095 edl->session->labels_follow_edits,
1096 edl->session->plugins_follow_edits,
1097 edl->session->autos_follow_edits,
1105 undo->update_undo_after(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1107 update_plugin_guis();
1108 gui->update(1, 2, 1, 1, 0, 1, 0);
1109 awindow->gui->async_update_assets();
1110 sync_parameters(CHANGE_EDL);
1115 int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
1118 undo->update_undo_before();
1120 if( session->drag_assets->total ) {
1121 load_assets(session->drag_assets,
1122 position, LOADMODE_PASTE, dest_track, 0,
1123 edl->session->labels_follow_edits,
1124 edl->session->plugins_follow_edits,
1125 edl->session->autos_follow_edits,
1130 if( session->drag_clips->total ) {
1131 paste_edls(session->drag_clips,
1132 LOADMODE_PASTE, dest_track, position,
1133 edl->session->labels_follow_edits,
1134 edl->session->plugins_follow_edits,
1135 edl->session->autos_follow_edits,
1142 undo->update_undo_after(_("paste assets"), LOAD_EDITS);
1144 gui->update(1, 2, 1, 0, 0, 1, 0);
1145 sync_parameters(CHANGE_EDL);
1149 void MWindow::load_assets(ArrayList<Indexable*> *new_assets,
1150 double position, int load_mode, Track *first_track, RecordLabels *labels,
1151 int edit_labels, int edit_plugins, int edit_autos, int overwrite)
1153 if( load_mode == LOADMODE_RESOURCESONLY )
1154 load_mode = LOADMODE_ASSETSONLY;
1155 const int debug = 0;
1156 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1157 if( position < 0 ) position = edl->local_session->get_selectionstart();
1159 ArrayList<EDL*> new_edls;
1160 for( int i = 0; i < new_assets->total; i++ ) {
1161 Indexable *indexable = new_assets->get(i);
1162 if( indexable->is_asset ) {
1163 remove_asset_from_caches((Asset*)indexable);
1165 EDL *new_edl = new EDL;
1166 new_edl->create_objects();
1167 new_edl->copy_session(edl);
1168 new_edls.append(new_edl);
1171 if( indexable->is_asset ) {
1172 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1173 if( debug ) ((Asset*)indexable)->dump();
1174 asset_to_edl(new_edl, (Asset*)indexable);
1177 edl_to_nested(new_edl, (EDL*)indexable);
1178 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1182 for( RecordLabel *label = labels->first; label; label = label->next ) {
1183 new_edl->labels->toggle_label(label->position, label->position);
1187 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1189 paste_edls(&new_edls, load_mode, first_track, position,
1190 edit_labels, edit_plugins, edit_autos, overwrite);
1191 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1194 for( int i = 0; i < new_edls.size(); i++ )
1195 new_edls.get(i)->Garbage::remove_user();
1197 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
1200 int MWindow::paste_automation()
1202 int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
1205 undo->update_undo_before();
1206 char *string = new char[len];
1207 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
1209 file.read_from_string(string);
1211 double start = edl->local_session->get_selectionstart();
1212 double end = edl->local_session->get_selectionend();
1213 edl->tracks->clear_automation(start, end);
1214 edl->tracks->paste_automation(start, &file, 0, 1,
1215 edl->session->typeless_keyframes);
1217 undo->update_undo_after(_("paste keyframes"), LOAD_AUTOMATION);
1221 update_plugin_guis();
1222 gui->draw_overlays(1);
1223 sync_parameters(CHANGE_PARAMS);
1224 gui->update_patchbay();
1225 cwindow->update(1, 0, 0);
1231 int MWindow::paste_default_keyframe()
1233 int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
1236 undo->update_undo_before();
1237 char *string = new char[len];
1238 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
1240 file.read_from_string(string);
1241 double start = edl->local_session->get_selectionstart();
1242 edl->tracks->paste_automation(start, &file, 1, 0,
1243 edl->session->typeless_keyframes);
1244 // edl->tracks->paste_default_keyframe(&file);
1245 undo->update_undo_after(_("paste default keyframe"), LOAD_AUTOMATION);
1248 update_plugin_guis();
1249 gui->draw_overlays(1);
1250 sync_parameters(CHANGE_PARAMS);
1251 gui->update_patchbay();
1252 cwindow->update(1, 0, 0);
1261 // Insert edls with project deletion and index file generation.
1262 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
1263 Track *first_track, double current_position,
1264 int edit_labels, int edit_plugins, int edit_autos,
1268 ArrayList<Track*> destination_tracks;
1269 int need_new_tracks = 0;
1272 if( !new_edls->total ) return 0;
1275 // double original_length = edl->tracks->total_playable_length();
1276 // double original_preview_end = edl->local_session->preview_end;
1279 // Delete current project
1280 if( load_mode == LOADMODE_REPLACE ||
1281 load_mode == LOADMODE_REPLACE_CONCATENATE ) {
1283 edl->save_defaults(defaults);
1285 edl->Garbage::remove_user();
1287 edl->create_objects();
1288 edl->copy_session(new_edls->values[0]);
1289 gui->mainmenu->update_toggles(0);
1290 gui->unlock_window();
1291 gwindow->gui->update_toggles(1);
1292 gui->lock_window("MWindow::paste_edls");
1294 // Insert labels for certain modes constitutively
1298 // Force reset of preview
1299 // original_length = 0;
1300 // original_preview_end = -1;
1306 // Create new tracks in master EDL
1307 if( load_mode == LOADMODE_REPLACE ||
1308 load_mode == LOADMODE_REPLACE_CONCATENATE ||
1309 load_mode == LOADMODE_NEW_TRACKS ) {
1311 need_new_tracks = 1;
1312 for( int i = 0; i < new_edls->total; i++ ) {
1313 EDL *new_edl = new_edls->values[i];
1314 for( Track *current = new_edl->tracks->first;
1317 if( current->data_type == TRACK_VIDEO ) {
1318 edl->tracks->add_video_track(0, 0);
1319 if( current->draw ) edl->tracks->last->draw = 1;
1320 destination_tracks.append(edl->tracks->last);
1323 if( current->data_type == TRACK_AUDIO ) {
1324 edl->tracks->add_audio_track(0, 0);
1325 destination_tracks.append(edl->tracks->last);
1328 if( current->data_type == TRACK_SUBTITLE ) {
1329 edl->tracks->add_subttl_track(0, 0);
1330 destination_tracks.append(edl->tracks->last);
1332 edl->session->highlighted_track = edl->tracks->total() - 1;
1335 // Base track count on first EDL only for concatenation
1336 if( load_mode == LOADMODE_REPLACE_CONCATENATE ) break;
1341 // Recycle existing tracks of master EDL
1342 if( load_mode == LOADMODE_CONCATENATE ||
1343 load_mode == LOADMODE_PASTE ||
1344 load_mode == LOADMODE_NESTED ) {
1347 // The point of this is to shift forward labels after the selection so they can
1348 // then be shifted back to their original locations without recursively
1349 // shifting back every paste.
1350 if( (load_mode == LOADMODE_PASTE || load_mode == LOADMODE_NESTED) &&
1351 edl->session->labels_follow_edits )
1352 edl->labels->clear(edl->local_session->get_selectionstart(),
1353 edl->local_session->get_selectionend(),
1356 Track *current = first_track ? first_track : edl->tracks->first;
1357 for( ; current; current = NEXT) {
1358 if( current->record ) {
1359 destination_tracks.append(current);
1366 int destination_track = 0;
1367 double *paste_position = new double[destination_tracks.total];
1369 // Iterate through the edls
1370 for( int i = 0; i < new_edls->total; i++ ) {
1372 EDL *new_edl = new_edls->values[i];
1373 double edl_length = new_edl->local_session->clipboard_length ?
1374 new_edl->local_session->clipboard_length :
1375 new_edl->tracks->total_length();
1376 // printf("MWindow::paste_edls 2 %f %f\n",
1377 // new_edl->local_session->clipboard_length,
1378 // new_edl->tracks->total_length());
1382 // Convert EDL to master rates
1383 new_edl->resample(new_edl->session->sample_rate,
1384 edl->session->sample_rate,
1386 new_edl->resample(new_edl->session->frame_rate,
1387 edl->session->frame_rate,
1390 // Add assets and prepare index files
1391 for( Asset *new_asset = new_edl->assets->first;
1393 new_asset = new_asset->next ) {
1394 mainindexes->add_next_asset(0, new_asset);
1396 // Capture index file status from mainindex test
1397 edl->update_assets(new_edl);
1399 // Get starting point of insertion. Need this to paste labels.
1400 switch( load_mode ) {
1401 case LOADMODE_REPLACE:
1402 case LOADMODE_NEW_TRACKS:
1403 current_position = 0;
1406 case LOADMODE_CONCATENATE:
1407 case LOADMODE_REPLACE_CONCATENATE:
1408 destination_track = 0;
1409 if( destination_tracks.total )
1410 current_position = destination_tracks.values[0]->get_length();
1412 current_position = 0;
1415 case LOADMODE_PASTE:
1416 case LOADMODE_NESTED:
1417 destination_track = 0;
1419 for( int j = 0; j < destination_tracks.total; j++ ) {
1420 paste_position[j] = (current_position >= 0) ?
1422 edl->local_session->get_selectionstart();
1427 case LOADMODE_RESOURCESONLY:
1428 edl->add_clip(new_edl);
1433 if( load_mode != LOADMODE_RESOURCESONLY &&
1434 load_mode != LOADMODE_ASSETSONLY ) {
1436 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1437 if( load_mode == LOADMODE_PASTE ||
1438 load_mode == LOADMODE_NESTED )
1439 edl->labels->insert_labels(new_edl->labels,
1440 destination_tracks.total ? paste_position[0] : 0.0,
1444 edl->labels->insert_labels(new_edl->labels,
1450 for( Track *new_track = new_edl->tracks->first;
1452 new_track = new_track->next ) {
1453 // Get destination track of same type as new_track
1455 k < destination_tracks.total &&
1456 destination_tracks.values[destination_track]->data_type != new_track->data_type;
1457 k++, destination_track++ ) {
1458 if( destination_track >= destination_tracks.total - 1 )
1459 destination_track = 0;
1462 // Insert data into destination track
1463 if( destination_track < destination_tracks.total &&
1464 destination_tracks.values[destination_track]->data_type == new_track->data_type ) {
1465 Track *track = destination_tracks.values[destination_track];
1467 // Replace default keyframes if first EDL and new tracks were created.
1468 // This means data copied from one track and pasted to another won't retain
1469 // the camera position unless it's a keyframe. If it did, previous data in the
1470 // track might get unknowingly corrupted. Ideally we would detect when differing
1471 // default keyframes existed and create discrete keyframes for both.
1472 int replace_default = (i == 0) && need_new_tracks;
1474 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1475 // Insert new track at current position
1476 switch( load_mode ) {
1477 case LOADMODE_REPLACE_CONCATENATE:
1478 case LOADMODE_CONCATENATE:
1479 current_position = track->get_length();
1482 case LOADMODE_PASTE:
1483 case LOADMODE_NESTED:
1484 current_position = paste_position[destination_track];
1485 paste_position[destination_track] += new_track->get_length();
1489 track->clear(current_position,
1490 current_position + new_track->get_length(),
1492 edit_labels, edit_plugins, edit_autos,
1497 track->insert_track(new_track, current_position, replace_default,
1498 edit_plugins, edit_autos, edl_length);
1502 // Get next destination track
1503 destination_track++;
1504 if( destination_track >= destination_tracks.total )
1505 destination_track = 0;
1509 if( load_mode == LOADMODE_PASTE ||
1510 load_mode == LOADMODE_NESTED )
1511 current_position += edl_length;
1515 // Move loading of clips and vwindow to the end - this fixes some
1516 // strange issue, for index not being shown
1517 // Assume any paste operation from the same EDL won't contain any clips.
1518 // If it did it would duplicate every clip here.
1519 for( int i = 0; i < new_edls->total; i++ ) {
1520 EDL *new_edl = new_edls->values[i];
1522 for( int j = 0; j < new_edl->clips.total; j++ ) {
1523 edl->add_clip(new_edl->clips.values[j]);
1526 if( new_edl->total_vwindow_edls() ) {
1527 // if( edl->vwindow_edl )
1528 // edl->vwindow_edl->Garbage::remove_user();
1529 // edl->vwindow_edl = new EDL(edl);
1530 // edl->vwindow_edl->create_objects();
1531 // edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1533 for( int j = 0; j < new_edl->total_vwindow_edls(); j++ ) {
1534 EDL *vwindow_edl = new EDL(edl);
1535 vwindow_edl->create_objects();
1536 vwindow_edl->copy_all(new_edl->get_vwindow_edl(j));
1537 edl->append_vwindow_edl(vwindow_edl, 0);
1542 if( paste_position ) delete [] paste_position;
1544 // This is already done in load_filenames and everything else that uses paste_edls
1545 // update_project(load_mode);
1547 // Fix preview range
1548 // if( EQUIV(original_length, original_preview_end) )
1550 // edl->local_session->preview_end = edl->tracks->total_playable_length();
1553 // Start examining next batch of index files
1554 mainindexes->start_build();
1556 // Don't save a backup after loading since the loaded file is on disk already.
1561 void MWindow::paste_silence()
1563 double start = edl->local_session->get_selectionstart();
1564 double end = edl->local_session->get_selectionend();
1565 undo->update_undo_before();
1566 edl->paste_silence(start, end,
1567 edl->session->labels_follow_edits,
1568 edl->session->plugins_follow_edits,
1569 edl->session->autos_follow_edits);
1572 undo->update_undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1574 update_plugin_guis();
1576 gui->update(1, 2, 1, 1, 1, 1, 0);
1577 cwindow->update(1, 0, 0, 0, 1);
1578 cwindow->playback_engine->que->
1579 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
1582 void MWindow::detach_transition(Transition *transition)
1584 undo->update_undo_before();
1585 hide_plugin(transition, 1);
1586 int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
1587 transition->edit->detach_transition();
1589 undo->update_undo_after(_("detach transition"), LOAD_ALL);
1591 if( is_video ) restart_brender();
1592 gui->update(0, 1, 0, 0, 0, 0, 0);
1593 sync_parameters(CHANGE_EDL);
1596 void MWindow::detach_transitions()
1598 gui->lock_window("MWindow::detach_transitions 1");
1600 undo->update_undo_before();
1601 double start = edl->local_session->get_selectionstart();
1602 double end = edl->local_session->get_selectionend();
1603 edl->tracks->clear_transitions(start, end);
1606 undo->update_undo_after(_("detach transitions"), LOAD_EDITS);
1608 sync_parameters(CHANGE_EDL);
1609 gui->update(0, 1, 0, 0, 0, 0, 0);
1610 gui->unlock_window();
1613 void MWindow::paste_transition()
1615 // Only the first transition gets dropped.
1616 PluginServer *server = session->drag_pluginservers->values[0];
1618 undo->update_undo_before();
1620 strcpy(edl->session->default_atransition, server->title);
1622 strcpy(edl->session->default_vtransition, server->title);
1624 edl->tracks->paste_transition(server, session->edit_highlighted);
1626 undo->update_undo_after(_("transition"), LOAD_EDITS);
1628 if( server->video ) restart_brender();
1629 sync_parameters(CHANGE_ALL);
1632 void MWindow::paste_transitions(int track_type, char *title)
1634 gui->lock_window("MWindow::detach_transitions 1");
1636 undo->update_undo_before();
1637 double start = edl->local_session->get_selectionstart();
1638 double end = edl->local_session->get_selectionend();
1639 edl->tracks->paste_transitions(start, end, track_type, title);
1642 undo->update_undo_after(_("attach transitions"), LOAD_EDITS);
1644 sync_parameters(CHANGE_EDL);
1645 gui->update(0, 1, 0, 0, 0, 0, 0);
1646 gui->unlock_window();
1649 void MWindow::paste_transition_cwindow(Track *dest_track)
1651 PluginServer *server = session->drag_pluginservers->values[0];
1652 undo->update_undo_before();
1653 edl->tracks->paste_video_transition(server, 1);
1655 undo->update_undo_after(_("transition"), LOAD_EDITS);
1657 gui->update(0, 1, 0, 0, 0, 0, 0);
1658 sync_parameters(CHANGE_ALL);
1661 void MWindow::paste_audio_transition()
1663 PluginServer *server = scan_plugindb(edl->session->default_atransition,
1666 char string[BCTEXTLEN];
1667 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1668 gui->show_message(string);
1672 undo->update_undo_before();
1673 edl->tracks->paste_audio_transition(server);
1675 undo->update_undo_after(_("transition"), LOAD_EDITS);
1677 sync_parameters(CHANGE_EDL);
1678 gui->update(0, 1, 0, 0, 0, 0, 0);
1681 void MWindow::paste_video_transition()
1683 PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1686 char string[BCTEXTLEN];
1687 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1688 gui->show_message(string);
1692 undo->update_undo_before();
1694 edl->tracks->paste_video_transition(server);
1696 undo->update_undo_after(_("transition"), LOAD_EDITS);
1698 sync_parameters(CHANGE_EDL);
1700 gui->update(0, 1, 0, 0, 0, 0, 0);
1703 void MWindow::shuffle_edits()
1705 gui->lock_window("MWindow::shuffle_edits 1");
1707 undo->update_undo_before();
1708 double start = edl->local_session->get_selectionstart();
1709 double end = edl->local_session->get_selectionend();
1711 edl->tracks->shuffle_edits(start, end);
1714 undo->update_undo_after(_("shuffle edits"), LOAD_EDITS | LOAD_TIMEBAR);
1716 sync_parameters(CHANGE_EDL);
1718 gui->update(0, 1, 1, 0, 0, 0, 0);
1719 gui->unlock_window();
1722 void MWindow::reverse_edits()
1724 gui->lock_window("MWindow::reverse_edits 1");
1726 undo->update_undo_before();
1727 double start = edl->local_session->get_selectionstart();
1728 double end = edl->local_session->get_selectionend();
1730 edl->tracks->reverse_edits(start, end);
1733 undo->update_undo_after(_("reverse edits"), LOAD_EDITS | LOAD_TIMEBAR);
1735 sync_parameters(CHANGE_EDL);
1737 gui->update(0, 1, 1, 0, 0, 0, 0);
1738 gui->unlock_window();
1741 void MWindow::align_edits()
1743 gui->lock_window("MWindow::align_edits 1");
1745 undo->update_undo_before();
1746 double start = edl->local_session->get_selectionstart();
1747 double end = edl->local_session->get_selectionend();
1749 edl->tracks->align_edits(start, end);
1752 undo->update_undo_after(_("align edits"), LOAD_EDITS | LOAD_TIMEBAR);
1754 sync_parameters(CHANGE_EDL);
1756 gui->update(0, 1, 1, 0, 0, 0, 0);
1757 gui->unlock_window();
1760 void MWindow::set_edit_length(double length)
1762 gui->lock_window("MWindow::detach_transitions 1");
1764 undo->update_undo_before();
1765 double start = edl->local_session->get_selectionstart();
1766 double end = edl->local_session->get_selectionend();
1768 edl->tracks->set_edit_length(start, end, length);
1771 undo->update_undo_after(_("edit length"), LOAD_EDITS | LOAD_TIMEBAR);
1773 sync_parameters(CHANGE_EDL);
1775 gui->update(0, 1, 1, 0, 0, 0, 0);
1776 gui->unlock_window();
1780 void MWindow::set_transition_length(Transition *transition, double length)
1782 gui->lock_window("MWindow::detach_transitions 1");
1784 undo->update_undo_before();
1785 //double start = edl->local_session->get_selectionstart();
1786 //double end = edl->local_session->get_selectionend();
1788 edl->tracks->set_transition_length(transition, length);
1791 undo->update_undo_after(_("transition length"), LOAD_EDITS);
1793 edl->session->default_transition_length = length;
1794 sync_parameters(CHANGE_PARAMS);
1795 gui->update(0, 1, 0, 0, 0, 0, 0);
1796 gui->unlock_window();
1799 void MWindow::set_transition_length(double length)
1801 gui->lock_window("MWindow::detach_transitions 1");
1803 undo->update_undo_before();
1804 double start = edl->local_session->get_selectionstart();
1805 double end = edl->local_session->get_selectionend();
1807 edl->tracks->set_transition_length(start, end, length);
1810 undo->update_undo_after(_("transition length"), LOAD_EDITS);
1812 edl->session->default_transition_length = length;
1813 sync_parameters(CHANGE_PARAMS);
1815 gui->update(0, 1, 0, 0, 0, 0, 0);
1816 gui->unlock_window();
1820 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1823 calling_window_gui->unlock_window();
1825 cwindow->playback_engine->que->
1826 send_command(STOP, CHANGE_NONE, 0, 0);
1827 cwindow->playback_engine->interrupt_playback(0);
1829 for( int i = 0; i < vwindows.size(); i++ ) {
1830 if( vwindows.get(i)->is_running() ) {
1831 vwindows.get(i)->playback_engine->que->
1832 send_command(STOP, CHANGE_NONE, 0, 0);
1833 vwindows.get(i)->playback_engine->interrupt_playback(0);
1837 cwindow->gui->lock_window("MWindow::redo_entry");
1838 for( int i = 0; i < vwindows.size(); i++ ) {
1839 if( vwindows.get(i)->is_running() ) {
1840 if( calling_window_gui != vwindows.get(i)->gui ) {
1841 vwindows.get(i)->gui->lock_window("MWindow::redo_entry 2");
1850 update_plugin_states();
1851 update_plugin_guis();
1853 gui->update(1, 2, 1, 1, 1, 1, 1);
1854 cwindow->update(1, 1, 1, 1, 1);
1856 if( calling_window_gui != cwindow->gui )
1857 cwindow->gui->unlock_window();
1858 if( calling_window_gui != gui )
1859 gui->unlock_window();
1862 for( int i = 0; i < vwindows.size(); i++ ) {
1863 if( vwindows.get(i)->is_running() ) {
1864 if( calling_window_gui != vwindows.get(i)->gui ) {
1865 vwindows.get(i)->gui->unlock_window();
1870 cwindow->playback_engine->que->
1871 send_command(CURRENT_FRAME, CHANGE_ALL, edl, 1);
1875 void MWindow::resize_track(Track *track, int w, int h)
1877 undo->update_undo_before();
1878 // We have to move all maskpoints so they do not move in relation to image areas
1879 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1880 (w - track->track_w) / 2,
1881 (h - track->track_h) / 2);
1884 undo->update_undo_after(_("resize track"), LOAD_ALL);
1888 sync_parameters(CHANGE_EDL);
1892 void MWindow::set_inpoint(int is_mwindow)
1894 undo->update_undo_before();
1895 edl->set_inpoint(edl->local_session->get_selectionstart(1));
1897 undo->update_undo_after(_("in point"), LOAD_TIMEBAR);
1900 gui->lock_window("MWindow::set_inpoint 1");
1902 gui->update_timebar(1);
1904 gui->unlock_window();
1908 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1910 cwindow->gui->timebar->update(1);
1912 cwindow->gui->unlock_window();
1916 void MWindow::set_outpoint(int is_mwindow)
1918 undo->update_undo_before();
1919 edl->set_outpoint(edl->local_session->get_selectionend(1));
1921 undo->update_undo_after(_("out point"), LOAD_TIMEBAR);
1924 gui->lock_window("MWindow::set_outpoint 1");
1926 gui->update_timebar(1);
1928 gui->unlock_window();
1932 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1934 cwindow->gui->timebar->update(1);
1936 cwindow->gui->unlock_window();
1940 void MWindow::splice(EDL *source)
1944 undo->update_undo_before();
1945 double source_start = source->local_session->get_selectionstart();
1946 double source_end = source->local_session->get_selectionend();
1947 source->copy(source_start, source_end, 1, 0, 0, &file, "", 1);
1949 double start = edl->local_session->get_selectionstart();
1950 //double end = edl->local_session->get_selectionend();
1952 paste(start, start, &file,
1953 edl->session->labels_follow_edits,
1954 edl->session->plugins_follow_edits,
1955 edl->session->autos_follow_edits);
1957 // Position at end of clip
1958 edl->local_session->set_selectionstart(start + source_end - source_start);
1959 edl->local_session->set_selectionend(start + source_end - source_start);
1962 undo->update_undo_after(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1963 update_plugin_guis();
1965 gui->update(1, 1, 1, 1, 0, 1, 0);
1966 sync_parameters(CHANGE_EDL);
1969 void MWindow::save_clip(EDL *new_edl, const char *txt)
1971 new_edl->local_session->set_selectionstart(0);
1972 new_edl->local_session->set_selectionend(0);
1973 sprintf(new_edl->local_session->clip_title, _("Clip %d"),
1974 session->clip_number++);
1975 char duration[BCTEXTLEN];
1976 Units::totext(duration, new_edl->tracks->total_length(),
1977 new_edl->session->time_format,
1978 new_edl->session->sample_rate,
1979 new_edl->session->frame_rate,
1980 new_edl->session->frames_per_foot);
1982 Track *track = new_edl->tracks->first;
1983 const char *path = edl->path;
1984 for( ; (!path || !*path) && track; track=track->next ) {
1985 if( !track->record ) continue;
1986 Edit *edit = track->edits->first;
1987 if( !edit ) continue;
1988 Indexable *indexable = edit->get_source();
1989 if( !indexable ) continue;
1990 path = indexable->path;
1993 time_t now; time(&now);
1994 struct tm *tm = localtime(&now);
1995 char *cp = new_edl->local_session->clip_notes;
1996 int n, sz = sizeof(new_edl->local_session->clip_notes)-1;
1998 n = snprintf(cp, sz, "%s", txt);
2001 n = snprintf(cp, sz,
2002 "%02d/%02d/%02d %02d:%02d:%02d, +%s\n",
2003 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
2004 tm->tm_hour, tm->tm_min, tm->tm_sec, duration);
2006 if( path && *path ) {
2008 char title[BCTEXTLEN];
2009 fs.extract_name(title, path);
2010 n = snprintf(cp, sz, "%s", title);
2015 edl->update_assets(new_edl);
2017 gui->get_abs_cursor_xy(cur_x, cur_y, 0);
2018 gui->unlock_window();
2020 awindow->clip_edit->create_clip(new_edl, cur_x, cur_y);
2022 gui->lock_window("MWindow::save_clip");
2026 void MWindow::to_clip(EDL *edl, const char *txt)
2031 gui->lock_window("MWindow::to_clip 1");
2032 start = edl->local_session->get_selectionstart();
2033 end = edl->local_session->get_selectionend();
2035 if( EQUIV(end, start) ) {
2037 end = edl->tracks->total_length();
2040 // Don't copy all since we don't want the clips twice.
2041 edl->copy(start, end, 0, 0, 0, &file, "", 1);
2043 EDL *new_edl = new EDL(edl);
2044 new_edl->create_objects();
2045 new_edl->load_xml(&file, LOAD_ALL);
2046 save_clip(new_edl, txt);
2047 gui->unlock_window();
2050 int MWindow::toggle_label(int is_mwindow)
2052 double position1, position2;
2053 undo->update_undo_before();
2055 if( cwindow->playback_engine->is_playing_back ) {
2056 position1 = position2 =
2057 cwindow->playback_engine->get_tracking_position();
2060 position1 = edl->local_session->get_selectionstart(1);
2061 position2 = edl->local_session->get_selectionend(1);
2064 position1 = edl->align_to_frame(position1, 0);
2065 position2 = edl->align_to_frame(position2, 0);
2067 //printf("MWindow::toggle_label 1\n");
2069 edl->labels->toggle_label(position1, position2);
2073 gui->lock_window("MWindow::toggle_label 1");
2075 gui->update_timebar(0);
2076 gui->activate_timeline();
2079 gui->unlock_window();
2083 cwindow->gui->lock_window("MWindow::toggle_label 2");
2085 cwindow->gui->timebar->update(1);
2087 cwindow->gui->unlock_window();
2090 awindow->gui->async_update_assets();
2092 undo->update_undo_after(_("label"), LOAD_TIMEBAR);
2096 void MWindow::trim_selection()
2098 undo->update_undo_before();
2101 edl->trim_selection(edl->local_session->get_selectionstart(),
2102 edl->local_session->get_selectionend(),
2103 edl->session->labels_follow_edits,
2104 edl->session->plugins_follow_edits,
2105 edl->session->autos_follow_edits);
2108 undo->update_undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
2109 update_plugin_guis();
2110 gui->update(1, 2, 1, 1, 1, 1, 0);
2111 cwindow->update(1, 0, 0, 0, 1);
2113 cwindow->playback_engine->que->
2114 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
2118 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2120 calling_window_gui->unlock_window();
2122 cwindow->playback_engine->que->
2123 send_command(STOP, CHANGE_NONE, 0, 0);
2124 cwindow->playback_engine->interrupt_playback(0);
2126 //printf("MWindow::undo_entry %d %d\n", __LINE__, vwindows.size());
2127 for( int i = 0; i < vwindows.size(); i++ ) {
2128 if( vwindows.get(i)->is_running() ) {
2129 vwindows.get(i)->playback_engine->que->
2130 send_command(STOP, CHANGE_NONE, 0, 0);
2131 vwindows.get(i)->playback_engine->interrupt_playback(0);
2135 cwindow->gui->lock_window("MWindow::undo_entry 1");
2136 for( int i = 0; i < vwindows.size(); i++ ) {
2137 if( vwindows.get(i)->is_running() ) {
2138 if( calling_window_gui != vwindows.get(i)->gui ) {
2139 vwindows.get(i)->gui->lock_window("MWindow::undo_entry 4");
2143 gui->lock_window("MWindow::undo_entry 2");
2149 update_plugin_states();
2150 update_plugin_guis();
2152 gui->update(1, 2, 1, 1, 1, 1, 1);
2153 gui->unlock_window();
2154 cwindow->update(1, 1, 1, 1, 1);
2155 cwindow->gui->unlock_window();
2157 for( int i = 0; i < vwindows.size(); i++ ) {
2158 if( vwindows.get(i)->is_running() ) {
2159 if( calling_window_gui != vwindows.get(i)->gui ) {
2160 vwindows.get(i)->gui->unlock_window();
2165 if( calling_window_gui != gui )
2166 gui->unlock_window();
2168 awindow->gui->async_update_assets();
2170 cwindow->playback_engine->que->
2171 send_command(CURRENT_FRAME, CHANGE_ALL, edl, 1);
2172 calling_window_gui->lock_window("MWindow::undo_entry 4");
2176 void MWindow::new_folder(const char *new_folder)
2178 undo->update_undo_before();
2179 edl->new_folder(new_folder);
2180 undo->update_undo_after(_("new folder"), LOAD_ALL);
2181 awindow->gui->async_update_assets();
2184 void MWindow::delete_folder(char *folder)
2186 // undo->update_undo_after(_("delete folder"), LOAD_ALL);
2189 void MWindow::select_point(double position)
2191 edl->local_session->set_selectionstart(position);
2192 edl->local_session->set_selectionend(position);
2195 cwindow->update(1, 0, 0, 0, 1);
2197 update_plugin_guis();
2198 gui->update_patchbay();
2199 gui->hide_cursor(0);
2200 gui->draw_cursor(0);
2201 gui->mainclock->update(edl->local_session->get_selectionstart(1));
2202 gui->zoombar->update();
2203 gui->update_timebar(0);
2204 gui->flash_canvas(0);
2211 void MWindow::map_audio(int pattern)
2213 undo->update_undo_before();
2214 remap_audio(pattern);
2215 undo->update_undo_after(
2216 pattern == MWindow::AUDIO_1_TO_1 ? _("map 1:1") : _("map 5.1:2"),
2218 sync_parameters(CHANGE_PARAMS);
2219 gui->update(0, 1, 0, 0, 1, 0, 0);
2222 void MWindow::remap_audio(int pattern)
2224 int current_channel = 0;
2225 int current_track = 0;
2226 for( Track *current = edl->tracks->first; current; current = NEXT ) {
2227 if( current->data_type == TRACK_AUDIO &&
2229 Autos *pan_autos = current->automation->autos[AUTOMATION_PAN];
2230 PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1);
2232 for( int i = 0; i < MAXCHANNELS; i++ ) {
2233 pan_auto->values[i] = 0.0;
2236 if( pattern == MWindow::AUDIO_1_TO_1 ) {
2237 pan_auto->values[current_channel] = 1.0;
2240 if( pattern == MWindow::AUDIO_5_1_TO_2 ) {
2241 switch( current_track ) {
2243 pan_auto->values[0] = 0.5;
2244 pan_auto->values[1] = 0.5;
2247 pan_auto->values[0] = 1;
2250 pan_auto->values[1] = 1;
2253 pan_auto->values[0] = 1;
2256 pan_auto->values[1] = 1;
2259 pan_auto->values[0] = 0.5;
2260 pan_auto->values[1] = 0.5;
2265 BC_Pan::calculate_stick_position(edl->session->audio_channels,
2266 edl->session->achannel_positions, pan_auto->values,
2267 MAX_PAN, PAN_RADIUS, pan_auto->handle_x, pan_auto->handle_y);
2271 if( current_channel >= edl->session->audio_channels )
2272 current_channel = 0;
2277 void MWindow::set_proxy(int use_scaler, int new_scale,
2278 ArrayList<Indexable*> *orig_assets, ArrayList<Indexable*> *proxy_assets)
2280 int orig_use_scaler = edl->session->proxy_use_scaler;
2281 int orig_scale = edl->session->proxy_scale;
2282 // rescale to full size asset in read_frame
2283 edl->session->proxy_use_scaler = use_scaler;
2284 edl->session->proxy_scale = new_scale;
2287 for( int i=0; i<proxy_assets->size(); ++i ) {
2288 Asset *proxy_asset = (Asset *)proxy_assets->get(i);
2289 proxy_asset->width = orig_assets->get(i)->get_w();
2290 proxy_asset->height = orig_assets->get(i)->get_h();
2295 if( !orig_use_scaler && new_scale != orig_scale ) {
2297 float orig_w = (float)edl->session->output_w * orig_scale;
2298 float orig_h = (float)edl->session->output_h * orig_scale;
2299 edl->session->output_w = Units::round(orig_w / new_scale);
2300 edl->session->output_h = Units::round(orig_h / new_scale);
2303 for( Track *track=edl->tracks->first; track; track=track->next ) {
2304 if( track->data_type != TRACK_VIDEO ) continue;
2305 orig_w = (float)track->track_w * orig_scale;
2306 orig_h = (float)track->track_h * orig_scale;
2307 track->track_w = Units::round(orig_w / new_scale);
2308 track->track_h = Units::round(orig_h / new_scale);
2309 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->
2310 set_proxy(orig_scale, new_scale);
2311 ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_X])->
2312 set_proxy(orig_scale, new_scale);
2313 ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_Y])->
2314 set_proxy(orig_scale, new_scale);
2315 ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_X])->
2316 set_proxy(orig_scale, new_scale);
2317 ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_Y])->
2318 set_proxy(orig_scale, new_scale);
2322 // change original assets to proxy assets
2323 for( int i=0; i<proxy_assets->size(); i++ ) {
2324 Asset *proxy_asset = edl->assets->update((Asset *)proxy_assets->get(i));
2325 // replace track contents
2326 for( Track *track = edl->tracks->first; track; track = track->next ) {
2327 if( track->data_type != TRACK_VIDEO ) continue;
2328 for( Edit *edit = track->edits->first; edit; edit = edit->next ) {
2329 if( !edit->asset ) continue;
2330 if( !strcmp(edit->asset->path, orig_assets->get(i)->path) ) {
2331 edit->asset = proxy_asset;
2338 void MWindow::cut_commercials()
2340 undo->update_undo_before();
2341 commercials->scan_media();
2344 undo->update_undo_after(_("cut ads"), LOAD_EDITS | LOAD_TIMEBAR);
2347 update_plugin_guis();
2348 gui->update(1, 2, 1, 1, 1, 1, 0);
2349 cwindow->update(1, 0, 0, 0, 1);
2350 cwindow->playback_engine->que->
2351 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);