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