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