r885: Don't delete a borrowed frame.
[cinelerra_cv/ct.git] / cinelerra / mwindowedit.C
blob5028f9aa4b8c7e5b1ef0b65bdd47a49b8ea3a9e3
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 "mainerror.h"
27 #include "mainindexes.h"
28 #include "mainmenu.h"
29 #include "mainsession.h"
30 #include "mainundo.h"
31 #include "maskautos.h"
32 #include "mtimebar.h"
33 #include "mwindowgui.h"
34 #include "mwindow.h"
35 #include "panauto.h"
36 #include "patchbay.h"
37 #include "playbackengine.h"
38 #include "pluginset.h"
39 #include "recordlabel.h"
40 #include "samplescroll.h"
41 #include "trackcanvas.h"
42 #include "track.h"
43 #include "trackscroll.h"
44 #include "tracks.h"
45 #include "transition.h"
46 #include "transportque.h"
47 #include "units.h"
48 #include "undostackitem.h"
49 #include "vplayback.h"
50 #include "vwindow.h"
51 #include "vwindowgui.h"
52 #include "zoombar.h"
53 #include "automation.h"
54 #include "maskautos.h"
57 #include <string.h>
64 void MWindow::add_audio_track_entry(int above, Track *dst)
66         add_audio_track(above, dst);
67         save_backup();
68         undo->update_undo(_("add track"), LOAD_ALL);
70         restart_brender();
71         gui->get_scrollbars();
72         gui->canvas->draw();
73         gui->patchbay->update();
74         gui->cursor->draw(1);
75         gui->canvas->flash();
76         gui->canvas->activate();
77         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
78                 CHANGE_EDL,
79                 edl,
80                 1);
83 void MWindow::add_video_track_entry(Track *dst)
85         add_video_track(1, dst);
86         undo->update_undo(_("add track"), LOAD_ALL);
88         restart_brender();
89         gui->get_scrollbars();
90         gui->canvas->draw();
91         gui->patchbay->update();
92         gui->cursor->draw(1);
93         gui->canvas->flash();
94         gui->canvas->activate();
95         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
96                                                         CHANGE_EDL,
97                                                         edl,
98                                                         1);
99         save_backup();
103 int MWindow::add_audio_track(int above, Track *dst)
105         edl->tracks->add_audio_track(above, dst);
106         edl->tracks->update_y_pixels(theme);
107         save_backup();
108         return 0;
111 int MWindow::add_video_track(int above, Track *dst)
113         edl->tracks->add_video_track(above, dst);
114         edl->tracks->update_y_pixels(theme);
115         save_backup();
116         return 0;
123 void MWindow::asset_to_size()
125         if(session->drag_assets->total &&
126                 session->drag_assets->values[0]->video_data)
127         {
128                 int w, h;
130 // Get w and h
131                 w = session->drag_assets->values[0]->width;
132                 h = session->drag_assets->values[0]->height;
135                 edl->session->output_w = w;
136                 edl->session->output_h = h;
138                 if(((edl->session->output_w % 4) || 
139                         (edl->session->output_h % 4)) && 
140                         edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
141                 {
142                         MainError::show_error(
143                                 _("This project's dimensions are not multiples of 4 so\n"
144                                 "it can't be rendered by OpenGL."));
145                 }
148 // Get aspect ratio
149                 if(defaults->get("AUTOASPECT", 0))
150                 {
151                         create_aspect_ratio(edl->session->aspect_w, 
152                                 edl->session->aspect_h, 
153                                 w, 
154                                 h);
155                 }
157                 save_backup();
159                 undo->update_undo(_("asset to size"), LOAD_ALL);
160                 restart_brender();
161                 sync_parameters(CHANGE_ALL);
162         }
166 void MWindow::asset_to_rate()
168         if(session->drag_assets->total &&
169                 session->drag_assets->values[0]->video_data)
170         {
171                 double new_framerate = session->drag_assets->values[0]->frame_rate;
172                 double old_framerate = edl->session->frame_rate;
174                 edl->session->frame_rate = new_framerate;
175                 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
177                 save_backup();
179                 undo->update_undo(_("asset to rate"), LOAD_ALL);
180                 restart_brender();
181                 gui->update(1,
182                         2,
183                         1,
184                         1,
185                         1, 
186                         1,
187                         0);
188                 sync_parameters(CHANGE_ALL);
189         }
194 void MWindow::clear_entry()
196         clear(1);
198         edl->optimize();
199         save_backup();
200         undo->update_undo(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
202         restart_brender();
203         update_plugin_guis();
204         gui->update(1, 2, 1, 1, 1, 1, 0);
205         cwindow->update(1, 0, 0, 0, 1);
206         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
207                            CHANGE_EDL,
208                            edl,
209                            1);
212 void MWindow::clear(int clear_handle)
214         double start = edl->local_session->get_selectionstart();
215         double end = edl->local_session->get_selectionend();
216         if(clear_handle || !EQUIV(start, end))
217         {
218                 edl->clear(start, 
219                         end, 
220                         edl->session->labels_follow_edits, 
221                         edl->session->plugins_follow_edits);
222         }
225 void MWindow::straighten_automation()
227         edl->tracks->straighten_automation(
228                 edl->local_session->get_selectionstart(), 
229                 edl->local_session->get_selectionend()); 
230         save_backup();
231         undo->update_undo(_("straighten curves"), LOAD_AUTOMATION); 
233         restart_brender();
234         update_plugin_guis();
235         gui->canvas->draw_overlays();
236         gui->canvas->flash();
237         sync_parameters(CHANGE_PARAMS);
238         gui->patchbay->update();
239         cwindow->update(1, 0, 0);
242 void MWindow::clear_automation()
244         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
245                 edl->local_session->get_selectionend()); 
246         save_backup();
247         undo->update_undo(_("clear keyframes"), LOAD_AUTOMATION); 
249         restart_brender();
250         update_plugin_guis();
251         gui->canvas->draw_overlays();
252         gui->canvas->flash();
253         sync_parameters(CHANGE_PARAMS);
254         gui->patchbay->update();
255         cwindow->update(1, 0, 0);
258 int MWindow::clear_default_keyframe()
260         edl->tracks->clear_default_keyframe();
261         save_backup();
262         undo->update_undo(_("clear default keyframe"), LOAD_AUTOMATION);
263         
264         restart_brender();
265         gui->canvas->draw_overlays();
266         gui->canvas->flash();
267         sync_parameters(CHANGE_PARAMS);
268         gui->patchbay->update();
269         cwindow->update(1, 0, 0);
270         
271         return 0;
274 void MWindow::clear_labels()
276         clear_labels(edl->local_session->get_selectionstart(), 
277                 edl->local_session->get_selectionend()); 
278         undo->update_undo(_("clear labels"), LOAD_TIMEBAR);
279         
280         gui->timebar->update();
281         cwindow->update(0, 0, 0, 0, 1);
282         save_backup();
285 int MWindow::clear_labels(double start, double end)
287         edl->labels->clear(start, end, 0);
288         return 0;
291 void MWindow::concatenate_tracks()
293         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
294         save_backup();
295         undo->update_undo(_("concatenate tracks"), LOAD_EDITS);
297         restart_brender();
298         gui->update(1, 1, 0, 0, 1, 0, 0);
299         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
300                 CHANGE_EDL,
301                 edl,
302                 1);
306 void MWindow::copy()
308         copy(edl->local_session->get_selectionstart(), 
309                 edl->local_session->get_selectionend());
312 int MWindow::copy(double start, double end)
314         if(start == end) return 1;
316 //printf("MWindow::copy 1\n");
317         FileXML file;
318 //printf("MWindow::copy 1\n");
319         edl->copy(start, 
320                 end, 
321                 0,
322                 0,
323                 0,
324                 &file, 
325                 plugindb,
326                 "",
327                 1);
328 //printf("MWindow::copy 1\n");
330 // File is now terminated and rewound
332 //printf("MWindow::copy 1\n");
333         gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
334 //printf("MWindow::copy\n%s\n", file.string);
335 //printf("MWindow::copy 2\n");
336         save_backup();
337         return 0;
340 int MWindow::copy_automation()
342         FileXML file;
343         edl->tracks->copy_automation(edl->local_session->get_selectionstart(), 
344                 edl->local_session->get_selectionend(),
345                 &file,
346                 0,
347                 0); 
348         gui->get_clipboard()->to_clipboard(file.string, 
349                 strlen(file.string), 
350                 SECONDARY_SELECTION);
351         return 0;
354 int MWindow::copy_default_keyframe()
356         FileXML file;
357         edl->tracks->copy_default_keyframe(&file);
358         gui->get_clipboard()->to_clipboard(file.string,
359                 strlen(file.string),
360                 SECONDARY_SELECTION);
361         return 0;
365 // Uses cropping coordinates in edl session to crop and translate video.
366 // We modify the projector since camera automation depends on the track size.
367 void MWindow::crop_video()
370 // Clamp EDL crop region
371         if(edl->session->crop_x1 > edl->session->crop_x2)
372         {
373                 edl->session->crop_x1 ^= edl->session->crop_x2;
374                 edl->session->crop_x2 ^= edl->session->crop_x1;
375                 edl->session->crop_x1 ^= edl->session->crop_x2;
376         }
377         if(edl->session->crop_y1 > edl->session->crop_y2)
378         {
379                 edl->session->crop_y1 ^= edl->session->crop_y2;
380                 edl->session->crop_y2 ^= edl->session->crop_y1;
381                 edl->session->crop_y1 ^= edl->session->crop_y2;
382         }
384         float old_projector_x = (float)edl->session->output_w / 2;
385         float old_projector_y = (float)edl->session->output_h / 2;
386         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
387         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
388         float projector_offset_x = -(new_projector_x - old_projector_x);
389         float projector_offset_y = -(new_projector_y - old_projector_y);
391         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
393         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
394         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
395         edl->session->crop_x1 = 0;
396         edl->session->crop_y1 = 0;
397         edl->session->crop_x2 = edl->session->output_w;
398         edl->session->crop_y2 = edl->session->output_h;
400 // Recalculate aspect ratio
401         if(defaults->get("AUTOASPECT", 0))
402         {
403                 create_aspect_ratio(edl->session->aspect_w, 
404                         edl->session->aspect_h, 
405                         edl->session->output_w, 
406                         edl->session->output_h);
407         }
409         undo->update_undo(_("crop"), LOAD_ALL);
411         restart_brender();
412         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
413                 CHANGE_ALL,
414                 edl,
415                 1);
416         save_backup();
419 void MWindow::cut()
422         double start = edl->local_session->get_selectionstart();
423         double end = edl->local_session->get_selectionend();
425         copy(start, end);
426         edl->clear(start, 
427                 end,
428                 edl->session->labels_follow_edits, 
429                 edl->session->plugins_follow_edits);
432         edl->optimize();
433         save_backup();
434         undo->update_undo(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
436         restart_brender();
437         update_plugin_guis();
438         gui->update(1, 2, 1, 1, 1, 1, 0);
439         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
440                                                         CHANGE_EDL,
441                                                         edl,
442                                                         1);
445 int MWindow::cut_automation()
447         
448         copy_automation();
450         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
451                 edl->local_session->get_selectionend()); 
452         save_backup();
453         undo->update_undo(_("cut keyframes"), LOAD_AUTOMATION); 
456         restart_brender();
457         update_plugin_guis();
458         gui->canvas->draw_overlays();
459         gui->canvas->flash();
460         sync_parameters(CHANGE_PARAMS);
461         gui->patchbay->update();
462         cwindow->update(1, 0, 0);
463         return 0;
466 int MWindow::cut_default_keyframe()
469         copy_default_keyframe();
470         edl->tracks->clear_default_keyframe();
471         undo->update_undo(_("cut default keyframe"), LOAD_AUTOMATION);
473         restart_brender();
474         gui->canvas->draw_overlays();
475         gui->canvas->flash();
476         sync_parameters(CHANGE_PARAMS);
477         gui->patchbay->update();
478         cwindow->update(1, 0, 0);
479         save_backup();
482         return 0;
485 void MWindow::delete_inpoint()
487         edl->local_session->unset_inpoint();
488         save_backup();
491 void MWindow::delete_outpoint()
493         edl->local_session->unset_outpoint();
494         save_backup();
497 void MWindow::delete_track()
499         if (edl->tracks->last)
500                 delete_track(edl->tracks->last);
503 void MWindow::delete_tracks()
505         edl->tracks->delete_tracks();
506         undo->update_undo(_("delete tracks"), LOAD_ALL);
507         save_backup();
509         restart_brender();
510         update_plugin_states();
511         gui->update(1, 1, 1, 0, 1, 0, 0);
512         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
513                            CHANGE_EDL,
514                            edl,
515                            1);
518 void MWindow::delete_track(Track *track)
520         edl->tracks->delete_track(track);
521         undo->update_undo(_("delete track"), LOAD_ALL);
523         restart_brender();
524         update_plugin_states();
525         gui->update(1, 1, 1, 0, 1, 0, 0);
526         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
527                            CHANGE_EDL,
528                            edl,
529                            1);
530         save_backup();
533 void MWindow::detach_transition(Transition *transition)
535         hide_plugin(transition, 1);
536         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
537         transition->edit->detach_transition();
538         save_backup();
539         undo->update_undo(_("detach transition"), LOAD_ALL);
541         if(is_video) restart_brender();
542         gui->update(0,
543                 1,
544                 0,
545                 0,
546                 0, 
547                 0,
548                 0);
549         sync_parameters(CHANGE_EDL);
556 // Insert data from clipboard
557 void MWindow::insert(double position, 
558         FileXML *file,
559         int edit_labels,
560         int edit_plugins,
561         EDL *parent_edl)
563 // For clipboard pasting make the new edl use a separate session 
564 // from the master EDL.  Then it can be resampled to the master rates.
565 // For splice, overwrite, and dragging need same session to get the assets.
566         EDL edl(parent_edl);
567         ArrayList<EDL*> new_edls;
568         uint32_t load_flags = LOAD_ALL;
571         new_edls.append(&edl);
572         edl.create_objects();
577         if(parent_edl) load_flags &= ~LOAD_SESSION;
578         if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
579         if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
581         edl.load_xml(plugindb, file, load_flags);
588         paste_edls(&new_edls, 
589                 LOAD_PASTE, 
590                 0, 
591                 position,
592                 edit_labels,
593                 edit_plugins);
594 // if(vwindow->edl)
595 // printf("MWindow::insert 5 %f %f\n", 
596 // vwindow->edl->local_session->in_point,
597 // vwindow->edl->local_session->out_point);
598         new_edls.remove_all();
599 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
602 void MWindow::insert_effects_canvas(double start,
603         double length)
605         Track *dest_track = session->track_highlighted;
606         if(!dest_track) return;
609         for(int i = 0; i < session->drag_pluginservers->total; i++)
610         {
611                 PluginServer *plugin = session->drag_pluginservers->values[i];
613                 insert_effect(plugin->title,
614                         0,
615                         dest_track,
616                         i == 0 ? session->pluginset_highlighted : 0,
617                         start,
618                         length,
619                         PLUGIN_STANDALONE);
620         }
622         save_backup();
623         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
624         restart_brender();
625         sync_parameters(CHANGE_EDL);
626 // GUI updated in TrackCanvas, after current_operations are reset
629 void MWindow::insert_effects_cwindow(Track *dest_track)
631         if(!dest_track) return;
634         double start = 0;
635         double length = dest_track->get_length();
637         if(edl->local_session->get_selectionend() > 
638                 edl->local_session->get_selectionstart())
639         {
640                 start = edl->local_session->get_selectionstart();
641                 length = edl->local_session->get_selectionend() - 
642                         edl->local_session->get_selectionstart();
643         }
645         for(int i = 0; i < session->drag_pluginservers->total; i++)
646         {
647                 PluginServer *plugin = session->drag_pluginservers->values[i];
650                 insert_effect(plugin->title,
651                         0,
652                         dest_track,
653                         0,
654                         start,
655                         length,
656                         PLUGIN_STANDALONE);
657         }
659         save_backup();
660         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
661         restart_brender();
662         sync_parameters(CHANGE_EDL);
663         gui->update(1,
664                 1,
665                 0,
666                 0,
667                 1,
668                 0,
669                 0);
674 void MWindow::insert_effect(char *title, 
675         SharedLocation *shared_location, 
676         Track *track,
677         PluginSet *plugin_set,
678         double start,
679         double length,
680         int plugin_type)
682         KeyFrame *default_keyframe = 0;
683         PluginServer *server = 0;
690 // Get default keyframe
691         if(plugin_type == PLUGIN_STANDALONE)
692         {
693                 default_keyframe = new KeyFrame;
694                 server = new PluginServer(*scan_plugindb(title, track->data_type));
696                 server->open_plugin(0, preferences, edl, 0, -1);
697                 server->save_data(default_keyframe);
698         }
702 // Insert plugin object
703         track->insert_effect(title, 
704                 shared_location, 
705                 default_keyframe, 
706                 plugin_set,
707                 start,
708                 length,
709                 plugin_type);
711         track->optimize();
714         if(plugin_type == PLUGIN_STANDALONE)
715         {
716                 server->close_plugin();
717                 delete server;
718                 delete default_keyframe;
719         }
722 int MWindow::modify_edithandles()
725         edl->modify_edithandles(session->drag_start, 
726                 session->drag_position, 
727                 session->drag_handle, 
728                 edl->session->edit_handle_mode[session->drag_button],
729                 edl->session->labels_follow_edits, 
730                 edl->session->plugins_follow_edits);
732         finish_modify_handles();
735 //printf("MWindow::modify_handles 1\n");
736         return 0;
739 int MWindow::modify_pluginhandles()
742         edl->modify_pluginhandles(session->drag_start, 
743                 session->drag_position, 
744                 session->drag_handle, 
745                 edl->session->edit_handle_mode[session->drag_button],
746                 edl->session->labels_follow_edits,
747                 session->trim_edits);
749         finish_modify_handles();
751         return 0;
755 // Common to edithandles and plugin handles
756 void MWindow::finish_modify_handles()
758         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
760         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
761                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
762         {
763                 edl->local_session->set_selectionstart(session->drag_position);
764                 edl->local_session->set_selectionend(session->drag_position);
765         }
766         else
767         if(edit_mode != MOVE_NO_EDITS)
768         {
769                 edl->local_session->set_selectionstart(session->drag_start);
770                 edl->local_session->set_selectionend(session->drag_start);
771         }
773         if(edl->local_session->get_selectionstart(1) < 0)
774         {
775                 edl->local_session->set_selectionstart(0);
776                 edl->local_session->set_selectionend(0);
777         }
779         save_backup();
780         undo->update_undo(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
781         restart_brender();
782         sync_parameters(CHANGE_EDL);
783         update_plugin_guis();
784         gui->update(1, 2, 1, 1, 1, 1, 0);
785         cwindow->update(1, 0, 0, 0, 1);
788 void MWindow::match_output_size(Track *track)
790         track->track_w = edl->session->output_w;
791         track->track_h = edl->session->output_h;
792         save_backup();
793         undo->update_undo(_("match output size"), LOAD_ALL);
795         restart_brender();
796         sync_parameters(CHANGE_EDL);
800 void MWindow::move_edits(ArrayList<Edit*> *edits, 
801                 Track *track,
802                 double position,
803                 int behaviour)
806         edl->tracks->move_edits(edits, 
807                 track, 
808                 position,
809                 edl->session->labels_follow_edits, 
810                 edl->session->plugins_follow_edits,
811                 behaviour);
813         save_backup();
814         undo->update_undo(_("move edit"), LOAD_ALL);
816         restart_brender();
817         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
818                 CHANGE_EDL,
819                 edl,
820                 1);
822         update_plugin_guis();
823         gui->update(1,
824                 1,      // 1 for incremental drawing.  2 for full refresh
825                 1,
826                 0,
827                 0, 
828                 0,
829                 0);
832 void MWindow::move_effect(Plugin *plugin,
833         PluginSet *dest_plugin_set,
834         Track *dest_track,
835         int64_t dest_position)
838         edl->tracks->move_effect(plugin, 
839                 dest_plugin_set, 
840                 dest_track, 
841                 dest_position);
843         save_backup();
844         undo->update_undo(_("move effect"), LOAD_ALL);
846         restart_brender();
847         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
848                 CHANGE_EDL,
849                 edl,
850                 1);
852         update_plugin_guis();
853         gui->update(1,
854                 1,      // 1 for incremental drawing.  2 for full refresh
855                 0,
856                 0,
857                 0, 
858                 0,
859                 0);
862 void MWindow::move_plugins_up(PluginSet *plugin_set)
865         plugin_set->track->move_plugins_up(plugin_set);
867         save_backup();
868         undo->update_undo(_("move effect up"), LOAD_ALL);
869         restart_brender();
870         gui->update(1,
871                 1,      // 1 for incremental drawing.  2 for full refresh
872                 0,
873                 0,
874                 0, 
875                 0,
876                 0);
877         sync_parameters(CHANGE_EDL);
880 void MWindow::move_plugins_down(PluginSet *plugin_set)
883         plugin_set->track->move_plugins_down(plugin_set);
885         save_backup();
886         undo->update_undo(_("move effect down"), LOAD_ALL);
887         restart_brender();
888         gui->update(1,
889                 1,      // 1 for incremental drawing.  2 for full refresh
890                 0,
891                 0,
892                 0, 
893                 0,
894                 0);
895         sync_parameters(CHANGE_EDL);
898 void MWindow::move_track_down(Track *track)
900         edl->tracks->move_track_down(track);
901         save_backup();
902         undo->update_undo(_("move track 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_tracks_down()
912         edl->tracks->move_tracks_down();
913         save_backup();
914         undo->update_undo(_("move tracks down"), LOAD_ALL);
916         restart_brender();
917         gui->update(1, 1, 0, 0, 1, 0, 0);
918         sync_parameters(CHANGE_EDL);
919         save_backup();
922 void MWindow::move_track_up(Track *track)
924         edl->tracks->move_track_up(track);
925         save_backup();
926         undo->update_undo(_("move track up"), LOAD_ALL);
927         restart_brender();
928         gui->update(1, 1, 0, 0, 1, 0, 0);
929         sync_parameters(CHANGE_EDL);
930         save_backup();
933 void MWindow::move_tracks_up()
935         edl->tracks->move_tracks_up();
936         save_backup();
937         undo->update_undo(_("move tracks up"), LOAD_ALL);
938         restart_brender();
939         gui->update(1, 1, 0, 0, 1, 0, 0);
940         sync_parameters(CHANGE_EDL);
944 void MWindow::mute_selection()
946         double start = edl->local_session->get_selectionstart();
947         double end = edl->local_session->get_selectionend();
948         if(start != end)
949         {
950                 edl->clear(start, 
951                         end, 
952                         0, 
953                         edl->session->plugins_follow_edits);
954                 edl->local_session->set_selectionend(end);
955                 edl->local_session->set_selectionstart(start);
956                 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
957                 save_backup();
958                 undo->update_undo(_("mute"), LOAD_EDITS);
960                 restart_brender();
961                 update_plugin_guis();
962                 gui->update(1, 2, 1, 1, 1, 1, 0);
963                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
964                                                                 CHANGE_EDL,
965                                                                 edl,
966                                                                 1);
967         }
972 void MWindow::overwrite(EDL *source)
974         FileXML file;
976         double src_start = source->local_session->get_selectionstart();
977         double overwrite_len = source->local_session->get_selectionend() - src_start;
978         double dst_start = edl->local_session->get_selectionstart();
979         double dst_len = edl->local_session->get_selectionend() - dst_start;
981         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
982         {
983 // in/out points or selection present and shorter than overwrite range
984 // shorten the copy range
985                 overwrite_len = dst_len;
986         }
988         source->copy(src_start, 
989                 src_start + overwrite_len, 
990                 1,
991                 0,
992                 0,
993                 &file,
994                 plugindb,
995                 "",
996                 1);
998 // HACK around paste_edl get_start/endselection on its own
999 // so we need to clear only when not using both io points
1000 // FIXME: need to write simple overwrite_edl to be used for overwrite function
1001         if (edl->local_session->get_inpoint() < 0 || 
1002                 edl->local_session->get_outpoint() < 0)
1003                 edl->clear(dst_start, 
1004                         dst_start + overwrite_len, 
1005                         0, 
1006                         0);
1008         paste(dst_start, 
1009                 dst_start + overwrite_len, 
1010                 &file,
1011                 0,
1012                 0);
1014         edl->local_session->set_selectionstart(dst_start + overwrite_len);
1015         edl->local_session->set_selectionend(dst_start + overwrite_len);
1017         save_backup();
1018         undo->update_undo(_("overwrite"), LOAD_EDITS);
1020         restart_brender();
1021         update_plugin_guis();
1022         gui->update(1, 1, 1, 1, 0, 1, 0);
1023         sync_parameters(CHANGE_EDL);
1026 // For splice and overwrite
1027 int MWindow::paste(double start, 
1028         double end, 
1029         FileXML *file,
1030         int edit_labels,
1031         int edit_plugins)
1033         clear(0);
1035 // Want to insert with assets shared with the master EDL.
1036         insert(start, 
1037                         file,
1038                         edit_labels,
1039                         edit_plugins,
1040                         edl);
1042         return 0;
1045 // For editing use insertion point position
1046 void MWindow::paste()
1049         double start = edl->local_session->get_selectionstart();
1050         double end = edl->local_session->get_selectionend();
1051         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1053         if(len)
1054         {
1055                 char *string = new char[len + 1];
1059                 gui->get_clipboard()->from_clipboard(string, 
1060                         len, 
1061                         SECONDARY_SELECTION);
1062                 FileXML file;
1063                 file.read_from_string(string);
1068                 clear(0);
1070                 insert(start, 
1071                         &file, 
1072                         edl->session->labels_follow_edits, 
1073                         edl->session->plugins_follow_edits);
1075                 edl->optimize();
1078                 delete [] string;
1082                 save_backup();
1085                 undo->update_undo(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1086                 restart_brender();
1087                 update_plugin_guis();
1088                 gui->update(1, 2, 1, 1, 0, 1, 0);
1089                 awindow->gui->update_assets();
1090                 sync_parameters(CHANGE_EDL);
1091         }
1095 int MWindow::paste_assets(double position, Track *dest_track)
1097         int result = 0;
1102         if(session->drag_assets->total)
1103         {
1104                 load_assets(session->drag_assets, 
1105                         position, 
1106                         LOAD_PASTE,
1107                         dest_track, 
1108                         0,
1109                         edl->session->labels_follow_edits, 
1110                         edl->session->plugins_follow_edits);
1111                 result = 1;
1112         }
1115         if(session->drag_clips->total)
1116         {
1117                 paste_edls(session->drag_clips, 
1118                         LOAD_PASTE, 
1119                         dest_track,
1120                         position, 
1121                         edl->session->labels_follow_edits, 
1122                         edl->session->plugins_follow_edits);
1123                 result = 1;
1124         }
1127         save_backup();
1129         undo->update_undo(_("paste assets"), LOAD_EDITS);
1130         restart_brender();
1131         gui->update(1, 
1132                 2,
1133                 1,
1134                 0,
1135                 0,
1136                 1,
1137                 0);
1138         sync_parameters(CHANGE_EDL);
1139         return result;
1142 void MWindow::load_assets(ArrayList<Asset*> *new_assets, 
1143         double position, 
1144         int load_mode,
1145         Track *first_track,
1146         RecordLabels *labels,
1147         int edit_labels,
1148         int edit_plugins)
1150 //printf("MWindow::load_assets 1\n");
1151         if(position < 0) position = edl->local_session->get_selectionstart();
1153         ArrayList<EDL*> new_edls;
1154         for(int i = 0; i < new_assets->total; i++)
1155         {
1156                 remove_asset_from_caches(new_assets->values[i]);
1157                 EDL *new_edl = new EDL;
1158                 new_edl->create_objects();
1159                 new_edl->copy_session(edl);
1160                 new_edls.append(new_edl);
1163 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1164                 asset_to_edl(new_edl, new_assets->values[i]);
1167                 if(labels)
1168                         for(RecordLabel *label = labels->first; label; label = label->next)
1169                         {
1170                                 new_edl->labels->toggle_label(label->position, label->position);
1171                         }
1172         }
1173 //printf("MWindow::load_assets 3\n");
1175         paste_edls(&new_edls, 
1176                 load_mode, 
1177                 first_track,
1178                 position,
1179                 edit_labels,
1180                 edit_plugins);
1181 //printf("MWindow::load_assets 4\n");
1184         save_backup();
1185         new_edls.remove_all_objects();
1189 int MWindow::paste_automation()
1191         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1193         if(len)
1194         {
1195                 char *string = new char[len + 1];
1196                 gui->get_clipboard()->from_clipboard(string, 
1197                         len, 
1198                         SECONDARY_SELECTION);
1199                 FileXML file;
1200                 file.read_from_string(string);
1202                 edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
1203                         edl->local_session->get_selectionend()); 
1204                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(), 
1205                         &file,
1206                         0); 
1207                 save_backup();
1208                 undo->update_undo(_("paste keyframes"), LOAD_AUTOMATION);
1209                 delete [] string;
1212                 restart_brender();
1213                 update_plugin_guis();
1214                 gui->canvas->draw_overlays();
1215                 gui->canvas->flash();
1216                 sync_parameters(CHANGE_PARAMS);
1217                 gui->patchbay->update();
1218                 cwindow->update(1, 0, 0);
1219         }
1221         return 0;
1224 int MWindow::paste_default_keyframe()
1226         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1228         if(len)
1229         {
1230                 char *string = new char[len + 1];
1231                 gui->get_clipboard()->from_clipboard(string, 
1232                         len, 
1233                         SECONDARY_SELECTION);
1234                 FileXML file;
1235                 file.read_from_string(string);
1236                 edl->tracks->paste_default_keyframe(&file); 
1237                 undo->update_undo(_("paste default keyframe"), LOAD_AUTOMATION);
1240                 restart_brender();
1241                 update_plugin_guis();
1242                 gui->canvas->draw_overlays();
1243                 gui->canvas->flash();
1244                 sync_parameters(CHANGE_PARAMS);
1245                 gui->patchbay->update();
1246                 cwindow->update(1, 0, 0);
1247                 delete [] string;
1248                 save_backup();
1249         }
1251         return 0;
1255 // Insert edls with project deletion and index file generation.
1256 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, 
1257         int load_mode, 
1258         Track *first_track,
1259         double current_position,
1260         int edit_labels,
1261         int edit_plugins)
1264         ArrayList<Track*> destination_tracks;
1265         int need_new_tracks = 0;
1267         if(!new_edls->total) return 0;
1270 SET_TRACE
1271         double original_length = edl->tracks->total_playable_length();
1272 SET_TRACE
1273         double original_preview_end = edl->local_session->preview_end;
1274 SET_TRACE
1276 // Delete current project
1277         if(load_mode == LOAD_REPLACE ||
1278                 load_mode == LOAD_REPLACE_CONCATENATE)
1279         {
1280                 reset_caches();
1282                 edl->save_defaults(defaults);
1284                 hide_plugins();
1286                 delete edl;
1288                 edl = new EDL;
1290                 edl->create_objects();
1292                 edl->copy_session(new_edls->values[0]);
1294                 gui->mainmenu->update_toggles(0);
1297                 gui->unlock_window();
1299                 gwindow->gui->update_toggles(1);
1301                 gui->lock_window("MWindow::paste_edls");
1304 // Insert labels for certain modes constitutively
1305                 edit_labels = 1;
1306                 edit_plugins = 1;
1307 // Force reset of preview
1308                 original_length = 0;
1309                 original_preview_end = -1;
1310         }
1312 SET_TRACE
1315 SET_TRACE
1316 // Create new tracks in master EDL
1317         if(load_mode == LOAD_REPLACE || 
1318                 load_mode == LOAD_REPLACE_CONCATENATE ||
1319                 load_mode == LOAD_NEW_TRACKS)
1320         {
1322                 need_new_tracks = 1;
1323                 for(int i = 0; i < new_edls->total; i++)
1324                 {
1325                         EDL *new_edl = new_edls->values[i];
1326                         for(Track *current = new_edl->tracks->first;
1327                                 current;
1328                                 current = NEXT)
1329                         {
1330                                 if(current->data_type == TRACK_VIDEO)
1331                                 {
1332                                         edl->tracks->add_video_track(0, 0);
1333                                         if(current->draw) edl->tracks->last->draw = 1;
1334                                         destination_tracks.append(edl->tracks->last);
1335                                 }
1336                                 else
1337                                 if(current->data_type == TRACK_AUDIO)
1338                                 {
1339                                         edl->tracks->add_audio_track(0, 0);
1340                                         destination_tracks.append(edl->tracks->last);
1341                                 }
1342                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1343                         }
1345 // Base track count on first EDL only for concatenation
1346                         if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1347                 }
1349         }
1350         else
1351 // Recycle existing tracks of master EDL
1352         if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1353         {
1355 // The point of this is to shift forward labels after the selection so they can
1356 // then be shifted back to their original locations without recursively
1357 // shifting back every paste.
1358                 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1359                         edl->labels->clear(edl->local_session->get_selectionstart(),
1360                                                 edl->local_session->get_selectionend(),
1361                                                 1);
1362         
1363                 Track *current = first_track ? first_track : edl->tracks->first;
1364                 for( ; current; current = NEXT)
1365                 {
1366                         if(current->record)
1367                         {
1368                                 destination_tracks.append(current);
1370 // This should be done in the caller so we don't get recursive clear disease.
1371 //                              if(load_mode == LOAD_PASTE)
1372 //                                      current->clear(edl->local_session->get_selectionstart(),
1373 //                                              edl->local_session->get_selectionend(),
1374 //                                              1,
1375 //                                              edl->session->labels_follow_edits, 
1376 //                                              edl->session->plugins_follow_edits,
1377 //                                              1);
1378                         }
1379                 }
1381         }
1386         int destination_track = 0;
1387         double *paste_position = new double[destination_tracks.total];
1391 SET_TRACE
1394 // Iterate through the edls
1395         for(int i = 0; i < new_edls->total; i++)
1396         {
1398                 EDL *new_edl = new_edls->values[i];
1399 SET_TRACE
1400                 double edl_length = new_edl->local_session->clipboard_length ?
1401                         new_edl->local_session->clipboard_length :
1402                         new_edl->tracks->total_length();
1403 // printf("MWindow::paste_edls 2\n");
1404 // new_edl->dump();
1406 SET_TRACE
1410 // Resample EDL to master rates
1411                 new_edl->resample(new_edl->session->sample_rate, 
1412                         edl->session->sample_rate, 
1413                         TRACK_AUDIO);
1414                 new_edl->resample(new_edl->session->frame_rate, 
1415                         edl->session->frame_rate, 
1416                         TRACK_VIDEO);
1418 SET_TRACE
1422 // Add assets and prepare index files
1423                 for(Asset *new_asset = new_edl->assets->first;
1424                         new_asset;
1425                         new_asset = new_asset->next)
1426                 {
1427                         mainindexes->add_next_asset(0, new_asset);
1428                 }
1429 SET_TRACE
1430 // Capture index file status from mainindex test
1431                 edl->update_assets(new_edl);
1433 SET_TRACE
1436 // Get starting point of insertion.  Need this to paste labels.
1437                 switch(load_mode)
1438                 {
1439                         case LOAD_REPLACE:
1440                         case LOAD_NEW_TRACKS:
1441                                 current_position = 0;
1442                                 break;
1444                         case LOAD_CONCATENATE:
1445                         case LOAD_REPLACE_CONCATENATE:
1446                                 destination_track = 0;
1447                                 if(destination_tracks.total)
1448                                         current_position = destination_tracks.values[0]->get_length();
1449                                 else
1450                                         current_position = 0;
1451                                 break;
1453                         case LOAD_PASTE:
1454                                 destination_track = 0;
1455                                 if(i == 0)
1456                                 {
1457                                         for(int j = 0; j < destination_tracks.total; j++)
1458                                         {
1459                                                 paste_position[j] = (current_position >= 0) ? 
1460                                                         current_position :
1461                                                         edl->local_session->get_selectionstart();
1462                                         }
1463                                 }
1464                                 break;
1466                         case LOAD_RESOURCESONLY:
1467                                 edl->add_clip(new_edl);
1468                                 break;
1469                 }
1474 SET_TRACE
1476 // Insert edl
1477                 if(load_mode != LOAD_RESOURCESONLY)
1478                 {
1479 // Insert labels
1480 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1481                         if(load_mode == LOAD_PASTE)
1482                                 edl->labels->insert_labels(new_edl->labels, 
1483                                         destination_tracks.total ? paste_position[0] : 0.0,
1484                                         edl_length,
1485                                         edit_labels);
1486                         else
1487                                 edl->labels->insert_labels(new_edl->labels, 
1488                                         current_position,
1489                                         edl_length,
1490                                         edit_labels);
1492                         for(Track *new_track = new_edl->tracks->first; 
1493                                 new_track; 
1494                                 new_track = new_track->next)
1495                         {
1496 // Get destination track of same type as new_track
1497                                 for(int k = 0; 
1498                                         k < destination_tracks.total &&
1499                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1500                                         k++, destination_track++)
1501                                 {
1502                                         if(destination_track >= destination_tracks.total - 1)
1503                                                 destination_track = 0;
1504                                 }
1506 // Insert data into destination track
1507                                 if(destination_track < destination_tracks.total &&
1508                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1509                                 {
1510                                         Track *track = destination_tracks.values[destination_track];
1512 // Replace default keyframes if first EDL and new tracks were created.
1513 // This means data copied from one track and pasted to another won't retain
1514 // the camera position unless it's a keyframe.  If it did, previous data in the
1515 // track might get unknowingly corrupted.  Ideally we would detect when differing
1516 // default keyframes existed and create discrete keyframes for both.
1517                                         int replace_default = (i == 0) && need_new_tracks;
1519 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1520 // Insert new track at current position
1521                                         switch(load_mode)
1522                                         {
1523                                                 case LOAD_REPLACE_CONCATENATE:
1524                                                 case LOAD_CONCATENATE:
1525                                                         current_position = track->get_length();
1526                                                         break;
1528                                                 case LOAD_PASTE:
1529                                                         current_position = paste_position[destination_track];
1530                                                         paste_position[destination_track] += new_track->get_length();
1531                                                         break;
1532                                         }
1534                                         track->insert_track(new_track, 
1535                                                 current_position, 
1536                                                 replace_default,
1537                                                 edit_plugins);
1538                                 }
1540 // Get next destination track
1541                                 destination_track++;
1542                                 if(destination_track >= destination_tracks.total)
1543                                         destination_track = 0;
1544                         }
1545                 }
1547 SET_TRACE
1548                 if(load_mode == LOAD_PASTE)
1549                         current_position += edl_length;
1550         }
1553 // Move loading of clips and vwindow to the end - this fixes some
1554 // strange issue, for index not being shown
1555 // Assume any paste operation from the same EDL won't contain any clips.
1556 // If it did it would duplicate every clip here.
1557         for(int i = 0; i < new_edls->total; i++)
1558         {
1559                 EDL *new_edl = new_edls->values[i];
1561                 for(int j = 0; j < new_edl->clips.total; j++)
1562                 {
1563                         edl->add_clip(new_edl->clips.values[j]);
1564                 }
1566                 if(new_edl->vwindow_edl)
1567                 {
1568                         if(edl->vwindow_edl) delete edl->vwindow_edl;
1569                         edl->vwindow_edl = new EDL(edl);
1570                         edl->vwindow_edl->create_objects();
1571                         edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1572                 }
1573         }
1576 SET_TRACE
1577         if(paste_position) delete [] paste_position;
1580 SET_TRACE
1581 // This is already done in load_filenames and everything else that uses paste_edls
1582 //      update_project(load_mode);
1584 // Fix preview range
1585         if(EQUIV(original_length, original_preview_end))
1586         {
1587                 edl->local_session->preview_end = edl->tracks->total_playable_length();
1588         }
1591 SET_TRACE
1592 // Start examining next batch of index files
1593         mainindexes->start_build();
1594 SET_TRACE
1597 // Don't save a backup after loading since the loaded file is on disk already.
1600         return 0;
1603 void MWindow::paste_silence()
1605         double start = edl->local_session->get_selectionstart();
1606         double end = edl->local_session->get_selectionend();
1607         edl->paste_silence(start, 
1608                 end, 
1609                 edl->session->labels_follow_edits, 
1610                 edl->session->plugins_follow_edits);
1611         edl->optimize();
1612         save_backup();
1613         undo->update_undo(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1615         update_plugin_guis();
1616         restart_brender();
1617         gui->update(1, 2, 1, 1, 1, 1, 0);
1618         cwindow->update(1, 0, 0, 0, 1);
1619         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1620                                                         CHANGE_EDL,
1621                                                         edl,
1622                                                         1);
1625 void MWindow::paste_transition()
1627 // Only the first transition gets dropped.
1628         PluginServer *server = session->drag_pluginservers->values[0];
1629         if(server->audio)
1630                 strcpy(edl->session->default_atransition, server->title);
1631         else
1632                 strcpy(edl->session->default_vtransition, server->title);
1634         edl->tracks->paste_transition(server, session->edit_highlighted);
1635         save_backup();
1636         undo->update_undo(_("transition"), LOAD_EDITS);
1638         if(server->video) restart_brender();
1639         sync_parameters(CHANGE_ALL);
1642 void MWindow::paste_transition_cwindow(Track *dest_track)
1644         PluginServer *server = session->drag_pluginservers->values[0];
1645         edl->tracks->paste_video_transition(server, 1);
1646         save_backup();
1647         undo->update_undo(_("transition"), LOAD_EDITS);
1648         restart_brender();
1649         gui->update(0, 1, 0, 0, 0, 0, 0);
1650         sync_parameters(CHANGE_ALL);
1653 void MWindow::paste_audio_transition()
1655         PluginServer *server = scan_plugindb(edl->session->default_atransition,
1656                 TRACK_AUDIO);
1657         if(!server)
1658         {
1659                 char string[BCTEXTLEN];
1660                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1661                 gui->show_message(string);
1662                 return;
1663         }
1665         edl->tracks->paste_audio_transition(server);
1666         save_backup();
1667         undo->update_undo(_("transition"), LOAD_EDITS);
1669         sync_parameters(CHANGE_ALL);
1670         gui->update(0, 1, 0, 0, 0, 0, 0);
1673 void MWindow::paste_video_transition()
1675         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1676                 TRACK_VIDEO);
1677         if(!server)
1678         {
1679                 char string[BCTEXTLEN];
1680                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1681                 gui->show_message(string);
1682                 return;
1683         }
1686         edl->tracks->paste_video_transition(server);
1687         save_backup();
1688         undo->update_undo(_("transition"), LOAD_EDITS);
1690         sync_parameters(CHANGE_ALL);
1691         restart_brender();
1692         gui->update(0, 1, 0, 0, 0, 0, 0);
1696 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1699         calling_window_gui->unlock_window();
1701         cwindow->playback_engine->que->send_command(STOP,
1702                 CHANGE_NONE, 
1703                 0,
1704                 0);
1705         vwindow->playback_engine->que->send_command(STOP,
1706                 CHANGE_NONE, 
1707                 0,
1708                 0);
1709         cwindow->playback_engine->interrupt_playback(0);
1710         vwindow->playback_engine->interrupt_playback(0);
1713         cwindow->gui->lock_window("MWindow::redo_entry");
1714         vwindow->gui->lock_window("MWindow::undo_entry 2");
1715         gui->lock_window();
1717         undo->redo(); 
1719         save_backup();
1720         update_plugin_states();
1721         update_plugin_guis();
1722         restart_brender();
1723         gui->update(1, 2, 1, 1, 1, 1, 1);
1724         cwindow->update(1, 1, 1, 1, 1);
1726         if (calling_window_gui != cwindow->gui) 
1727                 cwindow->gui->unlock_window();
1728         if (calling_window_gui != gui)
1729                 gui->unlock_window();
1730         if (calling_window_gui != vwindow->gui)
1731                 vwindow->gui->unlock_window();
1733         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1734                            CHANGE_ALL,
1735                            edl,
1736                            1);
1737         
1741 void MWindow::resize_track(Track *track, int w, int h)
1743 // We have to move all maskpoints so they do not move in relation to image areas
1744         ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1745                 (w - track->track_w) / 2, 
1746                 (h - track->track_h) / 2);
1747         track->track_w = w;
1748         track->track_h = h;
1749         undo->update_undo(_("resize track"), LOAD_ALL);
1750         save_backup();
1752         restart_brender();
1753         sync_parameters(CHANGE_EDL);
1757 class InPointUndoItem : public UndoStackItem
1759 public:
1760         InPointUndoItem(double old_position, double new_position, EDL *edl);
1761         void undo();
1762         int get_size();
1763 private:
1764         double old_position;
1765         double new_position;
1766         EDL *edl;
1769 InPointUndoItem::InPointUndoItem(
1770       double old_position, double new_position, EDL *edl)
1772    set_description(_("in point"));
1773    this->old_position = old_position;
1774    this->new_position = new_position;
1775    this->edl = edl;
1778 void InPointUndoItem::undo()
1780    edl->set_inpoint(old_position);
1781 // prepare to undo the undo
1782         double tmp = new_position;
1783         new_position = old_position;
1784         old_position = tmp;
1787 int InPointUndoItem::get_size()
1789    return 20;
1792 void MWindow::set_inpoint(int is_mwindow)
1794    InPointUndoItem *undo_item;
1796    undo_item = new InPointUndoItem(edl->local_session->get_inpoint(),
1797          edl->local_session->get_selectionstart(1), edl);
1798    undo->push_undo_item(undo_item);
1800         edl->set_inpoint(edl->local_session->get_selectionstart(1));
1801         save_backup();
1803         if(!is_mwindow)
1804         {
1805                 gui->lock_window("MWindow::set_inpoint 1");
1806         }
1807         gui->timebar->update();
1808         gui->flush();
1809         if(!is_mwindow)
1810         {
1811                 gui->unlock_window();
1812         }
1814         if(is_mwindow)
1815         {
1816                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1817         }
1818         cwindow->gui->timebar->update();
1819         cwindow->gui->flush();
1820         if(is_mwindow)
1821         {
1822                 cwindow->gui->unlock_window();
1823         }
1826 class OutPointUndoItem : public UndoStackItem
1828 public:
1829         OutPointUndoItem(double old_position, double new_position, EDL *edl);
1830         void undo();
1831         int get_size();
1832 private:
1833         double old_position;
1834         double new_position;
1835         EDL *edl;
1838 OutPointUndoItem::OutPointUndoItem(
1839       double old_position, double new_position, EDL *edl)
1841    set_description(_("out point"));
1842    this->old_position = old_position;
1843    this->new_position = new_position;
1844    this->edl = edl;
1847 void OutPointUndoItem::undo()
1849    edl->set_outpoint(old_position);
1850 // prepare to undo the undo
1851         double tmp = new_position;
1852         new_position = old_position;
1853         old_position = tmp;
1856 int OutPointUndoItem::get_size()
1858    return 20;
1861 void MWindow::set_outpoint(int is_mwindow)
1863    OutPointUndoItem *undo_item;
1865    undo_item = new OutPointUndoItem(edl->local_session->get_outpoint(),
1866          edl->local_session->get_selectionend(1), edl);
1867    undo->push_undo_item(undo_item);
1869         edl->set_outpoint(edl->local_session->get_selectionend(1));
1870         save_backup();
1872         if(!is_mwindow)
1873         {
1874                 gui->lock_window("MWindow::set_outpoint 1");
1875         }
1876         gui->timebar->update();
1877         gui->flush();
1878         if(!is_mwindow)
1879         {
1880                 gui->unlock_window();
1881         }
1883         if(is_mwindow)
1884         {
1885                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1886         }
1887         cwindow->gui->timebar->update();
1888         cwindow->gui->flush();
1889         if(is_mwindow)
1890         {
1891                 cwindow->gui->unlock_window();
1892         }
1895 void MWindow::splice(EDL *source)
1897         FileXML file;
1899         source->copy(source->local_session->get_selectionstart(), 
1900                 source->local_session->get_selectionend(), 
1901                 1,
1902                 0,
1903                 0,
1904                 &file,
1905                 plugindb,
1906                 "",
1907                 1);
1911 //file.dump();
1912         double start = edl->local_session->get_selectionstart();
1913         double end = edl->local_session->get_selectionend();
1914         double source_start = source->local_session->get_selectionstart();
1915         double source_end = source->local_session->get_selectionend();
1917         paste(start, 
1918                 start, 
1919                 &file,
1920                 edl->session->labels_follow_edits,
1921                 edl->session->plugins_follow_edits);
1923 // Position at end of clip
1924         edl->local_session->set_selectionstart(start + 
1925                 source_end - 
1926                 source_start);
1927         edl->local_session->set_selectionend(start + 
1928                 source_end - 
1929                 source_start);
1931         save_backup();
1932         undo->update_undo(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1933         update_plugin_guis();
1934         restart_brender();
1935         gui->update(1, 1, 1, 1, 0, 1, 0);
1936         sync_parameters(CHANGE_EDL);
1939 void MWindow::to_clip()
1941         FileXML file;
1942         double start, end;
1943         
1944         start = edl->local_session->get_selectionstart();
1945         end = edl->local_session->get_selectionend();
1947         if(EQUIV(end, start)) 
1948         {
1949                 start = 0;
1950                 end = edl->tracks->total_length();
1951         }
1953 // Don't copy all since we don't want the clips twice.
1954         edl->copy(start, 
1955                 end, 
1956                 0,
1957                 0,
1958                 0,
1959                 &file,
1960                 plugindb,
1961                 "",
1962                 1);
1965         EDL *new_edl = new EDL(edl);
1966         new_edl->create_objects();
1967         new_edl->load_xml(plugindb, &file, LOAD_ALL);
1968         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1969         new_edl->local_session->set_selectionstart(0);
1970         new_edl->local_session->set_selectionend(0);
1972         awindow->clip_edit->create_clip(new_edl);
1973         save_backup();
1976 class LabelUndoItem : public UndoStackItem
1978 public:
1979       LabelUndoItem(double position1, double position2, EDL *edl);
1980       void undo();
1981       int get_size();
1982 private:
1983       double position1;
1984       double position2;
1985       EDL *edl;
1988 LabelUndoItem::LabelUndoItem(
1989       double position1, double position2, EDL *edl)
1991    set_description(_("label"));
1992    this->position1 = position1;
1993    this->position2 = position2;
1994    this->edl = edl;
1997 void LabelUndoItem::undo()
1999         edl->labels->toggle_label(position1, position2);
2002 int LabelUndoItem::get_size()
2004    return 20;
2007 int MWindow::toggle_label(int is_mwindow)
2009    LabelUndoItem *undo_item;
2010         double position1, position2;
2012         if(cwindow->playback_engine->is_playing_back)
2013         {
2014                 position1 = position2 = 
2015                         cwindow->playback_engine->get_tracking_position();
2016         }
2017         else
2018         {
2019                 position1 = edl->local_session->get_selectionstart(1);
2020                 position2 = edl->local_session->get_selectionend(1);
2021         }
2023         position1 = edl->align_to_frame(position1, 0);
2024         position2 = edl->align_to_frame(position2, 0);
2026 //printf("MWindow::toggle_label 1\n");
2027    undo_item = new LabelUndoItem(position1, position2, edl);
2028    undo->push_undo_item(undo_item);
2030         edl->labels->toggle_label(position1, position2);
2031         save_backup();
2033         if(!is_mwindow)
2034         {
2035                 gui->lock_window("MWindow::toggle_label 1");
2036         }
2037         gui->timebar->update();
2038         gui->canvas->activate();
2039         gui->flush();
2040         if(!is_mwindow)
2041         {
2042                 gui->unlock_window();
2043         }
2045         if(is_mwindow)
2046         {
2047                 cwindow->gui->lock_window("MWindow::toggle_label 2");
2048         }
2049         cwindow->gui->timebar->update();
2050         cwindow->gui->flush();
2051         if(is_mwindow)
2052         {
2053                 cwindow->gui->unlock_window();
2054         }
2056         return 0;
2059 void MWindow::trim_selection()
2063         edl->trim_selection(edl->local_session->get_selectionstart(), 
2064                 edl->local_session->get_selectionend(), 
2065                 edl->session->labels_follow_edits, 
2066                 edl->session->plugins_follow_edits);
2068         save_backup();
2069         undo->update_undo(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
2070         update_plugin_guis();
2071         gui->update(1, 2, 1, 1, 1, 1, 0);
2072         restart_brender();
2073         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2074                                                         CHANGE_EDL,
2075                                                         edl,
2076                                                         1);
2081 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2083 //      if(is_mwindow)
2084 //              gui->unlock_window();
2085 //      else
2086 //              cwindow->gui->unlock_window();
2087         calling_window_gui->unlock_window();
2089         cwindow->playback_engine->que->send_command(STOP,
2090                 CHANGE_NONE, 
2091                 0,
2092                 0);
2093         vwindow->playback_engine->que->send_command(STOP,
2094                 CHANGE_NONE, 
2095                 0,
2096                 0);
2097         cwindow->playback_engine->interrupt_playback(0);
2098         vwindow->playback_engine->interrupt_playback(0);
2100         cwindow->gui->lock_window("MWindow::undo_entry 1");
2101         vwindow->gui->lock_window("MWindow::undo_entry 4");
2102         gui->lock_window("MWindow::undo_entry 2");
2104         undo->undo(); 
2106         save_backup();
2107         restart_brender();
2108         update_plugin_states();
2109         update_plugin_guis();
2110         gui->update(1, 2, 1, 1, 1, 1, 1);
2111         cwindow->update(1, 1, 1, 1, 1);
2113 //      if(is_mwindow)
2114 //              cwindow->gui->unlock_window();
2115 //      else
2116 //              gui->unlock_window();
2117         if (calling_window_gui != cwindow->gui) 
2118                 cwindow->gui->unlock_window();
2119         if (calling_window_gui != gui)
2120                 gui->unlock_window();
2121         if (calling_window_gui != vwindow->gui)
2122                 vwindow->gui->unlock_window();
2123         
2125         awindow->gui->lock_window("MWindow::undo_entry 3");
2126         awindow->gui->update_assets();
2127         awindow->gui->flush();
2128         awindow->gui->unlock_window();
2129         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2130                            CHANGE_ALL,
2131                            edl,
2132                            1);
2137 void MWindow::new_folder(char *new_folder)
2139         edl->new_folder(new_folder);
2140         undo->update_undo(_("new folder"), LOAD_ALL);
2141         awindow->gui->lock_window("MWindow::new_folder");
2142         awindow->gui->update_assets();
2143         awindow->gui->unlock_window();
2146 void MWindow::delete_folder(char *folder)
2148 //      undo->update_undo(_("delete folder"), LOAD_ALL);
2151 void MWindow::select_point(double position)
2153         edl->local_session->set_selectionstart(position);
2154         edl->local_session->set_selectionend(position);
2156 // Que the CWindow
2157         cwindow->update(1, 0, 0, 0, 1);
2158         update_plugin_guis();
2159         gui->patchbay->update();
2160         gui->cursor->hide(0);
2161         gui->cursor->draw(1);
2162         gui->mainclock->update(edl->local_session->get_selectionstart(1));
2163         gui->zoombar->update();
2164         gui->canvas->flash();
2165         gui->flush();
2171 void MWindow::map_audio(int pattern)
2173         int current_channel = 0;
2174         int current_track = 0;
2175         for(Track *current = edl->tracks->first; current; current = NEXT)
2176         {
2177                 if(current->data_type == TRACK_AUDIO && 
2178                         current->record)
2179                 {
2180                         Autos *pan_autos = current->automation->autos[AUTOMATION_PAN];
2181                         PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1);
2183                         for(int i = 0; i < MAXCHANNELS; i++)
2184                         {
2185                                 pan_auto->values[i] = 0.0;
2186                         }
2188                         if(pattern == MWindow::AUDIO_1_TO_1)
2189                         {
2190                                 pan_auto->values[current_channel] = 1.0;
2191                         }
2192                         else
2193                         if(pattern == MWindow::AUDIO_5_1_TO_2)
2194                         {
2195                                 switch(current_track)
2196                                 {
2197                                         case 0:
2198                                                 pan_auto->values[0] = 0.5;
2199                                                 pan_auto->values[1] = 0.5;
2200                                                 break;
2201                                         case 1:
2202                                                 pan_auto->values[0] = 1;
2203                                                 break;
2204                                         case 2:
2205                                                 pan_auto->values[1] = 1;
2206                                                 break;
2207                                         case 3:
2208                                                 pan_auto->values[0] = 1;
2209                                                 break;
2210                                         case 4:
2211                                                 pan_auto->values[1] = 1;
2212                                                 break;
2213                                         case 5:
2214                                                 pan_auto->values[0] = 0.5;
2215                                                 pan_auto->values[1] = 0.5;
2216                                                 break;
2217                                 }
2218                         }
2219                         
2220                         BC_Pan::calculate_stick_position(edl->session->audio_channels, 
2221                                 edl->session->achannel_positions, 
2222                                 pan_auto->values, 
2223                                 MAX_PAN, 
2224                                 PAN_RADIUS,
2225                                 pan_auto->handle_x,
2226                                 pan_auto->handle_y);
2227                 
2228                         current_channel++;
2229                         current_track++;
2230                         if(current_channel >= edl->session->audio_channels)
2231                                 current_channel = 0;
2232                 }
2233         }
2234         undo->update_undo(_("map 1:1"), LOAD_AUTOMATION, 0);
2235         sync_parameters(CHANGE_PARAMS);
2236         gui->update(0,
2237                 1,
2238                 0,
2239                 0,
2240                 1,
2241                 0,
2242                 0);