r851: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / mwindowedit.C
blob2fa003b5cb77b050cf491e7fb1fac1435db9656c
1 #include "asset.h"
2 #include "assets.h"
3 #include "awindowgui.h"
4 #include "awindow.h"
5 #include "bcsignals.h"
6 #include "cache.h"
7 #include "clip.h"
8 #include "clipedit.h"
9 #include "cplayback.h"
10 #include "ctimebar.h"
11 #include "cwindow.h"
12 #include "cwindowgui.h"
13 #include "bchash.h"
14 #include "edl.h"
15 #include "edlsession.h"
16 #include "filexml.h"
17 #include "gwindow.h"
18 #include "gwindowgui.h"
19 #include "keyframe.h"
20 #include "language.h"
21 #include "labels.h"
22 #include "levelwindow.h"
23 #include "localsession.h"
24 #include "mainclock.h"
25 #include "maincursor.h"
26 #include "mainindexes.h"
27 #include "mainmenu.h"
28 #include "mainsession.h"
29 #include "mainundo.h"
30 #include "maskautos.h"
31 #include "mtimebar.h"
32 #include "mwindowgui.h"
33 #include "mwindow.h"
34 #include "patchbay.h"
35 #include "playbackengine.h"
36 #include "pluginset.h"
37 #include "recordlabel.h"
38 #include "samplescroll.h"
39 #include "trackcanvas.h"
40 #include "track.h"
41 #include "trackscroll.h"
42 #include "tracks.h"
43 #include "transition.h"
44 #include "transportque.h"
45 #include "units.h"
46 #include "undostackitem.h"
47 #include "vplayback.h"
48 #include "vwindow.h"
49 #include "vwindowgui.h"
50 #include "zoombar.h"
51 #include "automation.h"
52 #include "maskautos.h"
55 #include <string.h>
62 void MWindow::add_audio_track_entry(int above, Track *dst)
64         add_audio_track(above, dst);
65         save_backup();
66         undo->update_undo(_("add track"), LOAD_ALL);
68         restart_brender();
69         gui->get_scrollbars();
70         gui->canvas->draw();
71         gui->patchbay->update();
72         gui->cursor->draw(1);
73         gui->canvas->flash();
74         gui->canvas->activate();
75         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
76                 CHANGE_EDL,
77                 edl,
78                 1);
81 void MWindow::add_video_track_entry(Track *dst)
83         add_video_track(1, dst);
84         undo->update_undo(_("add track"), LOAD_ALL);
86         restart_brender();
87         gui->get_scrollbars();
88         gui->canvas->draw();
89         gui->patchbay->update();
90         gui->cursor->draw(1);
91         gui->canvas->flash();
92         gui->canvas->activate();
93         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
94                                                         CHANGE_EDL,
95                                                         edl,
96                                                         1);
97         save_backup();
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);
105         save_backup();
106         return 0;
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);
113         save_backup();
114         return 0;
121 void MWindow::asset_to_size()
123         if(session->drag_assets->total &&
124                 session->drag_assets->values[0]->video_data)
125         {
126                 int w, h;
128 // Get w and h
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;
136 // Get aspect ratio
137                 if(defaults->get("AUTOASPECT", 0))
138                 {
139                         create_aspect_ratio(edl->session->aspect_w, 
140                                 edl->session->aspect_h, 
141                                 w, 
142                                 h);
143                 }
145                 save_backup();
147                 undo->update_undo(_("asset to size"), LOAD_ALL);
148                 restart_brender();
149                 sync_parameters(CHANGE_ALL);
150         }
154 void MWindow::asset_to_rate()
156         if(session->drag_assets->total &&
157                 session->drag_assets->values[0]->video_data)
158         {
159                 double new_framerate = session->drag_assets->values[0]->frame_rate;
160                 double old_framerate = edl->session->frame_rate;
162                 edl->session->frame_rate = new_framerate;
163                 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
165                 save_backup();
167                 undo->update_undo(_("asset to rate"), LOAD_ALL);
168                 restart_brender();
169                 gui->update(1,
170                         2,
171                         1,
172                         1,
173                         1, 
174                         1,
175                         0);
176                 sync_parameters(CHANGE_ALL);
177         }
182 void MWindow::clear_entry()
184         clear(1);
186         edl->optimize();
187         save_backup();
188         undo->update_undo(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
190         restart_brender();
191         update_plugin_guis();
192         gui->update(1, 2, 1, 1, 1, 1, 0);
193         cwindow->update(1, 0, 0, 0, 1);
194         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
195                            CHANGE_EDL,
196                            edl,
197                            1);
200 void MWindow::clear(int clear_handle)
202         double start = edl->local_session->get_selectionstart();
203         double end = edl->local_session->get_selectionend();
204         if(clear_handle || !EQUIV(start, end))
205         {
206                 edl->clear(start, 
207                         end, 
208                         edl->session->labels_follow_edits, 
209                         edl->session->plugins_follow_edits);
210         }
213 void MWindow::straighten_automation()
215         edl->tracks->straighten_automation(
216                 edl->local_session->get_selectionstart(), 
217                 edl->local_session->get_selectionend()); 
218         save_backup();
219         undo->update_undo(_("straighten curves"), LOAD_AUTOMATION); 
221         restart_brender();
222         update_plugin_guis();
223         gui->canvas->draw_overlays();
224         gui->canvas->flash();
225         sync_parameters(CHANGE_PARAMS);
226         gui->patchbay->update();
227         cwindow->update(1, 0, 0);
230 void MWindow::clear_automation()
232         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
233                 edl->local_session->get_selectionend()); 
234         save_backup();
235         undo->update_undo(_("clear keyframes"), LOAD_AUTOMATION); 
237         restart_brender();
238         update_plugin_guis();
239         gui->canvas->draw_overlays();
240         gui->canvas->flash();
241         sync_parameters(CHANGE_PARAMS);
242         gui->patchbay->update();
243         cwindow->update(1, 0, 0);
246 int MWindow::clear_default_keyframe()
248         edl->tracks->clear_default_keyframe();
249         save_backup();
250         undo->update_undo(_("clear default keyframe"), LOAD_AUTOMATION);
251         
252         restart_brender();
253         gui->canvas->draw_overlays();
254         gui->canvas->flash();
255         sync_parameters(CHANGE_PARAMS);
256         gui->patchbay->update();
257         cwindow->update(1, 0, 0);
258         
259         return 0;
262 void MWindow::clear_labels()
264         clear_labels(edl->local_session->get_selectionstart(), 
265                 edl->local_session->get_selectionend()); 
266         undo->update_undo(_("clear labels"), LOAD_TIMEBAR);
267         
268         gui->timebar->update();
269         cwindow->update(0, 0, 0, 0, 1);
270         save_backup();
273 int MWindow::clear_labels(double start, double end)
275         edl->labels->clear(start, end, 0);
276         return 0;
279 void MWindow::concatenate_tracks()
281         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
282         save_backup();
283         undo->update_undo(_("concatenate tracks"), LOAD_EDITS);
285         restart_brender();
286         gui->update(1, 1, 0, 0, 1, 0, 0);
287         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
288                 CHANGE_EDL,
289                 edl,
290                 1);
294 void MWindow::copy()
296         copy(edl->local_session->get_selectionstart(), 
297                 edl->local_session->get_selectionend());
300 int MWindow::copy(double start, double end)
302         if(start == end) return 1;
304 //printf("MWindow::copy 1\n");
305         FileXML file;
306 //printf("MWindow::copy 1\n");
307         edl->copy(start, 
308                 end, 
309                 0,
310                 0,
311                 0,
312                 &file, 
313                 plugindb,
314                 "",
315                 1);
316 //printf("MWindow::copy 1\n");
318 // File is now terminated and rewound
320 //printf("MWindow::copy 1\n");
321         gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
322 //printf("MWindow::copy\n%s\n", file.string);
323 //printf("MWindow::copy 2\n");
324         save_backup();
325         return 0;
328 int MWindow::copy_automation()
330         FileXML file;
331         edl->tracks->copy_automation(edl->local_session->get_selectionstart(), 
332                 edl->local_session->get_selectionend(),
333                 &file,
334                 0,
335                 0); 
336         gui->get_clipboard()->to_clipboard(file.string, 
337                 strlen(file.string), 
338                 SECONDARY_SELECTION);
339         return 0;
342 int MWindow::copy_default_keyframe()
344         FileXML file;
345         edl->tracks->copy_default_keyframe(&file);
346         gui->get_clipboard()->to_clipboard(file.string,
347                 strlen(file.string),
348                 SECONDARY_SELECTION);
349         return 0;
353 // Uses cropping coordinates in edl session to crop and translate video.
354 // We modify the projector since camera automation depends on the track size.
355 void MWindow::crop_video()
358 // Clamp EDL crop region
359         if(edl->session->crop_x1 > edl->session->crop_x2)
360         {
361                 edl->session->crop_x1 ^= edl->session->crop_x2;
362                 edl->session->crop_x2 ^= edl->session->crop_x1;
363                 edl->session->crop_x1 ^= edl->session->crop_x2;
364         }
365         if(edl->session->crop_y1 > edl->session->crop_y2)
366         {
367                 edl->session->crop_y1 ^= edl->session->crop_y2;
368                 edl->session->crop_y2 ^= edl->session->crop_y1;
369                 edl->session->crop_y1 ^= edl->session->crop_y2;
370         }
372         float old_projector_x = (float)edl->session->output_w / 2;
373         float old_projector_y = (float)edl->session->output_h / 2;
374         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
375         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
376         float projector_offset_x = -(new_projector_x - old_projector_x);
377         float projector_offset_y = -(new_projector_y - old_projector_y);
379         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
381         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
382         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
383         edl->session->crop_x1 = 0;
384         edl->session->crop_y1 = 0;
385         edl->session->crop_x2 = edl->session->output_w;
386         edl->session->crop_y2 = edl->session->output_h;
388 // Recalculate aspect ratio
389         if(defaults->get("AUTOASPECT", 0))
390         {
391                 create_aspect_ratio(edl->session->aspect_w, 
392                         edl->session->aspect_h, 
393                         edl->session->output_w, 
394                         edl->session->output_h);
395         }
397         undo->update_undo(_("crop"), LOAD_ALL);
399         restart_brender();
400         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
401                 CHANGE_ALL,
402                 edl,
403                 1);
404         save_backup();
407 void MWindow::cut()
410         double start = edl->local_session->get_selectionstart();
411         double end = edl->local_session->get_selectionend();
413         copy(start, end);
414         edl->clear(start, 
415                 end,
416                 edl->session->labels_follow_edits, 
417                 edl->session->plugins_follow_edits);
420         edl->optimize();
421         save_backup();
422         undo->update_undo(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
424         restart_brender();
425         update_plugin_guis();
426         gui->update(1, 2, 1, 1, 1, 1, 0);
427         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
428                                                         CHANGE_EDL,
429                                                         edl,
430                                                         1);
433 int MWindow::cut_automation()
435         
436         copy_automation();
438         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
439                 edl->local_session->get_selectionend()); 
440         save_backup();
441         undo->update_undo(_("cut keyframes"), LOAD_AUTOMATION); 
444         restart_brender();
445         update_plugin_guis();
446         gui->canvas->draw_overlays();
447         gui->canvas->flash();
448         sync_parameters(CHANGE_PARAMS);
449         gui->patchbay->update();
450         cwindow->update(1, 0, 0);
451         return 0;
454 int MWindow::cut_default_keyframe()
457         copy_default_keyframe();
458         edl->tracks->clear_default_keyframe();
459         undo->update_undo(_("cut default keyframe"), LOAD_AUTOMATION);
461         restart_brender();
462         gui->canvas->draw_overlays();
463         gui->canvas->flash();
464         sync_parameters(CHANGE_PARAMS);
465         gui->patchbay->update();
466         cwindow->update(1, 0, 0);
467         save_backup();
470         return 0;
473 void MWindow::delete_inpoint()
475         edl->local_session->unset_inpoint();
476         save_backup();
479 void MWindow::delete_outpoint()
481         edl->local_session->unset_outpoint();
482         save_backup();
485 void MWindow::delete_track()
487         if (edl->tracks->last)
488                 delete_track(edl->tracks->last);
491 void MWindow::delete_tracks()
493         edl->tracks->delete_tracks();
494         undo->update_undo(_("delete tracks"), LOAD_ALL);
495         save_backup();
497         restart_brender();
498         update_plugin_states();
499         gui->update(1, 1, 1, 0, 1, 0, 0);
500         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
501                            CHANGE_EDL,
502                            edl,
503                            1);
506 void MWindow::delete_track(Track *track)
508         edl->tracks->delete_track(track);
509         undo->update_undo(_("delete track"), LOAD_ALL);
511         restart_brender();
512         update_plugin_states();
513         gui->update(1, 1, 1, 0, 1, 0, 0);
514         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
515                            CHANGE_EDL,
516                            edl,
517                            1);
518         save_backup();
521 void MWindow::detach_transition(Transition *transition)
523         hide_plugin(transition, 1);
524         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
525         transition->edit->detach_transition();
526         save_backup();
527         undo->update_undo(_("detach transition"), LOAD_ALL);
529         if(is_video) restart_brender();
530         gui->update(0,
531                 1,
532                 0,
533                 0,
534                 0, 
535                 0,
536                 0);
537         sync_parameters(CHANGE_EDL);
544 // Insert data from clipboard
545 void MWindow::insert(double position, 
546         FileXML *file,
547         int edit_labels,
548         int edit_plugins,
549         EDL *parent_edl)
551 // For clipboard pasting make the new edl use a separate session 
552 // from the master EDL.  Then it can be resampled to the master rates.
553 // For splice, overwrite, and dragging need same session to get the assets.
554         EDL edl(parent_edl);
555         ArrayList<EDL*> new_edls;
556         uint32_t load_flags = LOAD_ALL;
559         new_edls.append(&edl);
560         edl.create_objects();
565         if(parent_edl) load_flags &= ~LOAD_SESSION;
566         if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
567         if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
569         edl.load_xml(plugindb, file, load_flags);
576         paste_edls(&new_edls, 
577                 LOAD_PASTE, 
578                 0, 
579                 position,
580                 edit_labels,
581                 edit_plugins);
582 // if(vwindow->edl)
583 // printf("MWindow::insert 5 %f %f\n", 
584 // vwindow->edl->local_session->in_point,
585 // vwindow->edl->local_session->out_point);
586         new_edls.remove_all();
587 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
590 void MWindow::insert_effects_canvas(double start,
591         double length)
593         Track *dest_track = session->track_highlighted;
594         if(!dest_track) return;
597         for(int i = 0; i < session->drag_pluginservers->total; i++)
598         {
599                 PluginServer *plugin = session->drag_pluginservers->values[i];
601                 insert_effect(plugin->title,
602                         0,
603                         dest_track,
604                         i == 0 ? session->pluginset_highlighted : 0,
605                         start,
606                         length,
607                         PLUGIN_STANDALONE);
608         }
610         save_backup();
611         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
612         restart_brender();
613         sync_parameters(CHANGE_EDL);
614 // GUI updated in TrackCanvas, after current_operations are reset
617 void MWindow::insert_effects_cwindow(Track *dest_track)
619         if(!dest_track) return;
622         double start = 0;
623         double length = dest_track->get_length();
625         if(edl->local_session->get_selectionend() > 
626                 edl->local_session->get_selectionstart())
627         {
628                 start = edl->local_session->get_selectionstart();
629                 length = edl->local_session->get_selectionend() - 
630                         edl->local_session->get_selectionstart();
631         }
633         for(int i = 0; i < session->drag_pluginservers->total; i++)
634         {
635                 PluginServer *plugin = session->drag_pluginservers->values[i];
638                 insert_effect(plugin->title,
639                         0,
640                         dest_track,
641                         0,
642                         start,
643                         length,
644                         PLUGIN_STANDALONE);
645         }
647         save_backup();
648         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
649         restart_brender();
650         sync_parameters(CHANGE_EDL);
651         gui->update(1,
652                 1,
653                 0,
654                 0,
655                 1,
656                 0,
657                 0);
662 void MWindow::insert_effect(char *title, 
663         SharedLocation *shared_location, 
664         Track *track,
665         PluginSet *plugin_set,
666         double start,
667         double length,
668         int plugin_type)
670         KeyFrame *default_keyframe = 0;
671         PluginServer *server = 0;
678 // Get default keyframe
679         if(plugin_type == PLUGIN_STANDALONE)
680         {
681                 default_keyframe = new KeyFrame;
682                 server = new PluginServer(*scan_plugindb(title, track->data_type));
684                 server->open_plugin(0, preferences, edl, 0, -1);
685                 server->save_data(default_keyframe);
686         }
690 // Insert plugin object
691         track->insert_effect(title, 
692                 shared_location, 
693                 default_keyframe, 
694                 plugin_set,
695                 start,
696                 length,
697                 plugin_type);
699         track->optimize();
702         if(plugin_type == PLUGIN_STANDALONE)
703         {
704                 server->close_plugin();
705                 delete server;
706                 delete default_keyframe;
707         }
710 int MWindow::modify_edithandles()
713         edl->modify_edithandles(session->drag_start, 
714                 session->drag_position, 
715                 session->drag_handle, 
716                 edl->session->edit_handle_mode[session->drag_button],
717                 edl->session->labels_follow_edits, 
718                 edl->session->plugins_follow_edits);
720         finish_modify_handles();
723 //printf("MWindow::modify_handles 1\n");
724         return 0;
727 int MWindow::modify_pluginhandles()
730         edl->modify_pluginhandles(session->drag_start, 
731                 session->drag_position, 
732                 session->drag_handle, 
733                 edl->session->edit_handle_mode[session->drag_button],
734                 edl->session->labels_follow_edits,
735                 session->trim_edits);
737         finish_modify_handles();
739         return 0;
743 // Common to edithandles and plugin handles
744 void MWindow::finish_modify_handles()
746         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
748         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
749                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
750         {
751                 edl->local_session->set_selectionstart(session->drag_position);
752                 edl->local_session->set_selectionend(session->drag_position);
753         }
754         else
755         if(edit_mode != MOVE_NO_EDITS)
756         {
757                 edl->local_session->set_selectionstart(session->drag_start);
758                 edl->local_session->set_selectionend(session->drag_start);
759         }
761         if(edl->local_session->get_selectionstart(1) < 0)
762         {
763                 edl->local_session->set_selectionstart(0);
764                 edl->local_session->set_selectionend(0);
765         }
767         save_backup();
768         undo->update_undo(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
769         restart_brender();
770         sync_parameters(CHANGE_EDL);
771         update_plugin_guis();
772         gui->update(1, 2, 1, 1, 1, 1, 0);
773         cwindow->update(1, 0, 0, 0, 1);
776 void MWindow::match_output_size(Track *track)
778         track->track_w = edl->session->output_w;
779         track->track_h = edl->session->output_h;
780         save_backup();
781         undo->update_undo(_("match output size"), LOAD_ALL);
783         restart_brender();
784         sync_parameters(CHANGE_EDL);
788 void MWindow::move_edits(ArrayList<Edit*> *edits, 
789                 Track *track,
790                 double position,
791                 int behaviour)
794         edl->tracks->move_edits(edits, 
795                 track, 
796                 position,
797                 edl->session->labels_follow_edits, 
798                 edl->session->plugins_follow_edits,
799                 behaviour);
801         save_backup();
802         undo->update_undo(_("move edit"), LOAD_ALL);
804         restart_brender();
805         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
806                 CHANGE_EDL,
807                 edl,
808                 1);
810         update_plugin_guis();
811         gui->update(1,
812                 1,      // 1 for incremental drawing.  2 for full refresh
813                 1,
814                 0,
815                 0, 
816                 0,
817                 0);
820 void MWindow::move_effect(Plugin *plugin,
821         PluginSet *dest_plugin_set,
822         Track *dest_track,
823         int64_t dest_position)
826         edl->tracks->move_effect(plugin, 
827                 dest_plugin_set, 
828                 dest_track, 
829                 dest_position);
831         save_backup();
832         undo->update_undo(_("move effect"), LOAD_ALL);
834         restart_brender();
835         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
836                 CHANGE_EDL,
837                 edl,
838                 1);
840         update_plugin_guis();
841         gui->update(1,
842                 1,      // 1 for incremental drawing.  2 for full refresh
843                 0,
844                 0,
845                 0, 
846                 0,
847                 0);
850 void MWindow::move_plugins_up(PluginSet *plugin_set)
853         plugin_set->track->move_plugins_up(plugin_set);
855         save_backup();
856         undo->update_undo(_("move effect up"), LOAD_ALL);
857         restart_brender();
858         gui->update(1,
859                 1,      // 1 for incremental drawing.  2 for full refresh
860                 0,
861                 0,
862                 0, 
863                 0,
864                 0);
865         sync_parameters(CHANGE_EDL);
868 void MWindow::move_plugins_down(PluginSet *plugin_set)
871         plugin_set->track->move_plugins_down(plugin_set);
873         save_backup();
874         undo->update_undo(_("move effect down"), LOAD_ALL);
875         restart_brender();
876         gui->update(1,
877                 1,      // 1 for incremental drawing.  2 for full refresh
878                 0,
879                 0,
880                 0, 
881                 0,
882                 0);
883         sync_parameters(CHANGE_EDL);
886 void MWindow::move_track_down(Track *track)
888         edl->tracks->move_track_down(track);
889         save_backup();
890         undo->update_undo(_("move track down"), LOAD_ALL);
892         restart_brender();
893         gui->update(1, 1, 0, 0, 1, 0, 0);
894         sync_parameters(CHANGE_EDL);
895         save_backup();
898 void MWindow::move_tracks_down()
900         edl->tracks->move_tracks_down();
901         save_backup();
902         undo->update_undo(_("move tracks down"), LOAD_ALL);
904         restart_brender();
905         gui->update(1, 1, 0, 0, 1, 0, 0);
906         sync_parameters(CHANGE_EDL);
907         save_backup();
910 void MWindow::move_track_up(Track *track)
912         edl->tracks->move_track_up(track);
913         save_backup();
914         undo->update_undo(_("move track up"), LOAD_ALL);
915         restart_brender();
916         gui->update(1, 1, 0, 0, 1, 0, 0);
917         sync_parameters(CHANGE_EDL);
918         save_backup();
921 void MWindow::move_tracks_up()
923         edl->tracks->move_tracks_up();
924         save_backup();
925         undo->update_undo(_("move tracks up"), LOAD_ALL);
926         restart_brender();
927         gui->update(1, 1, 0, 0, 1, 0, 0);
928         sync_parameters(CHANGE_EDL);
932 void MWindow::mute_selection()
934         double start = edl->local_session->get_selectionstart();
935         double end = edl->local_session->get_selectionend();
936         if(start != end)
937         {
938                 edl->clear(start, 
939                         end, 
940                         0, 
941                         edl->session->plugins_follow_edits);
942                 edl->local_session->set_selectionend(end);
943                 edl->local_session->set_selectionstart(start);
944                 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
945                 save_backup();
946                 undo->update_undo(_("mute"), LOAD_EDITS);
948                 restart_brender();
949                 update_plugin_guis();
950                 gui->update(1, 2, 1, 1, 1, 1, 0);
951                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
952                                                                 CHANGE_EDL,
953                                                                 edl,
954                                                                 1);
955         }
960 void MWindow::overwrite(EDL *source)
962         FileXML file;
964         double src_start = source->local_session->get_selectionstart();
965         double overwrite_len = source->local_session->get_selectionend() - src_start;
966         double dst_start = edl->local_session->get_selectionstart();
967         double dst_len = edl->local_session->get_selectionend() - dst_start;
969         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
970         {
971 // in/out points or selection present and shorter than overwrite range
972 // shorten the copy range
973                 overwrite_len = dst_len;
974         }
976         source->copy(src_start, 
977                 src_start + overwrite_len, 
978                 1,
979                 0,
980                 0,
981                 &file,
982                 plugindb,
983                 "",
984                 1);
986 // HACK around paste_edl get_start/endselection on its own
987 // so we need to clear only when not using both io points
988 // FIXME: need to write simple overwrite_edl to be used for overwrite function
989         if (edl->local_session->get_inpoint() < 0 || 
990                 edl->local_session->get_outpoint() < 0)
991                 edl->clear(dst_start, 
992                         dst_start + overwrite_len, 
993                         0, 
994                         0);
996         paste(dst_start, 
997                 dst_start + overwrite_len, 
998                 &file,
999                 0,
1000                 0);
1002         edl->local_session->set_selectionstart(dst_start + overwrite_len);
1003         edl->local_session->set_selectionend(dst_start + overwrite_len);
1005         save_backup();
1006         undo->update_undo(_("overwrite"), LOAD_EDITS);
1008         restart_brender();
1009         update_plugin_guis();
1010         gui->update(1, 1, 1, 1, 0, 1, 0);
1011         sync_parameters(CHANGE_EDL);
1014 // For splice and overwrite
1015 int MWindow::paste(double start, 
1016         double end, 
1017         FileXML *file,
1018         int edit_labels,
1019         int edit_plugins)
1021         clear(0);
1023 // Want to insert with assets shared with the master EDL.
1024         insert(start, 
1025                         file,
1026                         edit_labels,
1027                         edit_plugins,
1028                         edl);
1030         return 0;
1033 // For editing use insertion point position
1034 void MWindow::paste()
1037         double start = edl->local_session->get_selectionstart();
1038         double end = edl->local_session->get_selectionend();
1039         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1041         if(len)
1042         {
1043                 char *string = new char[len + 1];
1047                 gui->get_clipboard()->from_clipboard(string, 
1048                         len, 
1049                         SECONDARY_SELECTION);
1050                 FileXML file;
1051                 file.read_from_string(string);
1056                 clear(0);
1058                 insert(start, 
1059                         &file, 
1060                         edl->session->labels_follow_edits, 
1061                         edl->session->plugins_follow_edits);
1063                 edl->optimize();
1066                 delete [] string;
1070                 save_backup();
1073                 undo->update_undo(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1074                 restart_brender();
1075                 update_plugin_guis();
1076                 gui->update(1, 2, 1, 1, 0, 1, 0);
1077                 awindow->gui->update_assets();
1078                 sync_parameters(CHANGE_EDL);
1079         }
1083 int MWindow::paste_assets(double position, Track *dest_track)
1085         int result = 0;
1090         if(session->drag_assets->total)
1091         {
1092                 load_assets(session->drag_assets, 
1093                         position, 
1094                         LOAD_PASTE,
1095                         dest_track, 
1096                         0,
1097                         edl->session->labels_follow_edits, 
1098                         edl->session->plugins_follow_edits);
1099                 result = 1;
1100         }
1103         if(session->drag_clips->total)
1104         {
1105                 paste_edls(session->drag_clips, 
1106                         LOAD_PASTE, 
1107                         dest_track,
1108                         position, 
1109                         edl->session->labels_follow_edits, 
1110                         edl->session->plugins_follow_edits);
1111                 result = 1;
1112         }
1115         save_backup();
1117         undo->update_undo(_("paste assets"), LOAD_EDITS);
1118         restart_brender();
1119         gui->update(1, 
1120                 2,
1121                 1,
1122                 0,
1123                 0,
1124                 1,
1125                 0);
1126         sync_parameters(CHANGE_EDL);
1127         return result;
1130 void MWindow::load_assets(ArrayList<Asset*> *new_assets, 
1131         double position, 
1132         int load_mode,
1133         Track *first_track,
1134         RecordLabels *labels,
1135         int edit_labels,
1136         int edit_plugins)
1138 //printf("MWindow::load_assets 1\n");
1139         if(position < 0) position = edl->local_session->get_selectionstart();
1141         ArrayList<EDL*> new_edls;
1142         for(int i = 0; i < new_assets->total; i++)
1143         {
1144                 EDL *new_edl = new EDL;
1145                 new_edl->create_objects();
1146                 new_edl->copy_session(edl);
1147                 new_edls.append(new_edl);
1150 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1151                 asset_to_edl(new_edl, new_assets->values[i]);
1154                 if(labels)
1155                         for(RecordLabel *label = labels->first; label; label = label->next)
1156                         {
1157                                 new_edl->labels->toggle_label(label->position, label->position);
1158                         }
1159         }
1160 //printf("MWindow::load_assets 3\n");
1162         paste_edls(&new_edls, 
1163                 load_mode, 
1164                 first_track,
1165                 position,
1166                 edit_labels,
1167                 edit_plugins);
1168 //printf("MWindow::load_assets 4\n");
1171         save_backup();
1172         new_edls.remove_all_objects();
1176 int MWindow::paste_automation()
1178         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1180         if(len)
1181         {
1182                 char *string = new char[len + 1];
1183                 gui->get_clipboard()->from_clipboard(string, 
1184                         len, 
1185                         SECONDARY_SELECTION);
1186                 FileXML file;
1187                 file.read_from_string(string);
1189                 edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
1190                         edl->local_session->get_selectionend()); 
1191                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(), 
1192                         &file,
1193                         0); 
1194                 save_backup();
1195                 undo->update_undo(_("paste keyframes"), LOAD_AUTOMATION);
1196                 delete [] string;
1199                 restart_brender();
1200                 update_plugin_guis();
1201                 gui->canvas->draw_overlays();
1202                 gui->canvas->flash();
1203                 sync_parameters(CHANGE_PARAMS);
1204                 gui->patchbay->update();
1205                 cwindow->update(1, 0, 0);
1206         }
1208         return 0;
1211 int MWindow::paste_default_keyframe()
1213         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1215         if(len)
1216         {
1217                 char *string = new char[len + 1];
1218                 gui->get_clipboard()->from_clipboard(string, 
1219                         len, 
1220                         SECONDARY_SELECTION);
1221                 FileXML file;
1222                 file.read_from_string(string);
1223                 edl->tracks->paste_default_keyframe(&file); 
1224                 undo->update_undo(_("paste default keyframe"), LOAD_AUTOMATION);
1227                 restart_brender();
1228                 update_plugin_guis();
1229                 gui->canvas->draw_overlays();
1230                 gui->canvas->flash();
1231                 sync_parameters(CHANGE_PARAMS);
1232                 gui->patchbay->update();
1233                 cwindow->update(1, 0, 0);
1234                 delete [] string;
1235                 save_backup();
1236         }
1238         return 0;
1242 // Insert edls with project deletion and index file generation.
1243 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, 
1244         int load_mode, 
1245         Track *first_track,
1246         double current_position,
1247         int edit_labels,
1248         int edit_plugins)
1251         ArrayList<Track*> destination_tracks;
1252         int need_new_tracks = 0;
1254         if(!new_edls->total) return 0;
1257 SET_TRACE
1259 // Delete current project
1260         if(load_mode == LOAD_REPLACE ||
1261                 load_mode == LOAD_REPLACE_CONCATENATE)
1262         {
1263                 edl->save_defaults(defaults);
1265                 hide_plugins();
1267                 delete edl;
1269                 edl = new EDL;
1271                 edl->create_objects();
1273                 edl->copy_session(new_edls->values[0]);
1275                 gui->mainmenu->update_toggles(0);
1278                 gui->unlock_window();
1280                 gwindow->gui->update_toggles(1);
1282                 gui->lock_window("MWindow::paste_edls");
1285 // Insert labels for certain modes constitutively
1286                 edit_labels = 1;
1287                 edit_plugins = 1;
1288         }
1290 SET_TRACE
1293 SET_TRACE
1294 // Create new tracks in master EDL
1295         if(load_mode == LOAD_REPLACE || 
1296                 load_mode == LOAD_REPLACE_CONCATENATE ||
1297                 load_mode == LOAD_NEW_TRACKS)
1298         {
1300                 need_new_tracks = 1;
1301                 for(int i = 0; i < new_edls->total; i++)
1302                 {
1303                         EDL *new_edl = new_edls->values[i];
1304                         for(Track *current = new_edl->tracks->first;
1305                                 current;
1306                                 current = NEXT)
1307                         {
1308                                 if(current->data_type == TRACK_VIDEO)
1309                                 {
1310                                         edl->tracks->add_video_track(0, 0);
1311                                         if(current->draw) edl->tracks->last->draw = 1;
1312                                         destination_tracks.append(edl->tracks->last);
1313                                 }
1314                                 else
1315                                 if(current->data_type == TRACK_AUDIO)
1316                                 {
1317                                         edl->tracks->add_audio_track(0, 0);
1318                                         destination_tracks.append(edl->tracks->last);
1319                                 }
1320                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1321                         }
1323 // Base track count on first EDL only for concatenation
1324                         if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1325                 }
1327         }
1328         else
1329 // Recycle existing tracks of master EDL
1330         if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1331         {
1333 // The point of this is to shift forward labels after the selection so they can
1334 // then be shifted back to their original locations without recursively
1335 // shifting back every paste.
1336                 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1337                         edl->labels->clear(edl->local_session->get_selectionstart(),
1338                                                 edl->local_session->get_selectionend(),
1339                                                 1);
1340         
1341                 Track *current = first_track ? first_track : edl->tracks->first;
1342                 for( ; current; current = NEXT)
1343                 {
1344                         if(current->record)
1345                         {
1346                                 destination_tracks.append(current);
1348 // This should be done in the caller so we don't get recursive clear disease.
1349 //                              if(load_mode == LOAD_PASTE)
1350 //                                      current->clear(edl->local_session->get_selectionstart(),
1351 //                                              edl->local_session->get_selectionend(),
1352 //                                              1,
1353 //                                              edl->session->labels_follow_edits, 
1354 //                                              edl->session->plugins_follow_edits,
1355 //                                              1);
1356                         }
1357                 }
1359         }
1364         int destination_track = 0;
1365         double *paste_position = new double[destination_tracks.total];
1369 SET_TRACE
1372 // Iterate through the edls
1373         for(int i = 0; i < new_edls->total; i++)
1374         {
1376                 EDL *new_edl = new_edls->values[i];
1377 SET_TRACE
1378                 double edl_length = new_edl->local_session->clipboard_length ?
1379                         new_edl->local_session->clipboard_length :
1380                         new_edl->tracks->total_length();
1381 // printf("MWindow::paste_edls 2\n");
1382 // new_edl->dump();
1384 SET_TRACE
1388 // Resample EDL to master rates
1389                 new_edl->resample(new_edl->session->sample_rate, 
1390                         edl->session->sample_rate, 
1391                         TRACK_AUDIO);
1392                 new_edl->resample(new_edl->session->frame_rate, 
1393                         edl->session->frame_rate, 
1394                         TRACK_VIDEO);
1396 SET_TRACE
1400 // Add assets and prepare index files
1401                 for(Asset *new_asset = new_edl->assets->first;
1402                         new_asset;
1403                         new_asset = new_asset->next)
1404                 {
1405                         mainindexes->add_next_asset(0, new_asset);
1406                 }
1407 SET_TRACE
1408 // Capture index file status from mainindex test
1409                 edl->update_assets(new_edl);
1411 SET_TRACE
1414 // Get starting point of insertion.  Need this to paste labels.
1415                 switch(load_mode)
1416                 {
1417                         case LOAD_REPLACE:
1418                         case LOAD_NEW_TRACKS:
1419                                 current_position = 0;
1420                                 break;
1422                         case LOAD_CONCATENATE:
1423                         case LOAD_REPLACE_CONCATENATE:
1424                                 destination_track = 0;
1425                                 if(destination_tracks.total)
1426                                         current_position = destination_tracks.values[0]->get_length();
1427                                 else
1428                                         current_position = 0;
1429                                 break;
1431                         case LOAD_PASTE:
1432                                 destination_track = 0;
1433                                 if(i == 0)
1434                                 {
1435                                         for(int j = 0; j < destination_tracks.total; j++)
1436                                         {
1437                                                 paste_position[j] = (current_position >= 0) ? 
1438                                                         current_position :
1439                                                         edl->local_session->get_selectionstart();
1440                                         }
1441                                 }
1442                                 break;
1444                         case LOAD_RESOURCESONLY:
1445                                 edl->add_clip(new_edl);
1446                                 break;
1447                 }
1452 SET_TRACE
1454 // Insert edl
1455                 if(load_mode != LOAD_RESOURCESONLY)
1456                 {
1457 // Insert labels
1458 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1459                         if(load_mode == LOAD_PASTE)
1460                                 edl->labels->insert_labels(new_edl->labels, 
1461                                         destination_tracks.total ? paste_position[0] : 0.0,
1462                                         edl_length,
1463                                         edit_labels);
1464                         else
1465                                 edl->labels->insert_labels(new_edl->labels, 
1466                                         current_position,
1467                                         edl_length,
1468                                         edit_labels);
1470                         for(Track *new_track = new_edl->tracks->first; 
1471                                 new_track; 
1472                                 new_track = new_track->next)
1473                         {
1474 // Get destination track of same type as new_track
1475                                 for(int k = 0; 
1476                                         k < destination_tracks.total &&
1477                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1478                                         k++, destination_track++)
1479                                 {
1480                                         if(destination_track >= destination_tracks.total - 1)
1481                                                 destination_track = 0;
1482                                 }
1484 // Insert data into destination track
1485                                 if(destination_track < destination_tracks.total &&
1486                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1487                                 {
1488                                         Track *track = destination_tracks.values[destination_track];
1490 // Replace default keyframes if first EDL and new tracks were created.
1491 // This means data copied from one track and pasted to another won't retain
1492 // the camera position unless it's a keyframe.  If it did, previous data in the
1493 // track might get unknowingly corrupted.  Ideally we would detect when differing
1494 // default keyframes existed and create discrete keyframes for both.
1495                                         int replace_default = (i == 0) && need_new_tracks;
1497 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1498 // Insert new track at current position
1499                                         switch(load_mode)
1500                                         {
1501                                                 case LOAD_REPLACE_CONCATENATE:
1502                                                 case LOAD_CONCATENATE:
1503                                                         current_position = track->get_length();
1504                                                         break;
1506                                                 case LOAD_PASTE:
1507                                                         current_position = paste_position[destination_track];
1508                                                         paste_position[destination_track] += new_track->get_length();
1509                                                         break;
1510                                         }
1512                                         track->insert_track(new_track, 
1513                                                 current_position, 
1514                                                 replace_default,
1515                                                 edit_plugins);
1516                                 }
1518 // Get next destination track
1519                                 destination_track++;
1520                                 if(destination_track >= destination_tracks.total)
1521                                         destination_track = 0;
1522                         }
1523                 }
1525 SET_TRACE
1526                 if(load_mode == LOAD_PASTE)
1527                         current_position += edl_length;
1528         }
1531 // Move loading of clips and vwindow to the end - this fixes some
1532 // strange issue, for index not being shown
1533 // Assume any paste operation from the same EDL won't contain any clips.
1534 // If it did it would duplicate every clip here.
1535         for(int i = 0; i < new_edls->total; i++)
1536         {
1537                 EDL *new_edl = new_edls->values[i];
1539                 for(int j = 0; j < new_edl->clips.total; j++)
1540                 {
1541                         edl->add_clip(new_edl->clips.values[j]);
1542                 }
1544                 if(new_edl->vwindow_edl)
1545                 {
1546                         if(edl->vwindow_edl) delete edl->vwindow_edl;
1547                         edl->vwindow_edl = new EDL(edl);
1548                         edl->vwindow_edl->create_objects();
1549                         edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1550                 }
1551         }
1554 SET_TRACE
1555         if(paste_position) delete [] paste_position;
1558 SET_TRACE
1559 // This is already done in load_filenames and everything else that uses paste_edls
1560 //      update_project(load_mode);
1562 SET_TRACE
1563 // Start examining next batch of index files
1564         mainindexes->start_build();
1565 SET_TRACE
1568 // Don't save a backup after loading since the loaded file is on disk already.
1571         return 0;
1574 void MWindow::paste_silence()
1576         double start = edl->local_session->get_selectionstart();
1577         double end = edl->local_session->get_selectionend();
1578         edl->paste_silence(start, 
1579                 end, 
1580                 edl->session->labels_follow_edits, 
1581                 edl->session->plugins_follow_edits);
1582         edl->optimize();
1583         save_backup();
1584         undo->update_undo(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1586         update_plugin_guis();
1587         restart_brender();
1588         gui->update(1, 2, 1, 1, 1, 1, 0);
1589         cwindow->update(1, 0, 0, 0, 1);
1590         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1591                                                         CHANGE_EDL,
1592                                                         edl,
1593                                                         1);
1596 void MWindow::paste_transition()
1598 // Only the first transition gets dropped.
1599         PluginServer *server = session->drag_pluginservers->values[0];
1600         if(server->audio)
1601                 strcpy(edl->session->default_atransition, server->title);
1602         else
1603                 strcpy(edl->session->default_vtransition, server->title);
1605         edl->tracks->paste_transition(server, session->edit_highlighted);
1606         save_backup();
1607         undo->update_undo(_("transition"), LOAD_EDITS);
1609         if(server->video) restart_brender();
1610         sync_parameters(CHANGE_ALL);
1613 void MWindow::paste_transition_cwindow(Track *dest_track)
1615         PluginServer *server = session->drag_pluginservers->values[0];
1616         edl->tracks->paste_video_transition(server, 1);
1617         save_backup();
1618         undo->update_undo(_("transition"), LOAD_EDITS);
1619         restart_brender();
1620         gui->update(0, 1, 0, 0, 0, 0, 0);
1621         sync_parameters(CHANGE_ALL);
1624 void MWindow::paste_audio_transition()
1626         PluginServer *server = scan_plugindb(edl->session->default_atransition,
1627                 TRACK_AUDIO);
1628         if(!server)
1629         {
1630                 char string[BCTEXTLEN];
1631                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1632                 gui->show_message(string);
1633                 return;
1634         }
1636         edl->tracks->paste_audio_transition(server);
1637         save_backup();
1638         undo->update_undo(_("transition"), LOAD_EDITS);
1640         sync_parameters(CHANGE_ALL);
1641         gui->update(0, 1, 0, 0, 0, 0, 0);
1644 void MWindow::paste_video_transition()
1646         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1647                 TRACK_VIDEO);
1648         if(!server)
1649         {
1650                 char string[BCTEXTLEN];
1651                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1652                 gui->show_message(string);
1653                 return;
1654         }
1657         edl->tracks->paste_video_transition(server);
1658         save_backup();
1659         undo->update_undo(_("transition"), LOAD_EDITS);
1661         sync_parameters(CHANGE_ALL);
1662         restart_brender();
1663         gui->update(0, 1, 0, 0, 0, 0, 0);
1667 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1670         calling_window_gui->unlock_window();
1672         cwindow->playback_engine->que->send_command(STOP,
1673                 CHANGE_NONE, 
1674                 0,
1675                 0);
1676         vwindow->playback_engine->que->send_command(STOP,
1677                 CHANGE_NONE, 
1678                 0,
1679                 0);
1680         cwindow->playback_engine->interrupt_playback(0);
1681         vwindow->playback_engine->interrupt_playback(0);
1684         cwindow->gui->lock_window("MWindow::redo_entry");
1685         vwindow->gui->lock_window("MWindow::undo_entry 2");
1686         gui->lock_window();
1688         undo->redo(); 
1690         save_backup();
1691         update_plugin_states();
1692         update_plugin_guis();
1693         restart_brender();
1694         gui->update(1, 2, 1, 1, 1, 1, 1);
1695         cwindow->update(1, 1, 1, 1, 1);
1697         if (calling_window_gui != cwindow->gui) 
1698                 cwindow->gui->unlock_window();
1699         if (calling_window_gui != gui)
1700                 gui->unlock_window();
1701         if (calling_window_gui != vwindow->gui)
1702                 vwindow->gui->unlock_window();
1704         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1705                            CHANGE_ALL,
1706                            edl,
1707                            1);
1708         
1712 void MWindow::resize_track(Track *track, int w, int h)
1714 // We have to move all maskpoints so they do not move in relation to image areas
1715         ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1716                 (w - track->track_w) / 2, 
1717                 (h - track->track_h) / 2);
1718         track->track_w = w;
1719         track->track_h = h;
1720         undo->update_undo(_("resize track"), LOAD_ALL);
1721         save_backup();
1723         restart_brender();
1724         sync_parameters(CHANGE_EDL);
1728 class InPointUndoItem : public UndoStackItem
1730 public:
1731         InPointUndoItem(double old_position, double new_position, EDL *edl);
1732         void undo();
1733         int get_size();
1734 private:
1735         double old_position;
1736         double new_position;
1737         EDL *edl;
1740 InPointUndoItem::InPointUndoItem(
1741       double old_position, double new_position, EDL *edl)
1743    set_description(_("in point"));
1744    this->old_position = old_position;
1745    this->new_position = new_position;
1746    this->edl = edl;
1749 void InPointUndoItem::undo()
1751    edl->set_inpoint(old_position);
1752 // prepare to undo the undo
1753         double tmp = new_position;
1754         new_position = old_position;
1755         old_position = tmp;
1758 int InPointUndoItem::get_size()
1760    return 20;
1763 void MWindow::set_inpoint(int is_mwindow)
1765    InPointUndoItem *undo_item;
1767    undo_item = new InPointUndoItem(edl->local_session->get_inpoint(),
1768          edl->local_session->get_selectionstart(1), edl);
1769    undo->push_undo_item(undo_item);
1771         edl->set_inpoint(edl->local_session->get_selectionstart(1));
1772         save_backup();
1774         if(!is_mwindow)
1775         {
1776                 gui->lock_window("MWindow::set_inpoint 1");
1777         }
1778         gui->timebar->update();
1779         gui->flush();
1780         if(!is_mwindow)
1781         {
1782                 gui->unlock_window();
1783         }
1785         if(is_mwindow)
1786         {
1787                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1788         }
1789         cwindow->gui->timebar->update();
1790         cwindow->gui->flush();
1791         if(is_mwindow)
1792         {
1793                 cwindow->gui->unlock_window();
1794         }
1797 class OutPointUndoItem : public UndoStackItem
1799 public:
1800         OutPointUndoItem(double old_position, double new_position, EDL *edl);
1801         void undo();
1802         int get_size();
1803 private:
1804         double old_position;
1805         double new_position;
1806         EDL *edl;
1809 OutPointUndoItem::OutPointUndoItem(
1810       double old_position, double new_position, EDL *edl)
1812    set_description(_("out point"));
1813    this->old_position = old_position;
1814    this->new_position = new_position;
1815    this->edl = edl;
1818 void OutPointUndoItem::undo()
1820    edl->set_outpoint(old_position);
1821 // prepare to undo the undo
1822         double tmp = new_position;
1823         new_position = old_position;
1824         old_position = tmp;
1827 int OutPointUndoItem::get_size()
1829    return 20;
1832 void MWindow::set_outpoint(int is_mwindow)
1834    OutPointUndoItem *undo_item;
1836    undo_item = new OutPointUndoItem(edl->local_session->get_outpoint(),
1837          edl->local_session->get_selectionend(1), edl);
1838    undo->push_undo_item(undo_item);
1840         edl->set_outpoint(edl->local_session->get_selectionend(1));
1841         save_backup();
1843         if(!is_mwindow)
1844         {
1845                 gui->lock_window("MWindow::set_outpoint 1");
1846         }
1847         gui->timebar->update();
1848         gui->flush();
1849         if(!is_mwindow)
1850         {
1851                 gui->unlock_window();
1852         }
1854         if(is_mwindow)
1855         {
1856                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1857         }
1858         cwindow->gui->timebar->update();
1859         cwindow->gui->flush();
1860         if(is_mwindow)
1861         {
1862                 cwindow->gui->unlock_window();
1863         }
1866 void MWindow::splice(EDL *source)
1868         FileXML file;
1870         source->copy(source->local_session->get_selectionstart(), 
1871                 source->local_session->get_selectionend(), 
1872                 1,
1873                 0,
1874                 0,
1875                 &file,
1876                 plugindb,
1877                 "",
1878                 1);
1882 //file.dump();
1883         double start = edl->local_session->get_selectionstart();
1884         double end = edl->local_session->get_selectionend();
1885         double source_start = source->local_session->get_selectionstart();
1886         double source_end = source->local_session->get_selectionend();
1888         paste(start, 
1889                 start, 
1890                 &file,
1891                 edl->session->labels_follow_edits,
1892                 edl->session->plugins_follow_edits);
1894 // Position at end of clip
1895         edl->local_session->set_selectionstart(start + 
1896                 source_end - 
1897                 source_start);
1898         edl->local_session->set_selectionend(start + 
1899                 source_end - 
1900                 source_start);
1902         save_backup();
1903         undo->update_undo(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1904         update_plugin_guis();
1905         restart_brender();
1906         gui->update(1, 1, 1, 1, 0, 1, 0);
1907         sync_parameters(CHANGE_EDL);
1910 void MWindow::to_clip()
1912         FileXML file;
1913         double start, end;
1914         
1915         start = edl->local_session->get_selectionstart();
1916         end = edl->local_session->get_selectionend();
1918         if(EQUIV(end, start)) 
1919         {
1920                 start = 0;
1921                 end = edl->tracks->total_length();
1922         }
1924 // Don't copy all since we don't want the clips twice.
1925         edl->copy(start, 
1926                 end, 
1927                 0,
1928                 0,
1929                 0,
1930                 &file,
1931                 plugindb,
1932                 "",
1933                 1);
1936         EDL *new_edl = new EDL(edl);
1937         new_edl->create_objects();
1938         new_edl->load_xml(plugindb, &file, LOAD_ALL);
1939         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1940         new_edl->local_session->set_selectionstart(0);
1941         new_edl->local_session->set_selectionend(0);
1943         awindow->clip_edit->create_clip(new_edl);
1944         save_backup();
1947 class LabelUndoItem : public UndoStackItem
1949 public:
1950       LabelUndoItem(double position1, double position2, EDL *edl);
1951       void undo();
1952       int get_size();
1953 private:
1954       double position1;
1955       double position2;
1956       EDL *edl;
1959 LabelUndoItem::LabelUndoItem(
1960       double position1, double position2, EDL *edl)
1962    set_description(_("label"));
1963    this->position1 = position1;
1964    this->position2 = position2;
1965    this->edl = edl;
1968 void LabelUndoItem::undo()
1970         edl->labels->toggle_label(position1, position2);
1973 int LabelUndoItem::get_size()
1975    return 20;
1978 int MWindow::toggle_label(int is_mwindow)
1980    LabelUndoItem *undo_item;
1981         double position1, position2;
1983         if(cwindow->playback_engine->is_playing_back)
1984         {
1985                 position1 = position2 = 
1986                         cwindow->playback_engine->get_tracking_position();
1987         }
1988         else
1989         {
1990                 position1 = edl->local_session->get_selectionstart(1);
1991                 position2 = edl->local_session->get_selectionend(1);
1992         }
1994         position1 = edl->align_to_frame(position1, 0);
1995         position2 = edl->align_to_frame(position2, 0);
1997 //printf("MWindow::toggle_label 1\n");
1998    undo_item = new LabelUndoItem(position1, position2, edl);
1999    undo->push_undo_item(undo_item);
2001         edl->labels->toggle_label(position1, position2);
2002         save_backup();
2004         if(!is_mwindow)
2005         {
2006                 gui->lock_window("MWindow::toggle_label 1");
2007         }
2008         gui->timebar->update();
2009         gui->canvas->activate();
2010         gui->flush();
2011         if(!is_mwindow)
2012         {
2013                 gui->unlock_window();
2014         }
2016         if(is_mwindow)
2017         {
2018                 cwindow->gui->lock_window("MWindow::toggle_label 2");
2019         }
2020         cwindow->gui->timebar->update();
2021         cwindow->gui->flush();
2022         if(is_mwindow)
2023         {
2024                 cwindow->gui->unlock_window();
2025         }
2027         return 0;
2030 void MWindow::trim_selection()
2034         edl->trim_selection(edl->local_session->get_selectionstart(), 
2035                 edl->local_session->get_selectionend(), 
2036                 edl->session->labels_follow_edits, 
2037                 edl->session->plugins_follow_edits);
2039         save_backup();
2040         undo->update_undo(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
2041         update_plugin_guis();
2042         gui->update(1, 2, 1, 1, 1, 1, 0);
2043         restart_brender();
2044         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2045                                                         CHANGE_EDL,
2046                                                         edl,
2047                                                         1);
2052 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2054 //      if(is_mwindow)
2055 //              gui->unlock_window();
2056 //      else
2057 //              cwindow->gui->unlock_window();
2058         calling_window_gui->unlock_window();
2060         cwindow->playback_engine->que->send_command(STOP,
2061                 CHANGE_NONE, 
2062                 0,
2063                 0);
2064         vwindow->playback_engine->que->send_command(STOP,
2065                 CHANGE_NONE, 
2066                 0,
2067                 0);
2068         cwindow->playback_engine->interrupt_playback(0);
2069         vwindow->playback_engine->interrupt_playback(0);
2071         cwindow->gui->lock_window("MWindow::undo_entry 1");
2072         vwindow->gui->lock_window("MWindow::undo_entry 4");
2073         gui->lock_window("MWindow::undo_entry 2");
2075         undo->undo(); 
2077         save_backup();
2078         restart_brender();
2079         update_plugin_states();
2080         update_plugin_guis();
2081         gui->update(1, 2, 1, 1, 1, 1, 1);
2082         cwindow->update(1, 1, 1, 1, 1);
2084 //      if(is_mwindow)
2085 //              cwindow->gui->unlock_window();
2086 //      else
2087 //              gui->unlock_window();
2088         if (calling_window_gui != cwindow->gui) 
2089                 cwindow->gui->unlock_window();
2090         if (calling_window_gui != gui)
2091                 gui->unlock_window();
2092         if (calling_window_gui != vwindow->gui)
2093                 vwindow->gui->unlock_window();
2094         
2096         awindow->gui->lock_window("MWindow::undo_entry 3");
2097         awindow->gui->update_assets();
2098         awindow->gui->flush();
2099         awindow->gui->unlock_window();
2100         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2101                            CHANGE_ALL,
2102                            edl,
2103                            1);
2108 void MWindow::new_folder(char *new_folder)
2110         edl->new_folder(new_folder);
2111         undo->update_undo(_("new folder"), LOAD_ALL);
2112         awindow->gui->lock_window("MWindow::new_folder");
2113         awindow->gui->update_assets();
2114         awindow->gui->unlock_window();
2117 void MWindow::delete_folder(char *folder)
2119 //      undo->update_undo(_("delete folder"), LOAD_ALL);
2122 void MWindow::select_point(double position)
2124         edl->local_session->set_selectionstart(position);
2125         edl->local_session->set_selectionend(position);
2127 // Que the CWindow
2128         cwindow->update(1, 0, 0, 0, 1);
2129         update_plugin_guis();
2130         gui->patchbay->update();
2131         gui->cursor->hide(0);
2132         gui->cursor->draw(1);
2133         gui->mainclock->update(edl->local_session->get_selectionstart(1));
2134         gui->zoombar->update();
2135         gui->canvas->flash();
2136         gui->flush();