remove whitespace at eol
[goodguy/history.git] / cinelerra-5.1 / cinelerra / mwindowedit.C
1 /*
2  * CINELERRA
3  * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "asset.h"
22 #include "assets.h"
23 #include "awindowgui.h"
24 #include "awindow.h"
25 #include "bcsignals.h"
26 #include "cache.h"
27 #include "clip.h"
28 #include "clipedit.h"
29 #include "commercials.h"
30 #include "cplayback.h"
31 #include "ctimebar.h"
32 #include "cwindow.h"
33 #include "cwindowgui.h"
34 #include "bchash.h"
35 #include "edl.h"
36 #include "edlsession.h"
37 #include "filexml.h"
38 #include "floatauto.h"
39 #include "floatautos.h"
40 #include "gwindow.h"
41 #include "gwindowgui.h"
42 #include "keyframe.h"
43 #include "language.h"
44 #include "labels.h"
45 #include "levelwindow.h"
46 #include "localsession.h"
47 #include "mainclock.h"
48 #include "maincursor.h"
49 #include "mainerror.h"
50 #include "mainindexes.h"
51 #include "mainmenu.h"
52 #include "mainsession.h"
53 #include "mainundo.h"
54 #include "maskautos.h"
55 #include "mtimebar.h"
56 #include "mwindowgui.h"
57 #include "mwindow.h"
58 #include "panauto.h"
59 #include "patchbay.h"
60 #include "playbackengine.h"
61 #include "pluginset.h"
62 #include "recordlabel.h"
63 #include "samplescroll.h"
64 #include "trackcanvas.h"
65 #include "track.h"
66 #include "trackscroll.h"
67 #include "tracks.h"
68 #include "transition.h"
69 #include "transportque.h"
70 #include "units.h"
71 #include "undostackitem.h"
72 #include "vplayback.h"
73 #include "vwindow.h"
74 #include "vwindowgui.h"
75 #include "zoombar.h"
76 #include "automation.h"
77 #include "maskautos.h"
78
79
80 #include <string.h>
81
82
83
84
85
86
87 void MWindow::add_audio_track_entry(int above, Track *dst)
88 {
89         undo->update_undo_before();
90         add_audio_track(above, dst);
91         save_backup();
92         undo->update_undo_after(_("add track"), LOAD_ALL);
93
94         restart_brender();
95         gui->update(1,
96                 1,
97                 0,
98                 0,
99                 1,
100                 0,
101                 0);
102         gui->activate_timeline();
103
104 //      gui->get_scrollbars(0);
105 //      gui->canvas->draw();
106 //      gui->patchbay->update();
107 //      gui->cursor->draw(1);
108 //      gui->canvas->flash();
109 //      gui->canvas->activate();
110         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
111                 CHANGE_EDL,
112                 edl,
113                 1);
114 }
115
116 void MWindow::add_video_track_entry(Track *dst)
117 {
118         undo->update_undo_before();
119         add_video_track(1, dst);
120         undo->update_undo_after(_("add track"), LOAD_ALL);
121
122         restart_brender();
123
124         gui->update(1, 1, 0, 0, 1, 0, 0);
125         gui->activate_timeline();
126 //      gui->get_scrollbars(0);
127 //      gui->canvas->draw();
128 //      gui->patchbay->update();
129 //      gui->cursor->draw(1);
130 //      gui->canvas->flash();
131 //      gui->canvas->activate();
132         cwindow->playback_engine->que->
133                 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
134         save_backup();
135 }
136
137 void MWindow::add_subttl_track_entry(Track *dst)
138 {
139         undo->update_undo_before();
140         add_subttl_track(1, dst);
141         undo->update_undo_after(_("add track"), LOAD_ALL);
142
143         restart_brender();
144
145         gui->update(1, 1, 0, 0, 1, 0, 0);
146         gui->activate_timeline();
147 //      gui->get_scrollbars(0);
148 //      gui->canvas->draw();
149 //      gui->patchbay->update();
150 //      gui->cursor->draw(1);
151 //      gui->canvas->flash();
152 //      gui->canvas->activate();
153         cwindow->playback_engine->que->
154                 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
155         save_backup();
156 }
157
158
159 int MWindow::add_audio_track(int above, Track *dst)
160 {
161         edl->tracks->add_audio_track(above, dst);
162         edl->tracks->update_y_pixels(theme);
163         save_backup();
164         return 0;
165 }
166
167 int MWindow::add_video_track(int above, Track *dst)
168 {
169         edl->tracks->add_video_track(above, dst);
170         edl->tracks->update_y_pixels(theme);
171         save_backup();
172         return 0;
173 }
174
175 int MWindow::add_subttl_track(int above, Track *dst)
176 {
177         edl->tracks->add_subttl_track(above, dst);
178         edl->tracks->update_y_pixels(theme);
179         save_backup();
180         return 0;
181 }
182
183
184
185
186 void MWindow::asset_to_all()
187 {
188         if(!session->drag_assets->size()) return;
189         Indexable *indexable = session->drag_assets->get(0);
190
191 //      if(indexable->have_video())
192         {
193                 int w, h;
194
195                 undo->update_undo_before();
196
197 // Get w and h
198                 w = indexable->get_w();
199                 h = indexable->get_h();
200                 double new_framerate = session->drag_assets->get(0)->get_frame_rate();
201                 double old_framerate = edl->session->frame_rate;
202                 int old_samplerate = edl->session->sample_rate;
203                 int new_samplerate = session->drag_assets->get(0)->get_sample_rate();
204
205
206                 if(indexable->have_video())
207                 {
208                         edl->session->output_w = w;
209                         edl->session->output_h = h;
210                         edl->session->frame_rate = new_framerate;
211                         create_aspect_ratio(edl->session->aspect_w,
212                                 edl->session->aspect_h,
213                                 w,
214                                 h);
215
216                         for(Track *current = edl->tracks->first;
217                                 current;
218                                 current = NEXT)
219                         {
220                                 if(current->data_type == TRACK_VIDEO /* &&
221                                         current->record */ )
222                                 {
223                                         current->track_w = w;
224                                         current->track_h = h;
225                                 }
226                         }
227
228
229                         if(((edl->session->output_w % 4) ||
230                                 (edl->session->output_h % 4)) &&
231                                 edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
232                         {
233                                 MainError::show_error(
234                                         _("This project's dimensions are not multiples of 4 so\n"
235                                         "it can't be rendered by OpenGL."));
236                         }
237
238
239 // Get aspect ratio
240                         if(defaults->get("AUTOASPECT", 0))
241                         {
242                                 create_aspect_ratio(edl->session->aspect_w,
243                                         edl->session->aspect_h,
244                                         w,
245                                         h);
246                         }
247                 }
248
249                 if(indexable->have_audio())
250                 {
251                         edl->session->sample_rate = new_samplerate;
252                         edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
253                         edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
254                 }
255
256
257                 save_backup();
258
259                 undo->update_undo_after(_("asset to all"), LOAD_ALL);
260                 restart_brender();
261                 gui->update(1,
262                         2,
263                         1,
264                         1,
265                         1,
266                         1,
267                         0);
268                 sync_parameters(CHANGE_ALL);
269         }
270 }
271
272
273
274
275
276
277 void MWindow::asset_to_size()
278 {
279         if(!session->drag_assets->size()) return;
280         Indexable *indexable = session->drag_assets->get(0);
281
282         if(indexable->have_video())
283         {
284                 int w, h;
285                 undo->update_undo_before();
286
287 // Get w and h
288                 w = indexable->get_w();
289                 h = indexable->get_h();
290
291
292                 edl->session->output_w = w;
293                 edl->session->output_h = h;
294
295                 if(((edl->session->output_w % 4) ||
296                         (edl->session->output_h % 4)) &&
297                         edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
298                 {
299                         MainError::show_error(
300                                 _("This project's dimensions are not multiples of 4 so\n"
301                                 "it can't be rendered by OpenGL."));
302                 }
303
304
305 // Get aspect ratio
306                 if(defaults->get("AUTOASPECT", 0))
307                 {
308                         create_aspect_ratio(edl->session->aspect_w,
309                                 edl->session->aspect_h,
310                                 w,
311                                 h);
312                 }
313
314                 save_backup();
315
316                 undo->update_undo_after(_("asset to size"), LOAD_ALL);
317                 restart_brender();
318                 sync_parameters(CHANGE_ALL);
319         }
320 }
321
322
323 void MWindow::asset_to_rate()
324 {
325         if(session->drag_assets->size() &&
326                 session->drag_assets->get(0)->have_video())
327         {
328                 double new_framerate = session->drag_assets->get(0)->get_frame_rate();
329                 double old_framerate = edl->session->frame_rate;
330                 undo->update_undo_before();
331
332                 edl->session->frame_rate = new_framerate;
333                 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
334
335                 save_backup();
336
337                 undo->update_undo_after(_("asset to rate"), LOAD_ALL);
338                 restart_brender();
339                 gui->update(1,
340                         2,
341                         1,
342                         1,
343                         1,
344                         1,
345                         0);
346                 sync_parameters(CHANGE_ALL);
347         }
348 }
349
350
351
352 void MWindow::clear_entry()
353 {
354         undo->update_undo_before();
355         clear(1);
356
357         edl->optimize();
358         save_backup();
359         undo->update_undo_after(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
360
361         restart_brender();
362         update_plugin_guis();
363         gui->update(1, 2, 1, 1, 1, 1, 0);
364         cwindow->update(1, 0, 0, 0, 1);
365         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
366                            CHANGE_EDL,
367                            edl,
368                            1);
369 }
370
371 void MWindow::clear(int clear_handle)
372 {
373         double start = edl->local_session->get_selectionstart();
374         double end = edl->local_session->get_selectionend();
375         if(clear_handle || !EQUIV(start, end))
376         {
377                 edl->clear(start,
378                         end,
379                         edl->session->labels_follow_edits,
380                         edl->session->plugins_follow_edits,
381                         edl->session->autos_follow_edits);
382         }
383 }
384
385 void MWindow::set_automation_mode(int mode)
386 {
387         undo->update_undo_before();
388         edl->tracks->set_automation_mode(
389                 edl->local_session->get_selectionstart(),
390                 edl->local_session->get_selectionend(),
391                 mode);
392         save_backup();
393         char string[BCSTRLEN];
394         sprintf(string,"set %s", FloatAuto::curve_name(mode));
395         undo->update_undo_after(string, LOAD_AUTOMATION);
396
397         restart_brender();
398         update_plugin_guis();
399         gui->draw_overlays(1);
400         sync_parameters(CHANGE_PARAMS);
401         gui->update_patchbay();
402         cwindow->update(1, 0, 0);
403 }
404
405 void MWindow::clear_automation()
406 {
407         undo->update_undo_before();
408         edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
409                 edl->local_session->get_selectionend());
410         save_backup();
411         undo->update_undo_after(_("clear keyframes"), LOAD_AUTOMATION);
412
413         restart_brender();
414         update_plugin_guis();
415         gui->draw_overlays(1);
416         sync_parameters(CHANGE_PARAMS);
417         gui->update_patchbay();
418         cwindow->update(1, 0, 0);
419 }
420
421 int MWindow::clear_default_keyframe()
422 {
423         undo->update_undo_before();
424         edl->tracks->clear_default_keyframe();
425         save_backup();
426         undo->update_undo_after(_("clear default keyframe"), LOAD_AUTOMATION);
427
428         restart_brender();
429         gui->draw_overlays(1);
430         sync_parameters(CHANGE_PARAMS);
431         gui->update_patchbay();
432         cwindow->update(1, 0, 0);
433
434         return 0;
435 }
436
437 void MWindow::clear_labels()
438 {
439         undo->update_undo_before();
440         clear_labels(edl->local_session->get_selectionstart(),
441                 edl->local_session->get_selectionend());
442         undo->update_undo_after(_("clear labels"), LOAD_TIMEBAR);
443
444         gui->update_timebar(1);
445         cwindow->update(0, 0, 0, 0, 1);
446         save_backup();
447 }
448
449 int MWindow::clear_labels(double start, double end)
450 {
451         edl->labels->clear(start, end, 0);
452         return 0;
453 }
454
455 void MWindow::concatenate_tracks()
456 {
457         undo->update_undo_before();
458         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits,
459                 edl->session->autos_follow_edits);
460         save_backup();
461         undo->update_undo_after(_("concatenate tracks"), LOAD_EDITS);
462
463         restart_brender();
464         gui->update(1, 1, 0, 0, 1, 0, 0);
465         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
466                 CHANGE_EDL,
467                 edl,
468                 1);
469 }
470
471
472 void MWindow::copy()
473 {
474         copy(edl->local_session->get_selectionstart(),
475                 edl->local_session->get_selectionend());
476 }
477
478 int MWindow::copy(double start, double end)
479 {
480         if(start == end) return 1;
481
482 //printf("MWindow::copy 1\n");
483         FileXML file;
484 //printf("MWindow::copy 1\n");
485         edl->copy(start,
486                 end,
487                 0,
488                 0,
489                 0,
490                 &file,
491                 "",
492                 1);
493 //printf("MWindow::copy 1\n");
494
495 // File is now terminated and rewound
496
497 //printf("MWindow::copy 1\n");
498         const char *file_string = file.string();
499         long file_length = strlen(file_string);
500         gui->get_clipboard()->to_clipboard(file_string, file_length,
501                 SECONDARY_SELECTION);
502         gui->get_clipboard()->to_clipboard(file_string, file_length,
503                 BC_PRIMARY_SELECTION);
504 //printf("MWindow::copy\n%s\n", file.string);
505 //printf("MWindow::copy 2\n");
506         save_backup();
507         return 0;
508 }
509
510 int MWindow::copy_automation()
511 {
512         FileXML file;
513         edl->tracks->copy_automation(edl->local_session->get_selectionstart(),
514                 edl->local_session->get_selectionend(),
515                 &file,
516                 0,
517                 1);
518         const char *file_string = file.string();
519         long file_length = strlen(file_string);
520         gui->get_clipboard()->to_clipboard(file_string, file_length,
521                 BC_PRIMARY_SELECTION);
522         gui->get_clipboard()->to_clipboard(file_string, file_length,
523                 SECONDARY_SELECTION);
524         return 0;
525 }
526
527 int MWindow::copy_default_keyframe()
528 {
529         FileXML file;
530         edl->tracks->copy_automation(edl->local_session->get_selectionstart(),
531                 edl->local_session->get_selectionend(),
532                 &file,
533                 1,
534                 0);
535         const char *file_string = file.string();
536         long file_length = strlen(file_string);
537         gui->get_clipboard()->to_clipboard(file_string, file_length,
538                 BC_PRIMARY_SELECTION);
539         gui->get_clipboard()->to_clipboard(file_string, file_length,
540                 SECONDARY_SELECTION);
541         return 0;
542 }
543
544
545 // Uses cropping coordinates in edl session to crop and translate video.
546 // We modify the projector since camera automation depends on the track size.
547 void MWindow::crop_video()
548 {
549
550         undo->update_undo_before();
551 // Clamp EDL crop region
552         if(edl->session->crop_x1 > edl->session->crop_x2)
553         {
554                 edl->session->crop_x1 ^= edl->session->crop_x2;
555                 edl->session->crop_x2 ^= edl->session->crop_x1;
556                 edl->session->crop_x1 ^= edl->session->crop_x2;
557         }
558         if(edl->session->crop_y1 > edl->session->crop_y2)
559         {
560                 edl->session->crop_y1 ^= edl->session->crop_y2;
561                 edl->session->crop_y2 ^= edl->session->crop_y1;
562                 edl->session->crop_y1 ^= edl->session->crop_y2;
563         }
564
565         float old_projector_x = (float)edl->session->output_w / 2;
566         float old_projector_y = (float)edl->session->output_h / 2;
567         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
568         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
569         float projector_offset_x = -(new_projector_x - old_projector_x);
570         float projector_offset_y = -(new_projector_y - old_projector_y);
571
572         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
573
574         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
575         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
576         edl->session->crop_x1 = 0;
577         edl->session->crop_y1 = 0;
578         edl->session->crop_x2 = edl->session->output_w;
579         edl->session->crop_y2 = edl->session->output_h;
580
581 // Recalculate aspect ratio
582         if(defaults->get("AUTOASPECT", 0))
583         {
584                 create_aspect_ratio(edl->session->aspect_w,
585                         edl->session->aspect_h,
586                         edl->session->output_w,
587                         edl->session->output_h);
588         }
589
590         undo->update_undo_after(_("crop"), LOAD_ALL);
591
592         restart_brender();
593         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
594                 CHANGE_ALL,
595                 edl,
596                 1);
597         save_backup();
598 }
599
600 void MWindow::cut()
601 {
602         undo->update_undo_before();
603
604         double start = edl->local_session->get_selectionstart();
605         double end = edl->local_session->get_selectionend();
606
607         copy(start, end);
608         edl->clear(start,
609                 end,
610                 edl->session->labels_follow_edits,
611                 edl->session->plugins_follow_edits,
612                 edl->session->autos_follow_edits);
613
614
615         edl->optimize();
616         save_backup();
617         undo->update_undo_after(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
618
619         restart_brender();
620         update_plugin_guis();
621         gui->update(1, 2, 1, 1, 1, 1, 0);
622         cwindow->update(1, 0, 0, 0, 1);
623         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
624                                                         CHANGE_EDL,
625                                                         edl,
626                                                         1);
627 }
628
629 int MWindow::cut_automation()
630 {
631         undo->update_undo_before();
632
633         copy_automation();
634
635         edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
636                 edl->local_session->get_selectionend());
637         save_backup();
638         undo->update_undo_after(_("cut keyframes"), LOAD_AUTOMATION);
639
640
641         restart_brender();
642         update_plugin_guis();
643         gui->draw_overlays(1);
644         sync_parameters(CHANGE_PARAMS);
645         gui->update_patchbay();
646         cwindow->update(1, 0, 0);
647         return 0;
648 }
649
650 int MWindow::cut_default_keyframe()
651 {
652
653         undo->update_undo_before();
654         copy_default_keyframe();
655         edl->tracks->clear_default_keyframe();
656         undo->update_undo_after(_("cut default keyframe"), LOAD_AUTOMATION);
657
658         restart_brender();
659         gui->draw_overlays(1);
660         sync_parameters(CHANGE_PARAMS);
661         gui->update_patchbay();
662         cwindow->update(1, 0, 0);
663         save_backup();
664
665
666         return 0;
667 }
668
669
670 void MWindow::delete_inpoint()
671 {
672         edl->local_session->unset_inpoint();
673         save_backup();
674 }
675
676 void MWindow::delete_outpoint()
677 {
678         edl->local_session->unset_outpoint();
679         save_backup();
680 }
681
682
683 void MWindow::delete_track()
684 {
685         if (edl->tracks->last)
686                 delete_track(edl->tracks->last);
687 }
688
689 void MWindow::delete_tracks()
690 {
691         undo->update_undo_before();
692         edl->tracks->delete_tracks();
693         undo->update_undo_after(_("delete tracks"), LOAD_ALL);
694         save_backup();
695
696         restart_brender();
697         update_plugin_states();
698
699         gui->update(1, 1, 1, 0, 1, 0, 0);
700         cwindow->playback_engine->que->
701                 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
702 }
703
704 void MWindow::delete_track(Track *track)
705 {
706         undo->update_undo_before();
707         edl->tracks->delete_track(track);
708         undo->update_undo_after(_("delete track"), LOAD_ALL);
709
710         restart_brender();
711         update_plugin_states();
712
713         gui->update(1, 1, 1, 0, 1, 0, 0);
714         cwindow->playback_engine->que->
715                 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
716         save_backup();
717 }
718
719
720 // Insert data from clipboard
721 void MWindow::insert(double position,
722         FileXML *file,
723         int edit_labels,
724         int edit_plugins,
725         int edit_autos,
726         EDL *parent_edl)
727 {
728 // For clipboard pasting make the new edl use a separate session
729 // from the master EDL.  Then it can be resampled to the master rates.
730 // For splice, overwrite, and dragging need same session to get the assets.
731         EDL *edl = new EDL(parent_edl);
732         ArrayList<EDL*> new_edls;
733         uint32_t load_flags = LOAD_ALL;
734
735
736         new_edls.append(edl);
737         edl->create_objects();
738
739
740
741
742         if(parent_edl) load_flags &= ~LOAD_SESSION;
743         if(!edl->session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
744         if(!edl->session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
745
746         edl->load_xml(file, load_flags);
747
748
749 //printf("MWindow::insert %f\n", edl->local_session->clipboard_length);
750
751
752
753         paste_edls(&new_edls,
754                 LOADMODE_PASTE,
755                 0,
756                 position,
757                 edit_labels,
758                 edit_plugins,
759                 edit_autos,
760                 0); // overwrite
761 // if(vwindow->edl)
762 // printf("MWindow::insert 5 %f %f\n",
763 // vwindow->edl->local_session->in_point,
764 // vwindow->edl->local_session->out_point);
765         new_edls.remove_all();
766         edl->Garbage::remove_user();
767 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
768 }
769
770 void MWindow::insert_effects_canvas(double start,
771         double length)
772 {
773         Track *dest_track = session->track_highlighted;
774         if(!dest_track) return;
775
776         undo->update_undo_before();
777
778         for(int i = 0; i < session->drag_pluginservers->total; i++)
779         {
780                 PluginServer *plugin = session->drag_pluginservers->values[i];
781
782                 insert_effect(plugin->title,
783                         0,
784                         dest_track,
785                         i == 0 ? session->pluginset_highlighted : 0,
786                         start,
787                         length,
788                         PLUGIN_STANDALONE);
789         }
790
791         save_backup();
792         undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
793         restart_brender();
794         sync_parameters(CHANGE_EDL);
795 // GUI updated in TrackCanvas, after current_operations are reset
796 }
797
798 void MWindow::insert_effects_cwindow(Track *dest_track)
799 {
800         if(!dest_track) return;
801
802         undo->update_undo_before();
803
804         double start = 0;
805         double length = dest_track->get_length();
806
807         if(edl->local_session->get_selectionend() >
808                 edl->local_session->get_selectionstart())
809         {
810                 start = edl->local_session->get_selectionstart();
811                 length = edl->local_session->get_selectionend() -
812                         edl->local_session->get_selectionstart();
813         }
814
815         for(int i = 0; i < session->drag_pluginservers->total; i++)
816         {
817                 PluginServer *plugin = session->drag_pluginservers->values[i];
818
819
820                 insert_effect(plugin->title,
821                         0,
822                         dest_track,
823                         0,
824                         start,
825                         length,
826                         PLUGIN_STANDALONE);
827         }
828
829         save_backup();
830         undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
831         restart_brender();
832         sync_parameters(CHANGE_EDL);
833         gui->update(1,
834                 1,
835                 0,
836                 0,
837                 1,
838                 0,
839                 0);
840 }
841
842 void MWindow::insert_effect(char *title,
843         SharedLocation *shared_location,
844         int data_type,
845         int plugin_type,
846         int single_standalone)
847 {
848         Track *current = edl->tracks->first;
849         SharedLocation shared_location_local;
850         shared_location_local.copy_from(shared_location);
851         int first_track = 1;
852         for( ; current; current = NEXT)
853         {
854                 if(current->data_type == data_type &&
855                         current->record)
856                 {
857                         insert_effect(title,
858                                 &shared_location_local,
859                                 current,
860                                 0,
861                                 0,
862                                 0,
863                                 plugin_type);
864
865                         if(first_track)
866                         {
867                                 if(plugin_type == PLUGIN_STANDALONE && single_standalone)
868                                 {
869                                         plugin_type = PLUGIN_SHAREDPLUGIN;
870                                         shared_location_local.module = edl->tracks->number_of(current);
871                                         shared_location_local.plugin = current->plugin_set.total - 1;
872                                 }
873                                 first_track = 0;
874                         }
875                 }
876         }
877 }
878
879
880 void MWindow::insert_effect(char *title,
881         SharedLocation *shared_location,
882         Track *track,
883         PluginSet *plugin_set,
884         double start,
885         double length,
886         int plugin_type)
887 {
888         KeyFrame *default_keyframe = 0;
889         PluginServer *server = 0;
890
891
892
893
894
895
896 // Get default keyframe
897         if(plugin_type == PLUGIN_STANDALONE)
898         {
899                 default_keyframe = new KeyFrame;
900                 server = new PluginServer(*scan_plugindb(title, track->data_type));
901
902                 server->open_plugin(0, preferences, edl, 0);
903                 server->save_data(default_keyframe);
904         }
905
906
907
908 // Insert plugin object
909         track->insert_effect(title,
910                 shared_location,
911                 default_keyframe,
912                 plugin_set,
913                 start,
914                 length,
915                 plugin_type);
916
917         track->optimize();
918
919
920         if(plugin_type == PLUGIN_STANDALONE)
921         {
922                 server->close_plugin();
923                 delete server;
924                 delete default_keyframe;
925         }
926 }
927
928 int MWindow::modify_edithandles()
929 {
930         undo->update_undo_before();
931         edl->modify_edithandles(session->drag_start,
932                 session->drag_position,
933                 session->drag_handle,
934                 edl->session->edit_handle_mode[session->drag_button],
935                 edl->session->labels_follow_edits,
936                 edl->session->plugins_follow_edits,
937                 edl->session->autos_follow_edits);
938
939         finish_modify_handles();
940
941
942 //printf("MWindow::modify_handles 1\n");
943         return 0;
944 }
945
946 int MWindow::modify_pluginhandles()
947 {
948         undo->update_undo_before();
949
950         edl->modify_pluginhandles(session->drag_start,
951                 session->drag_position,
952                 session->drag_handle,
953                 edl->session->edit_handle_mode[session->drag_button],
954                 edl->session->labels_follow_edits,
955                 edl->session->autos_follow_edits,
956                 session->trim_edits);
957
958         finish_modify_handles();
959
960         return 0;
961 }
962
963
964 // Common to edithandles and plugin handles
965 void MWindow::finish_modify_handles()
966 {
967         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
968
969         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
970                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
971         {
972                 edl->local_session->set_selectionstart(session->drag_position);
973                 edl->local_session->set_selectionend(session->drag_position);
974         }
975         else
976         if(edit_mode != MOVE_NO_EDITS)
977         {
978                 edl->local_session->set_selectionstart(session->drag_start);
979                 edl->local_session->set_selectionend(session->drag_start);
980         }
981
982         if(edl->local_session->get_selectionstart(1) < 0)
983         {
984                 edl->local_session->set_selectionstart(0);
985                 edl->local_session->set_selectionend(0);
986         }
987         undo->update_undo_after(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
988
989         save_backup();
990         restart_brender();
991         sync_parameters(CHANGE_EDL);
992         update_plugin_guis();
993         gui->update(1, 2, 1, 1, 1, 1, 0);
994         cwindow->update(1, 0, 0, 0, 1);
995 }
996
997 void MWindow::match_output_size(Track *track)
998 {
999         undo->update_undo_before();
1000         track->track_w = edl->session->output_w;
1001         track->track_h = edl->session->output_h;
1002         save_backup();
1003         undo->update_undo_after(_("match output size"), LOAD_ALL);
1004
1005         restart_brender();
1006         sync_parameters(CHANGE_EDL);
1007 }
1008
1009
1010 void MWindow::move_edits(ArrayList<Edit*> *edits,
1011                 Track *track,
1012                 double position,
1013                 int behaviour)
1014 {
1015         undo->update_undo_before();
1016
1017         edl->tracks->move_edits(edits,
1018                 track,
1019                 position,
1020                 edl->session->labels_follow_edits,
1021                 edl->session->plugins_follow_edits,
1022                 edl->session->autos_follow_edits,
1023                 behaviour);
1024
1025         save_backup();
1026         undo->update_undo_after(_("move edit"), LOAD_ALL);
1027
1028         restart_brender();
1029         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1030                 CHANGE_EDL,
1031                 edl,
1032                 1);
1033
1034         update_plugin_guis();
1035         gui->update(1,
1036                 1,      // 1 for incremental drawing.  2 for full refresh
1037                 1,
1038                 0,
1039                 0,
1040                 0,
1041                 0);
1042 }
1043
1044 void MWindow::move_effect(Plugin *plugin, Track *track, int64_t position)
1045 {
1046         undo->update_undo_before();
1047         edl->tracks->move_effect(plugin, track, position);
1048         save_backup();
1049         undo->update_undo_after(_("paste effect"), LOAD_ALL);
1050
1051         restart_brender();
1052         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1053                 CHANGE_EDL, edl, 1);
1054
1055         update_plugin_guis();
1056         gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
1057                 0, 0, 0, 0, 0);
1058 }
1059
1060 void MWindow::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t position)
1061 {
1062         undo->update_undo_before();
1063         edl->tracks->move_effect(plugin, plugin_set, position);
1064         save_backup();
1065         undo->update_undo_after(_("move effect"), LOAD_ALL);
1066
1067         restart_brender();
1068         cwindow->playback_engine->que->send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
1069         update_plugin_guis();
1070         gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
1071                 0, 0, 0, 0, 0);
1072 }
1073
1074 void MWindow::move_plugins_up(PluginSet *plugin_set)
1075 {
1076
1077         undo->update_undo_before();
1078         plugin_set->track->move_plugins_up(plugin_set);
1079
1080         save_backup();
1081         undo->update_undo_after(_("move effect up"), LOAD_ALL);
1082         restart_brender();
1083         gui->update(1,
1084                 1,      // 1 for incremental drawing.  2 for full refresh
1085                 0,
1086                 0,
1087                 0,
1088                 0,
1089                 0);
1090         sync_parameters(CHANGE_EDL);
1091 }
1092
1093 void MWindow::move_plugins_down(PluginSet *plugin_set)
1094 {
1095         undo->update_undo_before();
1096
1097         plugin_set->track->move_plugins_down(plugin_set);
1098
1099         save_backup();
1100         undo->update_undo_after(_("move effect down"), LOAD_ALL);
1101         restart_brender();
1102         gui->update(1,
1103                 1,      // 1 for incremental drawing.  2 for full refresh
1104                 0,
1105                 0,
1106                 0,
1107                 0,
1108                 0);
1109         sync_parameters(CHANGE_EDL);
1110 }
1111
1112 void MWindow::move_track_down(Track *track)
1113 {
1114         undo->update_undo_before();
1115         edl->tracks->move_track_down(track);
1116         save_backup();
1117         undo->update_undo_after(_("move track down"), LOAD_ALL);
1118
1119         restart_brender();
1120         gui->update(1, 1, 0, 0, 1, 0, 0);
1121         sync_parameters(CHANGE_EDL);
1122         save_backup();
1123 }
1124
1125 void MWindow::move_tracks_down()
1126 {
1127         undo->update_undo_before();
1128         edl->tracks->move_tracks_down();
1129         save_backup();
1130         undo->update_undo_after(_("move tracks down"), LOAD_ALL);
1131
1132         restart_brender();
1133         gui->update(1, 1, 0, 0, 1, 0, 0);
1134         sync_parameters(CHANGE_EDL);
1135         save_backup();
1136 }
1137
1138 void MWindow::move_track_up(Track *track)
1139 {
1140         undo->update_undo_before();
1141         edl->tracks->move_track_up(track);
1142         save_backup();
1143         undo->update_undo_after(_("move track up"), LOAD_ALL);
1144         restart_brender();
1145         gui->update(1, 1, 0, 0, 1, 0, 0);
1146         sync_parameters(CHANGE_EDL);
1147         save_backup();
1148 }
1149
1150 void MWindow::move_tracks_up()
1151 {
1152         undo->update_undo_before();
1153         edl->tracks->move_tracks_up();
1154         save_backup();
1155         undo->update_undo_after(_("move tracks up"), LOAD_ALL);
1156         restart_brender();
1157         gui->update(1, 1, 0, 0, 1, 0, 0);
1158         sync_parameters(CHANGE_EDL);
1159 }
1160
1161
1162 void MWindow::mute_selection()
1163 {
1164         double start = edl->local_session->get_selectionstart();
1165         double end = edl->local_session->get_selectionend();
1166         if(start != end)
1167         {
1168                 undo->update_undo_before();
1169                 edl->clear(start,
1170                         end,
1171                         0,
1172                         edl->session->plugins_follow_edits,
1173                         edl->session->autos_follow_edits);
1174                 edl->local_session->set_selectionend(end);
1175                 edl->local_session->set_selectionstart(start);
1176                 edl->paste_silence(start,
1177                         end,
1178                         0,
1179                         edl->session->plugins_follow_edits,
1180                         edl->session->autos_follow_edits);
1181                 save_backup();
1182                 undo->update_undo_after(_("mute"), LOAD_EDITS);
1183
1184                 restart_brender();
1185                 update_plugin_guis();
1186                 gui->update(1, 2, 1, 1, 1, 1, 0);
1187                 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1188                                                                 CHANGE_EDL,
1189                                                                 edl,
1190                                                                 1);
1191         }
1192 }
1193
1194
1195
1196 void MWindow::overwrite(EDL *source)
1197 {
1198         FileXML file;
1199
1200         double src_start = source->local_session->get_selectionstart();
1201         double overwrite_len = source->local_session->get_selectionend() - src_start;
1202         double dst_start = edl->local_session->get_selectionstart();
1203         double dst_len = edl->local_session->get_selectionend() - dst_start;
1204
1205         undo->update_undo_before();
1206         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
1207         {
1208 // in/out points or selection present and shorter than overwrite range
1209 // shorten the copy range
1210                 overwrite_len = dst_len;
1211         }
1212
1213         source->copy(src_start,
1214                 src_start + overwrite_len,
1215                 1,
1216                 0,
1217                 0,
1218                 &file,
1219                 "",
1220                 1);
1221
1222 // HACK around paste_edl get_start/endselection on its own
1223 // so we need to clear only when not using both io points
1224 // FIXME: need to write simple overwrite_edl to be used for overwrite function
1225         if (edl->local_session->get_inpoint() < 0 ||
1226                 edl->local_session->get_outpoint() < 0)
1227                 edl->clear(dst_start,
1228                         dst_start + overwrite_len,
1229                         0,
1230                         0,
1231                         0);
1232
1233         paste(dst_start,
1234                 dst_start + overwrite_len,
1235                 &file,
1236                 0,
1237                 0,
1238                 0);
1239
1240         edl->local_session->set_selectionstart(dst_start + overwrite_len);
1241         edl->local_session->set_selectionend(dst_start + overwrite_len);
1242
1243         save_backup();
1244         undo->update_undo_after(_("overwrite"), LOAD_EDITS);
1245
1246         restart_brender();
1247         update_plugin_guis();
1248         gui->update(1, 1, 1, 1, 0, 1, 0);
1249         sync_parameters(CHANGE_EDL);
1250 }
1251
1252 // For splice and overwrite
1253 int MWindow::paste(double start,
1254         double end,
1255         FileXML *file,
1256         int edit_labels,
1257         int edit_plugins,
1258         int edit_autos)
1259 {
1260         clear(0);
1261
1262 // Want to insert with assets shared with the master EDL.
1263         insert(start,
1264                         file,
1265                         edit_labels,
1266                         edit_plugins,
1267                         edit_autos,
1268                         edl);
1269
1270         return 0;
1271 }
1272
1273 // For editing using insertion point
1274 void MWindow::paste()
1275 {
1276         double start = edl->local_session->get_selectionstart();
1277         //double end = edl->local_session->get_selectionend();
1278         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1279
1280         if(len)
1281         {
1282                 char *string = new char[len + 1];
1283
1284                 undo->update_undo_before();
1285
1286
1287                 gui->get_clipboard()->from_clipboard(string,
1288                         len,
1289                         BC_PRIMARY_SELECTION);
1290                 FileXML file;
1291                 file.read_from_string(string);
1292
1293
1294
1295
1296                 clear(0);
1297
1298                 insert(start,
1299                         &file,
1300                         edl->session->labels_follow_edits,
1301                         edl->session->plugins_follow_edits,
1302                         edl->session->autos_follow_edits,
1303                         0);
1304
1305                 edl->optimize();
1306
1307
1308                 delete [] string;
1309
1310
1311
1312                 save_backup();
1313
1314
1315                 undo->update_undo_after(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1316                 restart_brender();
1317                 update_plugin_guis();
1318                 gui->update(1, 2, 1, 1, 0, 1, 0);
1319                 awindow->gui->async_update_assets();
1320                 sync_parameters(CHANGE_EDL);
1321         }
1322
1323 }
1324
1325 int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
1326 {
1327         int result = 0;
1328
1329         undo->update_undo_before();
1330
1331
1332
1333         if(session->drag_assets->total)
1334         {
1335                 load_assets(session->drag_assets,
1336                         position,
1337                         LOADMODE_PASTE,
1338                         dest_track,
1339                         0,
1340                         edl->session->labels_follow_edits,
1341                         edl->session->plugins_follow_edits,
1342                         edl->session->autos_follow_edits,
1343                         overwrite);
1344                 result = 1;
1345         }
1346
1347
1348         if(session->drag_clips->total)
1349         {
1350                 paste_edls(session->drag_clips,
1351                         LOADMODE_PASTE,
1352                         dest_track,
1353                         position,
1354                         edl->session->labels_follow_edits,
1355                         edl->session->plugins_follow_edits,
1356                         edl->session->autos_follow_edits,
1357                         overwrite);
1358                 result = 1;
1359         }
1360
1361
1362         save_backup();
1363
1364         undo->update_undo_after(_("paste assets"), LOAD_EDITS);
1365         restart_brender();
1366         gui->update(1,
1367                 2,
1368                 1,
1369                 0,
1370                 0,
1371                 1,
1372                 0);
1373         sync_parameters(CHANGE_EDL);
1374         return result;
1375 }
1376
1377 void MWindow::load_assets(ArrayList<Indexable*> *new_assets,
1378         double position,
1379         int load_mode,
1380         Track *first_track,
1381         RecordLabels *labels,
1382         int edit_labels,
1383         int edit_plugins,
1384         int edit_autos,
1385         int overwrite)
1386 {
1387 const int debug = 0;
1388 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1389         if(position < 0) position = edl->local_session->get_selectionstart();
1390
1391         ArrayList<EDL*> new_edls;
1392         for(int i = 0; i < new_assets->total; i++)
1393         {
1394                 Indexable *indexable = new_assets->get(i);
1395                 if(indexable->is_asset)
1396                 {
1397                         remove_asset_from_caches((Asset*)indexable);
1398                 }
1399                 EDL *new_edl = new EDL;
1400                 new_edl->create_objects();
1401                 new_edl->copy_session(edl);
1402                 new_edls.append(new_edl);
1403
1404
1405                 if(indexable->is_asset)
1406                 {
1407 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1408 if(debug) ((Asset*)indexable)->dump();
1409                         asset_to_edl(new_edl, (Asset*)indexable);
1410                 }
1411                 else
1412                         edl_to_nested(new_edl, (EDL*)indexable);
1413 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1414
1415
1416                 if(labels)
1417                 {
1418                         for(RecordLabel *label = labels->first; label; label = label->next)
1419                         {
1420                                 new_edl->labels->toggle_label(label->position, label->position);
1421                         }
1422                 }
1423         }
1424 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1425
1426         paste_edls(&new_edls,
1427                 load_mode,
1428                 first_track,
1429                 position,
1430                 edit_labels,
1431                 edit_plugins,
1432                 edit_autos,
1433                 overwrite);
1434 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1435
1436
1437         save_backup();
1438         for(int i = 0; i < new_edls.size(); i++)
1439                 new_edls.get(i)->Garbage::remove_user();
1440
1441 if(debug) printf("MWindow::load_assets %d\n", __LINE__);
1442 }
1443
1444 int MWindow::paste_automation()
1445 {
1446         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1447
1448         if(len)
1449         {
1450                 undo->update_undo_before();
1451                 char *string = new char[len + 1];
1452                 gui->get_clipboard()->from_clipboard(string,
1453                         len,
1454                         BC_PRIMARY_SELECTION);
1455                 FileXML file;
1456                 file.read_from_string(string);
1457
1458                 edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
1459                         edl->local_session->get_selectionend());
1460                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(),
1461                         &file,
1462                         0,
1463                         1,
1464                         edl->session->typeless_keyframes);
1465                 save_backup();
1466                 undo->update_undo_after(_("paste keyframes"), LOAD_AUTOMATION);
1467                 delete [] string;
1468
1469
1470                 restart_brender();
1471                 update_plugin_guis();
1472                 gui->draw_overlays(1);
1473                 sync_parameters(CHANGE_PARAMS);
1474                 gui->update_patchbay();
1475                 cwindow->update(1, 0, 0);
1476         }
1477
1478         return 0;
1479 }
1480
1481 int MWindow::paste_default_keyframe()
1482 {
1483         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1484
1485         if(len)
1486         {
1487                 undo->update_undo_before();
1488                 char *string = new char[len + 1];
1489                 gui->get_clipboard()->from_clipboard(string,
1490                         len,
1491                         BC_PRIMARY_SELECTION);
1492                 FileXML file;
1493                 file.read_from_string(string);
1494                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(),
1495                         &file,
1496                         1,
1497                         0,
1498                         edl->session->typeless_keyframes);
1499 //              edl->tracks->paste_default_keyframe(&file);
1500                 undo->update_undo_after(_("paste default keyframe"), LOAD_AUTOMATION);
1501
1502
1503                 restart_brender();
1504                 update_plugin_guis();
1505                 gui->draw_overlays(1);
1506                 sync_parameters(CHANGE_PARAMS);
1507                 gui->update_patchbay();
1508                 cwindow->update(1, 0, 0);
1509                 delete [] string;
1510                 save_backup();
1511         }
1512
1513         return 0;
1514 }
1515
1516
1517 // Insert edls with project deletion and index file generation.
1518 int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
1519         int load_mode,
1520         Track *first_track,
1521         double current_position,
1522         int edit_labels,
1523         int edit_plugins,
1524         int edit_autos,
1525         int overwrite)
1526 {
1527
1528         ArrayList<Track*> destination_tracks;
1529         int need_new_tracks = 0;
1530
1531 //PRINT_TRACE
1532         if(!new_edls->total) return 0;
1533
1534 //PRINT_TRACE
1535 //      double original_length = edl->tracks->total_playable_length();
1536 //      double original_preview_end = edl->local_session->preview_end;
1537 //PRINT_TRACE
1538
1539 // Delete current project
1540         if(load_mode == LOADMODE_REPLACE ||
1541                 load_mode == LOADMODE_REPLACE_CONCATENATE)
1542         {
1543                 reset_caches();
1544
1545                 edl->save_defaults(defaults);
1546
1547                 hide_plugins();
1548
1549                 edl->Garbage::remove_user();
1550
1551                 edl = new EDL;
1552
1553                 edl->create_objects();
1554
1555                 edl->copy_session(new_edls->values[0]);
1556
1557                 gui->mainmenu->update_toggles(0);
1558
1559
1560                 gui->unlock_window();
1561
1562                 gwindow->gui->update_toggles(1);
1563
1564                 gui->lock_window("MWindow::paste_edls");
1565
1566
1567 // Insert labels for certain modes constitutively
1568                 edit_labels = 1;
1569                 edit_plugins = 1;
1570                 edit_autos = 1;
1571 // Force reset of preview
1572 //              original_length = 0;
1573 //              original_preview_end = -1;
1574         }
1575
1576
1577 //PRINT_TRACE
1578
1579 // Create new tracks in master EDL
1580         if(load_mode == LOADMODE_REPLACE ||
1581                 load_mode == LOADMODE_REPLACE_CONCATENATE ||
1582                 load_mode == LOADMODE_NEW_TRACKS)
1583         {
1584
1585                 need_new_tracks = 1;
1586                 for(int i = 0; i < new_edls->total; i++)
1587                 {
1588                         EDL *new_edl = new_edls->values[i];
1589                         for(Track *current = new_edl->tracks->first;
1590                                 current;
1591                                 current = NEXT)
1592                         {
1593                                 if(current->data_type == TRACK_VIDEO)
1594                                 {
1595                                         edl->tracks->add_video_track(0, 0);
1596                                         if(current->draw) edl->tracks->last->draw = 1;
1597                                         destination_tracks.append(edl->tracks->last);
1598                                 }
1599                                 else
1600                                 if(current->data_type == TRACK_AUDIO)
1601                                 {
1602                                         edl->tracks->add_audio_track(0, 0);
1603                                         destination_tracks.append(edl->tracks->last);
1604                                 }
1605                                 else
1606                                 if(current->data_type == TRACK_SUBTITLE)
1607                                 {
1608                                         edl->tracks->add_subttl_track(0, 0);
1609                                         destination_tracks.append(edl->tracks->last);
1610                                 }
1611                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1612                         }
1613
1614 // Base track count on first EDL only for concatenation
1615                         if(load_mode == LOADMODE_REPLACE_CONCATENATE) break;
1616                 }
1617
1618         }
1619         else
1620 // Recycle existing tracks of master EDL
1621         if(load_mode == LOADMODE_CONCATENATE ||
1622                 load_mode == LOADMODE_PASTE ||
1623                 load_mode == LOADMODE_NESTED)
1624         {
1625 //PRINT_TRACE
1626
1627 // The point of this is to shift forward labels after the selection so they can
1628 // then be shifted back to their original locations without recursively
1629 // shifting back every paste.
1630                 if((load_mode == LOADMODE_PASTE ||
1631                         load_mode == LOADMODE_NESTED) &&
1632                         edl->session->labels_follow_edits)
1633                         edl->labels->clear(edl->local_session->get_selectionstart(),
1634                                                 edl->local_session->get_selectionend(),
1635                                                 1);
1636
1637                 Track *current = first_track ? first_track : edl->tracks->first;
1638                 for( ; current; current = NEXT)
1639                 {
1640                         if(current->record)
1641                         {
1642                                 destination_tracks.append(current);
1643                         }
1644                 }
1645 //PRINT_TRACE
1646
1647         }
1648 //PRINT_TRACE
1649
1650
1651
1652
1653         int destination_track = 0;
1654         double *paste_position = new double[destination_tracks.total];
1655
1656
1657
1658
1659
1660 // Iterate through the edls
1661         for(int i = 0; i < new_edls->total; i++)
1662         {
1663
1664                 EDL *new_edl = new_edls->values[i];
1665                 double edl_length = new_edl->local_session->clipboard_length ?
1666                         new_edl->local_session->clipboard_length :
1667                         new_edl->tracks->total_length();
1668 // printf("MWindow::paste_edls 2 %f %f\n",
1669 // new_edl->local_session->clipboard_length,
1670 // new_edl->tracks->total_length());
1671 // new_edl->dump();
1672
1673
1674
1675 //PRINT_TRACE
1676
1677 // Convert EDL to master rates
1678                 new_edl->resample(new_edl->session->sample_rate,
1679                         edl->session->sample_rate,
1680                         TRACK_AUDIO);
1681                 new_edl->resample(new_edl->session->frame_rate,
1682                         edl->session->frame_rate,
1683                         TRACK_VIDEO);
1684 //PRINT_TRACE
1685
1686
1687
1688
1689 // Add assets and prepare index files
1690                 for(Asset *new_asset = new_edl->assets->first;
1691                         new_asset;
1692                         new_asset = new_asset->next)
1693                 {
1694                         mainindexes->add_next_asset(0, new_asset);
1695                 }
1696 // Capture index file status from mainindex test
1697                 edl->update_assets(new_edl);
1698 //PRINT_TRACE
1699
1700
1701
1702 // Get starting point of insertion.  Need this to paste labels.
1703                 switch(load_mode)
1704                 {
1705                         case LOADMODE_REPLACE:
1706                         case LOADMODE_NEW_TRACKS:
1707                                 current_position = 0;
1708                                 break;
1709
1710                         case LOADMODE_CONCATENATE:
1711                         case LOADMODE_REPLACE_CONCATENATE:
1712                                 destination_track = 0;
1713                                 if(destination_tracks.total)
1714                                         current_position = destination_tracks.values[0]->get_length();
1715                                 else
1716                                         current_position = 0;
1717                                 break;
1718
1719                         case LOADMODE_PASTE:
1720                         case LOADMODE_NESTED:
1721                                 destination_track = 0;
1722                                 if(i == 0)
1723                                 {
1724                                         for(int j = 0; j < destination_tracks.total; j++)
1725                                         {
1726                                                 paste_position[j] = (current_position >= 0) ?
1727                                                         current_position :
1728                                                         edl->local_session->get_selectionstart();
1729                                         }
1730                                 }
1731                                 break;
1732
1733                         case LOADMODE_RESOURCESONLY:
1734                                 edl->add_clip(new_edl);
1735                                 break;
1736                 }
1737
1738
1739
1740 //PRINT_TRACE
1741
1742
1743 // Insert edl
1744                 if(load_mode != LOADMODE_RESOURCESONLY)
1745                 {
1746 // Insert labels
1747 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1748                         if(load_mode == LOADMODE_PASTE ||
1749                                 load_mode == LOADMODE_NESTED)
1750                                 edl->labels->insert_labels(new_edl->labels,
1751                                         destination_tracks.total ? paste_position[0] : 0.0,
1752                                         edl_length,
1753                                         edit_labels);
1754                         else
1755                                 edl->labels->insert_labels(new_edl->labels,
1756                                         current_position,
1757                                         edl_length,
1758                                         edit_labels);
1759 //PRINT_TRACE
1760
1761                         for(Track *new_track = new_edl->tracks->first;
1762                                 new_track;
1763                                 new_track = new_track->next)
1764                         {
1765 // Get destination track of same type as new_track
1766                                 for(int k = 0;
1767                                         k < destination_tracks.total &&
1768                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1769                                         k++, destination_track++)
1770                                 {
1771                                         if(destination_track >= destination_tracks.total - 1)
1772                                                 destination_track = 0;
1773                                 }
1774
1775 // Insert data into destination track
1776                                 if(destination_track < destination_tracks.total &&
1777                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1778                                 {
1779                                         Track *track = destination_tracks.values[destination_track];
1780
1781 // Replace default keyframes if first EDL and new tracks were created.
1782 // This means data copied from one track and pasted to another won't retain
1783 // the camera position unless it's a keyframe.  If it did, previous data in the
1784 // track might get unknowingly corrupted.  Ideally we would detect when differing
1785 // default keyframes existed and create discrete keyframes for both.
1786                                         int replace_default = (i == 0) && need_new_tracks;
1787
1788 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1789 // Insert new track at current position
1790                                         switch(load_mode)
1791                                         {
1792                                                 case LOADMODE_REPLACE_CONCATENATE:
1793                                                 case LOADMODE_CONCATENATE:
1794                                                         current_position = track->get_length();
1795                                                         break;
1796
1797                                                 case LOADMODE_PASTE:
1798                                                 case LOADMODE_NESTED:
1799                                                         current_position = paste_position[destination_track];
1800                                                         paste_position[destination_track] += new_track->get_length();
1801                                                         break;
1802                                         }
1803                                         if (overwrite)
1804                                                 track->clear(current_position,
1805                                                                 current_position + new_track->get_length(),
1806                                                                 1, // edit edits
1807                                                                 edit_labels,
1808                                                                 edit_plugins,
1809                                                                 edit_autos,
1810                                                                 1, // convert units
1811                                                                 0); // trim edits
1812
1813
1814 //PRINT_TRACE
1815                                         track->insert_track(new_track,
1816                                                 current_position,
1817                                                 replace_default,
1818                                                 edit_plugins,
1819                                                 edit_autos,
1820                                                 edl_length);
1821 //PRINT_TRACE
1822                                 }
1823
1824 // Get next destination track
1825                                 destination_track++;
1826                                 if(destination_track >= destination_tracks.total)
1827                                         destination_track = 0;
1828                         }
1829                 }
1830
1831                 if(load_mode == LOADMODE_PASTE ||
1832                         load_mode == LOADMODE_NESTED)
1833                         current_position += edl_length;
1834         }
1835
1836
1837 // Move loading of clips and vwindow to the end - this fixes some
1838 // strange issue, for index not being shown
1839 // Assume any paste operation from the same EDL won't contain any clips.
1840 // If it did it would duplicate every clip here.
1841         for(int i = 0; i < new_edls->total; i++)
1842         {
1843                 EDL *new_edl = new_edls->values[i];
1844
1845                 for(int j = 0; j < new_edl->clips.total; j++)
1846                 {
1847                         edl->add_clip(new_edl->clips.values[j]);
1848                 }
1849
1850                 if(new_edl->total_vwindow_edls())
1851                 {
1852 //                      if(edl->vwindow_edl)
1853 //                              edl->vwindow_edl->Garbage::remove_user();
1854 //                      edl->vwindow_edl = new EDL(edl);
1855 //                      edl->vwindow_edl->create_objects();
1856 //                      edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1857
1858                         for(int j = 0; j < new_edl->total_vwindow_edls(); j++)
1859                         {
1860                                 EDL *vwindow_edl = new EDL(edl);
1861                                 vwindow_edl->create_objects();
1862                                 vwindow_edl->copy_all(new_edl->get_vwindow_edl(j));
1863                                 edl->append_vwindow_edl(vwindow_edl, 0);
1864                         }
1865                 }
1866         }
1867
1868
1869         if(paste_position) delete [] paste_position;
1870
1871
1872 // This is already done in load_filenames and everything else that uses paste_edls
1873 //      update_project(load_mode);
1874
1875 // Fix preview range
1876 //      if(EQUIV(original_length, original_preview_end))
1877 //      {
1878 //              edl->local_session->preview_end = edl->tracks->total_playable_length();
1879 //      }
1880
1881
1882 // Start examining next batch of index files
1883         mainindexes->start_build();
1884
1885
1886 // Don't save a backup after loading since the loaded file is on disk already.
1887
1888
1889 //PRINT_TRACE
1890         return 0;
1891 }
1892
1893 void MWindow::paste_silence()
1894 {
1895         double start = edl->local_session->get_selectionstart();
1896         double end = edl->local_session->get_selectionend();
1897         undo->update_undo_before();
1898         edl->paste_silence(start,
1899                 end,
1900                 edl->session->labels_follow_edits,
1901                 edl->session->plugins_follow_edits,
1902                 edl->session->autos_follow_edits);
1903         edl->optimize();
1904         save_backup();
1905         undo->update_undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1906
1907         update_plugin_guis();
1908         restart_brender();
1909         gui->update(1, 2, 1, 1, 1, 1, 0);
1910         cwindow->update(1, 0, 0, 0, 1);
1911         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1912                                                         CHANGE_EDL,
1913                                                         edl,
1914                                                         1);
1915 }
1916
1917 void MWindow::detach_transition(Transition *transition)
1918 {
1919         undo->update_undo_before();
1920         hide_plugin(transition, 1);
1921         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
1922         transition->edit->detach_transition();
1923         save_backup();
1924         undo->update_undo_after(_("detach transition"), LOAD_ALL);
1925
1926         if(is_video) restart_brender();
1927         gui->update(0,
1928                 1,
1929                 0,
1930                 0,
1931                 0,
1932                 0,
1933                 0);
1934         sync_parameters(CHANGE_EDL);
1935 }
1936
1937 void MWindow::detach_transitions()
1938 {
1939         gui->lock_window("MWindow::detach_transitions 1");
1940
1941         undo->update_undo_before();
1942         double start = edl->local_session->get_selectionstart();
1943         double end = edl->local_session->get_selectionend();
1944         edl->tracks->clear_transitions(start, end);
1945
1946         save_backup();
1947         undo->update_undo_after(_("detach transitions"), LOAD_EDITS);
1948
1949         sync_parameters(CHANGE_EDL);
1950         gui->update(0, 1, 0, 0, 0, 0, 0);
1951         gui->unlock_window();
1952 }
1953
1954 void MWindow::paste_transition()
1955 {
1956 // Only the first transition gets dropped.
1957         PluginServer *server = session->drag_pluginservers->values[0];
1958
1959         undo->update_undo_before();
1960         if(server->audio)
1961                 strcpy(edl->session->default_atransition, server->title);
1962         else
1963                 strcpy(edl->session->default_vtransition, server->title);
1964
1965         edl->tracks->paste_transition(server, session->edit_highlighted);
1966         save_backup();
1967         undo->update_undo_after(_("transition"), LOAD_EDITS);
1968
1969         if(server->video) restart_brender();
1970         sync_parameters(CHANGE_ALL);
1971 }
1972
1973 void MWindow::paste_transitions(int track_type, char *title)
1974 {
1975         gui->lock_window("MWindow::detach_transitions 1");
1976
1977         undo->update_undo_before();
1978         double start = edl->local_session->get_selectionstart();
1979         double end = edl->local_session->get_selectionend();
1980         edl->tracks->paste_transitions(start, end, track_type, title);
1981
1982         save_backup();
1983         undo->update_undo_after(_("attach transitions"), LOAD_EDITS);
1984
1985         sync_parameters(CHANGE_EDL);
1986         gui->update(0, 1, 0, 0, 0, 0, 0);
1987         gui->unlock_window();
1988 }
1989
1990 void MWindow::paste_transition_cwindow(Track *dest_track)
1991 {
1992         PluginServer *server = session->drag_pluginservers->values[0];
1993         undo->update_undo_before();
1994         edl->tracks->paste_video_transition(server, 1);
1995         save_backup();
1996         undo->update_undo_after(_("transition"), LOAD_EDITS);
1997         restart_brender();
1998         gui->update(0, 1, 0, 0, 0, 0, 0);
1999         sync_parameters(CHANGE_ALL);
2000 }
2001
2002 void MWindow::paste_audio_transition()
2003 {
2004         PluginServer *server = scan_plugindb(edl->session->default_atransition,
2005                 TRACK_AUDIO);
2006         if(!server)
2007         {
2008                 char string[BCTEXTLEN];
2009                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
2010                 gui->show_message(string);
2011                 return;
2012         }
2013
2014         undo->update_undo_before();
2015         edl->tracks->paste_audio_transition(server);
2016         save_backup();
2017         undo->update_undo_after(_("transition"), LOAD_EDITS);
2018
2019         sync_parameters(CHANGE_EDL);
2020         gui->update(0, 1, 0, 0, 0, 0, 0);
2021 }
2022
2023 void MWindow::paste_video_transition()
2024 {
2025         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
2026                 TRACK_VIDEO);
2027         if(!server)
2028         {
2029                 char string[BCTEXTLEN];
2030                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
2031                 gui->show_message(string);
2032                 return;
2033         }
2034
2035         undo->update_undo_before();
2036
2037         edl->tracks->paste_video_transition(server);
2038         save_backup();
2039         undo->update_undo_after(_("transition"), LOAD_EDITS);
2040
2041         sync_parameters(CHANGE_EDL);
2042         restart_brender();
2043         gui->update(0, 1, 0, 0, 0, 0, 0);
2044 }
2045
2046 void MWindow::shuffle_edits()
2047 {
2048         gui->lock_window("MWindow::shuffle_edits 1");
2049
2050         undo->update_undo_before();
2051         double start = edl->local_session->get_selectionstart();
2052         double end = edl->local_session->get_selectionend();
2053
2054         edl->tracks->shuffle_edits(start, end);
2055
2056         save_backup();
2057         undo->update_undo_after(_("shuffle edits"), LOAD_EDITS | LOAD_TIMEBAR);
2058
2059         sync_parameters(CHANGE_EDL);
2060         restart_brender();
2061         gui->update(0, 1, 1, 0, 0, 0, 0);
2062         gui->unlock_window();
2063 }
2064
2065 void MWindow::reverse_edits()
2066 {
2067         gui->lock_window("MWindow::reverse_edits 1");
2068
2069         undo->update_undo_before();
2070         double start = edl->local_session->get_selectionstart();
2071         double end = edl->local_session->get_selectionend();
2072
2073         edl->tracks->reverse_edits(start, end);
2074
2075         save_backup();
2076         undo->update_undo_after(_("reverse edits"), LOAD_EDITS | LOAD_TIMEBAR);
2077
2078         sync_parameters(CHANGE_EDL);
2079         restart_brender();
2080         gui->update(0, 1, 1, 0, 0, 0, 0);
2081         gui->unlock_window();
2082 }
2083
2084 void MWindow::align_edits()
2085 {
2086         gui->lock_window("MWindow::align_edits 1");
2087
2088         undo->update_undo_before();
2089         double start = edl->local_session->get_selectionstart();
2090         double end = edl->local_session->get_selectionend();
2091
2092         edl->tracks->align_edits(start, end);
2093
2094         save_backup();
2095         undo->update_undo_after(_("align edits"), LOAD_EDITS | LOAD_TIMEBAR);
2096
2097         sync_parameters(CHANGE_EDL);
2098         restart_brender();
2099         gui->update(0, 1, 1, 0, 0, 0, 0);
2100         gui->unlock_window();
2101 }
2102
2103 void MWindow::set_edit_length(double length)
2104 {
2105         gui->lock_window("MWindow::detach_transitions 1");
2106
2107         undo->update_undo_before();
2108         double start = edl->local_session->get_selectionstart();
2109         double end = edl->local_session->get_selectionend();
2110
2111         edl->tracks->set_edit_length(start, end, length);
2112
2113         save_backup();
2114         undo->update_undo_after(_("edit length"), LOAD_EDITS | LOAD_TIMEBAR);
2115
2116         sync_parameters(CHANGE_EDL);
2117         restart_brender();
2118         gui->update(0, 1, 1, 0, 0, 0, 0);
2119         gui->unlock_window();
2120 }
2121
2122
2123 void MWindow::set_transition_length(Transition *transition, double length)
2124 {
2125         gui->lock_window("MWindow::detach_transitions 1");
2126
2127         undo->update_undo_before();
2128         //double start = edl->local_session->get_selectionstart();
2129         //double end = edl->local_session->get_selectionend();
2130
2131         edl->tracks->set_transition_length(transition, length);
2132
2133         save_backup();
2134         undo->update_undo_after(_("transition length"), LOAD_EDITS);
2135
2136         edl->session->default_transition_length = length;
2137         sync_parameters(CHANGE_PARAMS);
2138         gui->update(0, 1, 0, 0, 0, 0, 0);
2139         gui->unlock_window();
2140 }
2141
2142 void MWindow::set_transition_length(double length)
2143 {
2144         gui->lock_window("MWindow::detach_transitions 1");
2145
2146         undo->update_undo_before();
2147         double start = edl->local_session->get_selectionstart();
2148         double end = edl->local_session->get_selectionend();
2149
2150         edl->tracks->set_transition_length(start, end, length);
2151
2152         save_backup();
2153         undo->update_undo_after(_("transition length"), LOAD_EDITS);
2154
2155         edl->session->default_transition_length = length;
2156         sync_parameters(CHANGE_PARAMS);
2157         restart_brender();
2158         gui->update(0, 1, 0, 0, 0, 0, 0);
2159         gui->unlock_window();
2160 }
2161
2162
2163 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
2164 {
2165
2166         calling_window_gui->unlock_window();
2167
2168         cwindow->playback_engine->que->send_command(STOP,
2169                 CHANGE_NONE,
2170                 0,
2171                 0);
2172         cwindow->playback_engine->interrupt_playback(0);
2173
2174         for(int i = 0; i < vwindows.size(); i++)
2175         {
2176                 if(vwindows.get(i)->is_running())
2177                 {
2178                         vwindows.get(i)->playback_engine->que->send_command(STOP,
2179                                 CHANGE_NONE,
2180                                 0,
2181                                 0);
2182                         vwindows.get(i)->playback_engine->interrupt_playback(0);
2183                 }
2184         }
2185
2186         cwindow->gui->lock_window("MWindow::redo_entry");
2187         for(int i = 0; i < vwindows.size(); i++)
2188         {
2189                 if(vwindows.get(i)->is_running())
2190                 {
2191                         if (calling_window_gui != vwindows.get(i)->gui)
2192                         {
2193                                 vwindows.get(i)->gui->lock_window("MWindow::redo_entry 2");
2194                         }
2195                 }
2196         }
2197         gui->lock_window();
2198
2199         undo->redo();
2200
2201         save_backup();
2202         update_plugin_states();
2203         update_plugin_guis();
2204         restart_brender();
2205         gui->update(1, 2, 1, 1, 1, 1, 1);
2206         cwindow->update(1, 1, 1, 1, 1);
2207
2208         if (calling_window_gui != cwindow->gui)
2209                 cwindow->gui->unlock_window();
2210         if (calling_window_gui != gui)
2211                 gui->unlock_window();
2212
2213
2214         for(int i = 0; i < vwindows.size(); i++)
2215         {
2216                 if(vwindows.get(i)->is_running())
2217                 {
2218                         if (calling_window_gui != vwindows.get(i)->gui)
2219                         {
2220                                 vwindows.get(i)->gui->unlock_window();
2221                         }
2222                 }
2223         }
2224
2225         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
2226                            CHANGE_ALL,
2227                            edl,
2228                            1);
2229
2230 }
2231
2232
2233 void MWindow::resize_track(Track *track, int w, int h)
2234 {
2235         undo->update_undo_before();
2236 // We have to move all maskpoints so they do not move in relation to image areas
2237         ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
2238                 (w - track->track_w) / 2,
2239                 (h - track->track_h) / 2);
2240         track->track_w = w;
2241         track->track_h = h;
2242         undo->update_undo_after(_("resize track"), LOAD_ALL);
2243         save_backup();
2244
2245         restart_brender();
2246         sync_parameters(CHANGE_EDL);
2247 }
2248
2249
2250 void MWindow::set_inpoint(int is_mwindow)
2251 {
2252         undo->update_undo_before();
2253         edl->set_inpoint(edl->local_session->get_selectionstart(1));
2254         save_backup();
2255         undo->update_undo_after(_("in point"), LOAD_TIMEBAR);
2256
2257         if(!is_mwindow)
2258         {
2259                 gui->lock_window("MWindow::set_inpoint 1");
2260         }
2261         gui->update_timebar(1);
2262         if(!is_mwindow)
2263         {
2264                 gui->unlock_window();
2265         }
2266
2267         if(is_mwindow)
2268         {
2269                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
2270         }
2271         cwindow->gui->timebar->update(1);
2272         if(is_mwindow)
2273         {
2274                 cwindow->gui->unlock_window();
2275         }
2276 }
2277
2278 void MWindow::set_outpoint(int is_mwindow)
2279 {
2280         undo->update_undo_before();
2281         edl->set_outpoint(edl->local_session->get_selectionend(1));
2282         save_backup();
2283         undo->update_undo_after(_("out point"), LOAD_TIMEBAR);
2284
2285         if(!is_mwindow)
2286         {
2287                 gui->lock_window("MWindow::set_outpoint 1");
2288         }
2289         gui->update_timebar(1);
2290         if(!is_mwindow)
2291         {
2292                 gui->unlock_window();
2293         }
2294
2295         if(is_mwindow)
2296         {
2297                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
2298         }
2299         cwindow->gui->timebar->update(1);
2300         if(is_mwindow)
2301         {
2302                 cwindow->gui->unlock_window();
2303         }
2304 }
2305
2306 void MWindow::splice(EDL *source)
2307 {
2308         FileXML file;
2309
2310         undo->update_undo_before();
2311         source->copy(source->local_session->get_selectionstart(),
2312                 source->local_session->get_selectionend(),
2313                 1,
2314                 0,
2315                 0,
2316                 &file,
2317                 "",
2318                 1);
2319
2320
2321
2322 //file.dump();
2323         double start = edl->local_session->get_selectionstart();
2324         //double end = edl->local_session->get_selectionend();
2325         double source_start = source->local_session->get_selectionstart();
2326         double source_end = source->local_session->get_selectionend();
2327
2328         paste(start,
2329                 start,
2330                 &file,
2331                 edl->session->labels_follow_edits,
2332                 edl->session->plugins_follow_edits,
2333                 edl->session->autos_follow_edits);
2334
2335 // Position at end of clip
2336         edl->local_session->set_selectionstart(start +
2337                 source_end -
2338                 source_start);
2339         edl->local_session->set_selectionend(start +
2340                 source_end -
2341                 source_start);
2342
2343         save_backup();
2344         undo->update_undo_after(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
2345         update_plugin_guis();
2346         restart_brender();
2347         gui->update(1, 1, 1, 1, 0, 1, 0);
2348         sync_parameters(CHANGE_EDL);
2349 }
2350
2351 void MWindow::to_clip()
2352 {
2353         FileXML file;
2354         double start, end;
2355
2356         gui->lock_window("MWindow::to_clip 1");
2357         start = edl->local_session->get_selectionstart();
2358         end = edl->local_session->get_selectionend();
2359
2360         if(EQUIV(end, start))
2361         {
2362                 start = 0;
2363                 end = edl->tracks->total_length();
2364         }
2365
2366 // Don't copy all since we don't want the clips twice.
2367         edl->copy(start,
2368                 end,
2369                 0,
2370                 0,
2371                 0,
2372                 &file,
2373                 "",
2374                 1);
2375
2376
2377         EDL *new_edl = new EDL(edl);
2378         new_edl->create_objects();
2379         new_edl->load_xml(&file, LOAD_ALL);
2380         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
2381         char string[BCTEXTLEN];
2382         Units::totext(string,
2383                         end - start,
2384                         edl->session->time_format,
2385                         edl->session->sample_rate,
2386                         edl->session->frame_rate,
2387                         edl->session->frames_per_foot);
2388
2389         sprintf(new_edl->local_session->clip_notes, _("%s\nCreated from main window"), string);
2390
2391         new_edl->local_session->set_selectionstart(0);
2392         new_edl->local_session->set_selectionend(0);
2393
2394         gui->unlock_window();
2395
2396         awindow->clip_edit->create_clip(new_edl);
2397
2398         gui->lock_window("MWindow::to_clip 2");
2399         save_backup();
2400         gui->unlock_window();
2401 }
2402
2403 int MWindow::toggle_label(int is_mwindow)
2404 {
2405         double position1, position2;
2406         undo->update_undo_before();
2407
2408         if(cwindow->playback_engine->is_playing_back)
2409         {
2410                 position1 = position2 =
2411                         cwindow->playback_engine->get_tracking_position();
2412         }
2413         else
2414         {
2415                 position1 = edl->local_session->get_selectionstart(1);
2416                 position2 = edl->local_session->get_selectionend(1);
2417         }
2418
2419         position1 = edl->align_to_frame(position1, 0);
2420         position2 = edl->align_to_frame(position2, 0);
2421
2422 //printf("MWindow::toggle_label 1\n");
2423
2424         edl->labels->toggle_label(position1, position2);
2425         save_backup();
2426
2427         if(!is_mwindow)
2428         {
2429                 gui->lock_window("MWindow::toggle_label 1");
2430         }
2431         gui->update_timebar(0);
2432         gui->activate_timeline();
2433         gui->flush();
2434         if(!is_mwindow)
2435         {
2436                 gui->unlock_window();
2437         }
2438
2439         if(is_mwindow)
2440         {
2441                 cwindow->gui->lock_window("MWindow::toggle_label 2");
2442         }
2443         cwindow->gui->timebar->update(1);
2444         if(is_mwindow)
2445         {
2446                 cwindow->gui->unlock_window();
2447         }
2448
2449         awindow->gui->async_update_assets();
2450
2451         undo->update_undo_after(_("label"), LOAD_TIMEBAR);
2452         return 0;
2453 }
2454
2455 void MWindow::trim_selection()
2456 {
2457         undo->update_undo_before();
2458
2459
2460         edl->trim_selection(edl->local_session->get_selectionstart(),
2461                 edl->local_session->get_selectionend(),
2462                 edl->session->labels_follow_edits,
2463                 edl->session->plugins_follow_edits,
2464                 edl->session->autos_follow_edits);
2465
2466         save_backup();
2467         undo->update_undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
2468         update_plugin_guis();
2469         gui->update(1, 2, 1, 1, 1, 1, 0);
2470         cwindow->update(1, 0, 0, 0, 1);
2471         restart_brender();
2472         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
2473                                                         CHANGE_EDL,
2474                                                         edl,
2475                                                         1);
2476 }
2477
2478
2479
2480 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2481 {
2482         calling_window_gui->unlock_window();
2483
2484         cwindow->playback_engine->que->send_command(STOP,
2485                 CHANGE_NONE,
2486                 0,
2487                 0);
2488         cwindow->playback_engine->interrupt_playback(0);
2489
2490 //printf("MWindow::undo_entry %d %d\n", __LINE__, vwindows.size());
2491         for(int i = 0; i < vwindows.size(); i++)
2492         {
2493                 if(vwindows.get(i)->is_running())
2494                 {
2495                         vwindows.get(i)->playback_engine->que->send_command(STOP,
2496                                 CHANGE_NONE,
2497                                 0,
2498                                 0);
2499                         vwindows.get(i)->playback_engine->interrupt_playback(0);
2500                 }
2501         }
2502
2503         cwindow->gui->lock_window("MWindow::undo_entry 1");
2504         for(int i = 0; i < vwindows.size(); i++)
2505         {
2506                 if(vwindows.get(i)->is_running())
2507                 {
2508                         if (calling_window_gui != vwindows.get(i)->gui)
2509                         {
2510                                 vwindows.get(i)->gui->lock_window("MWindow::undo_entry 4");
2511                         }
2512                 }
2513         }
2514         gui->lock_window("MWindow::undo_entry 2");
2515
2516         undo->undo();
2517
2518         save_backup();
2519         restart_brender();
2520         update_plugin_states();
2521         update_plugin_guis();
2522
2523
2524
2525         gui->update(1, 2, 1, 1, 1, 1, 1);
2526
2527         gui->unlock_window();
2528
2529         cwindow->update(1, 1, 1, 1, 1);
2530
2531         cwindow->gui->unlock_window();
2532
2533         for(int i = 0; i < vwindows.size(); i++)
2534         {
2535                 if(vwindows.get(i)->is_running())
2536                 {
2537                         if (calling_window_gui != vwindows.get(i)->gui)
2538                         {
2539                                 vwindows.get(i)->gui->unlock_window();
2540                         }
2541                 }
2542         }
2543
2544         if (calling_window_gui != gui)
2545                 gui->unlock_window();
2546
2547
2548         awindow->gui->async_update_assets();
2549
2550         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
2551                            CHANGE_ALL,
2552                            edl,
2553                            1);
2554         calling_window_gui->lock_window("MWindow::undo_entry 4");
2555 }
2556
2557
2558
2559 void MWindow::new_folder(const char *new_folder)
2560 {
2561         undo->update_undo_before();
2562         edl->new_folder(new_folder);
2563         undo->update_undo_after(_("new folder"), LOAD_ALL);
2564         awindow->gui->async_update_assets();
2565 }
2566
2567 void MWindow::delete_folder(char *folder)
2568 {
2569 //      undo->update_undo_after(_("delete folder"), LOAD_ALL);
2570 }
2571
2572 void MWindow::select_point(double position)
2573 {
2574         edl->local_session->set_selectionstart(position);
2575         edl->local_session->set_selectionend(position);
2576
2577 // Que the CWindow
2578         cwindow->update(1, 0, 0, 0, 1);
2579
2580
2581         update_plugin_guis();
2582         gui->update_patchbay();
2583         gui->hide_cursor(0);
2584         gui->draw_cursor(0);
2585         gui->mainclock->update(edl->local_session->get_selectionstart(1));
2586         gui->zoombar->update();
2587         gui->update_timebar(0);
2588         gui->flash_canvas(0);
2589         gui->flush();
2590 }
2591
2592
2593
2594
2595 void MWindow::map_audio(int pattern)
2596 {
2597         undo->update_undo_before();
2598         remap_audio(pattern);
2599         undo->update_undo_after(
2600                 pattern == MWindow::AUDIO_1_TO_1 ? _("map 1:1") : _("map 5.1:2"),
2601                 LOAD_AUTOMATION);
2602         sync_parameters(CHANGE_PARAMS);
2603         gui->update(0, 1, 0, 0, 1, 0, 0);
2604 }
2605
2606 void MWindow::remap_audio(int pattern)
2607 {
2608         int current_channel = 0;
2609         int current_track = 0;
2610         for(Track *current = edl->tracks->first; current; current = NEXT)
2611         {
2612                 if(current->data_type == TRACK_AUDIO &&
2613                         current->record)
2614                 {
2615                         Autos *pan_autos = current->automation->autos[AUTOMATION_PAN];
2616                         PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1);
2617
2618                         for(int i = 0; i < MAXCHANNELS; i++)
2619                         {
2620                                 pan_auto->values[i] = 0.0;
2621                         }
2622
2623                         if(pattern == MWindow::AUDIO_1_TO_1)
2624                         {
2625                                 pan_auto->values[current_channel] = 1.0;
2626                         }
2627                         else
2628                         if(pattern == MWindow::AUDIO_5_1_TO_2)
2629                         {
2630                                 switch(current_track)
2631                                 {
2632                                         case 0:
2633                                                 pan_auto->values[0] = 0.5;
2634                                                 pan_auto->values[1] = 0.5;
2635                                                 break;
2636                                         case 1:
2637                                                 pan_auto->values[0] = 1;
2638                                                 break;
2639                                         case 2:
2640                                                 pan_auto->values[1] = 1;
2641                                                 break;
2642                                         case 3:
2643                                                 pan_auto->values[0] = 1;
2644                                                 break;
2645                                         case 4:
2646                                                 pan_auto->values[1] = 1;
2647                                                 break;
2648                                         case 5:
2649                                                 pan_auto->values[0] = 0.5;
2650                                                 pan_auto->values[1] = 0.5;
2651                                                 break;
2652                                 }
2653                         }
2654
2655                         BC_Pan::calculate_stick_position(edl->session->audio_channels,
2656                                 edl->session->achannel_positions,
2657                                 pan_auto->values,
2658                                 MAX_PAN,
2659                                 PAN_RADIUS,
2660                                 pan_auto->handle_x,
2661                                 pan_auto->handle_y);
2662
2663                         current_channel++;
2664                         current_track++;
2665                         if(current_channel >= edl->session->audio_channels)
2666                                 current_channel = 0;
2667                 }
2668         }
2669 }
2670
2671 void MWindow::cut_commercials()
2672 {
2673         undo->update_undo_before();
2674         commercials->scan_media();
2675         edl->optimize();
2676         save_backup();
2677         undo->update_undo_after(_("cut ads"), LOAD_EDITS | LOAD_TIMEBAR);
2678
2679         restart_brender();
2680         update_plugin_guis();
2681         gui->update(1, 2, 1, 1, 1, 1, 0);
2682         cwindow->update(1, 0, 0, 0, 1);
2683         cwindow->playback_engine->que->
2684                 send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
2685 }
2686
2687