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