Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / cinelerra / mwindowedit.C
blobbf5e2e0e7f2b14ce090d6a1a50a7a9bee30d0f60
1 #include "asset.h"
2 #include "assets.h"
3 #include "awindowgui.h"
4 #include "awindow.h"
5 #include "bcsignals.h"
6 #include "cache.h"
7 #include "clip.h"
8 #include "clipedit.h"
9 #include "cplayback.h"
10 #include "ctimebar.h"
11 #include "cwindow.h"
12 #include "cwindowgui.h"
13 #include "bchash.h"
14 #include "edl.h"
15 #include "edlsession.h"
16 #include "filexml.h"
17 #include "gwindow.h"
18 #include "gwindowgui.h"
19 #include "keyframe.h"
20 #include "language.h"
21 #include "labels.h"
22 #include "levelwindow.h"
23 #include "localsession.h"
24 #include "mainclock.h"
25 #include "maincursor.h"
26 #include "mainerror.h"
27 #include "mainindexes.h"
28 #include "mainmenu.h"
29 #include "mainsession.h"
30 #include "mainundo.h"
31 #include "maskautos.h"
32 #include "mtimebar.h"
33 #include "mwindowgui.h"
34 #include "mwindow.h"
35 #include "panauto.h"
36 #include "patchbay.h"
37 #include "playbackengine.h"
38 #include "pluginset.h"
39 #include "recordlabel.h"
40 #include "samplescroll.h"
41 #include "trackcanvas.h"
42 #include "track.h"
43 #include "trackscroll.h"
44 #include "tracks.h"
45 #include "transition.h"
46 #include "transportque.h"
47 #include "units.h"
48 #include "undostackitem.h"
49 #include "vplayback.h"
50 #include "vwindow.h"
51 #include "vwindowgui.h"
52 #include "zoombar.h"
53 #include "automation.h"
54 #include "maskautos.h"
57 #include <string.h>
64 void MWindow::add_audio_track_entry(int above, Track *dst)
66         add_audio_track(above, dst);
67         save_backup();
68         undo->update_undo(_("add track"), LOAD_ALL);
70         restart_brender();
71         gui->get_scrollbars();
72         gui->canvas->draw();
73         gui->patchbay->update();
74         gui->cursor->draw(1);
75         gui->canvas->flash();
76         gui->canvas->activate();
77         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
78                 CHANGE_EDL,
79                 edl,
80                 1);
83 void MWindow::add_video_track_entry(Track *dst)
85         add_video_track(1, dst);
86         undo->update_undo(_("add track"), LOAD_ALL);
88         restart_brender();
89         gui->get_scrollbars();
90         gui->canvas->draw();
91         gui->patchbay->update();
92         gui->cursor->draw(1);
93         gui->canvas->flash();
94         gui->canvas->activate();
95         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
96                                                         CHANGE_EDL,
97                                                         edl,
98                                                         1);
99         save_backup();
103 int MWindow::add_audio_track(int above, Track *dst)
105         edl->tracks->add_audio_track(above, dst);
106         edl->tracks->update_y_pixels(theme);
107         save_backup();
108         return 0;
111 int MWindow::add_video_track(int above, Track *dst)
113         edl->tracks->add_video_track(above, dst);
114         edl->tracks->update_y_pixels(theme);
115         save_backup();
116         return 0;
123 void MWindow::asset_to_size()
125         if(session->drag_assets->total &&
126                 session->drag_assets->values[0]->video_data)
127         {
128                 int w, h;
130 // Get w and h
131                 w = session->drag_assets->values[0]->width;
132                 h = session->drag_assets->values[0]->height;
135                 edl->session->output_w = w;
136                 edl->session->output_h = h;
138                 if(((edl->session->output_w % 4) || 
139                         (edl->session->output_h % 4)) && 
140                         edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
141                 {
142                         MainError::show_error(
143                                 _("This project's dimensions are not multiples of 4 so\n"
144                                 "it can't be rendered by OpenGL."));
145                 }
148 // Get aspect ratio
149                 if(defaults->get("AUTOASPECT", 0))
150                 {
151                         create_aspect_ratio(edl->session->aspect_w, 
152                                 edl->session->aspect_h, 
153                                 w, 
154                                 h);
155                 }
157                 save_backup();
159                 undo->update_undo(_("asset to size"), LOAD_ALL);
160                 restart_brender();
161                 sync_parameters(CHANGE_ALL);
162         }
166 void MWindow::asset_to_rate()
168         if(session->drag_assets->total &&
169                 session->drag_assets->values[0]->video_data)
170         {
171                 double new_framerate = session->drag_assets->values[0]->frame_rate;
172                 double old_framerate = edl->session->frame_rate;
174                 edl->session->frame_rate = new_framerate;
175                 edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
177                 save_backup();
179                 undo->update_undo(_("asset to rate"), LOAD_ALL);
180                 restart_brender();
181                 gui->update(1,
182                         2,
183                         1,
184                         1,
185                         1, 
186                         1,
187                         0);
188                 sync_parameters(CHANGE_ALL);
189         }
194 void MWindow::clear_entry()
196         clear(1);
198         edl->optimize();
199         save_backup();
200         undo->update_undo(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
202         restart_brender();
203         update_plugin_guis();
204         gui->update(1, 2, 1, 1, 1, 1, 0);
205         cwindow->update(1, 0, 0, 0, 1);
206         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
207                            CHANGE_EDL,
208                            edl,
209                            1);
212 void MWindow::clear(int clear_handle)
214         double start = edl->local_session->get_selectionstart();
215         double end = edl->local_session->get_selectionend();
216         if(clear_handle || !EQUIV(start, end))
217         {
218                 edl->clear(start, 
219                         end, 
220                         edl->session->labels_follow_edits, 
221                         edl->session->plugins_follow_edits);
222         }
225 void MWindow::straighten_automation()
227         edl->tracks->straighten_automation(
228                 edl->local_session->get_selectionstart(), 
229                 edl->local_session->get_selectionend()); 
230         save_backup();
231         undo->update_undo(_("straighten curves"), LOAD_AUTOMATION); 
233         restart_brender();
234         update_plugin_guis();
235         gui->canvas->draw_overlays();
236         gui->canvas->flash();
237         sync_parameters(CHANGE_PARAMS);
238         gui->patchbay->update();
239         cwindow->update(1, 0, 0);
242 void MWindow::clear_automation()
244         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
245                 edl->local_session->get_selectionend()); 
246         save_backup();
247         undo->update_undo(_("clear keyframes"), LOAD_AUTOMATION); 
249         restart_brender();
250         update_plugin_guis();
251         gui->canvas->draw_overlays();
252         gui->canvas->flash();
253         sync_parameters(CHANGE_PARAMS);
254         gui->patchbay->update();
255         cwindow->update(1, 0, 0);
258 int MWindow::clear_default_keyframe()
260         edl->tracks->clear_default_keyframe();
261         save_backup();
262         undo->update_undo(_("clear default keyframe"), LOAD_AUTOMATION);
263         
264         restart_brender();
265         gui->canvas->draw_overlays();
266         gui->canvas->flash();
267         sync_parameters(CHANGE_PARAMS);
268         gui->patchbay->update();
269         cwindow->update(1, 0, 0);
270         
271         return 0;
274 void MWindow::clear_labels()
276         clear_labels(edl->local_session->get_selectionstart(), 
277                 edl->local_session->get_selectionend()); 
278         undo->update_undo(_("clear labels"), LOAD_TIMEBAR);
279         
280         gui->timebar->update();
281         cwindow->update(0, 0, 0, 0, 1);
282         save_backup();
285 int MWindow::clear_labels(double start, double end)
287         edl->labels->clear(start, end, 0);
288         return 0;
291 void MWindow::concatenate_tracks()
293         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
294         save_backup();
295         undo->update_undo(_("concatenate tracks"), LOAD_EDITS);
297         restart_brender();
298         gui->update(1, 1, 0, 0, 1, 0, 0);
299         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
300                 CHANGE_EDL,
301                 edl,
302                 1);
306 void MWindow::copy()
308         copy(edl->local_session->get_selectionstart(), 
309                 edl->local_session->get_selectionend());
312 int MWindow::copy(double start, double end)
314         if(start == end) return 1;
316 //printf("MWindow::copy 1\n");
317         FileXML file;
318 //printf("MWindow::copy 1\n");
319         edl->copy(start, 
320                 end, 
321                 0,
322                 0,
323                 0,
324                 &file, 
325                 plugindb,
326                 "",
327                 1);
328 //printf("MWindow::copy 1\n");
330 // File is now terminated and rewound
332 //printf("MWindow::copy 1\n");
333         gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
334 //printf("MWindow::copy\n%s\n", file.string);
335 //printf("MWindow::copy 2\n");
336         save_backup();
337         return 0;
340 int MWindow::copy_automation()
342         FileXML file;
343         edl->tracks->copy_automation(edl->local_session->get_selectionstart(), 
344                 edl->local_session->get_selectionend(),
345                 &file,
346                 0,
347                 0); 
348         gui->get_clipboard()->to_clipboard(file.string, 
349                 strlen(file.string), 
350                 SECONDARY_SELECTION);
351         return 0;
354 int MWindow::copy_default_keyframe()
356         FileXML file;
357         edl->tracks->copy_default_keyframe(&file);
358         gui->get_clipboard()->to_clipboard(file.string,
359                 strlen(file.string),
360                 SECONDARY_SELECTION);
361         return 0;
365 // Uses cropping coordinates in edl session to crop and translate video.
366 // We modify the projector since camera automation depends on the track size.
367 void MWindow::crop_video()
370 // Clamp EDL crop region
371         if(edl->session->crop_x1 > edl->session->crop_x2)
372         {
373                 edl->session->crop_x1 ^= edl->session->crop_x2;
374                 edl->session->crop_x2 ^= edl->session->crop_x1;
375                 edl->session->crop_x1 ^= edl->session->crop_x2;
376         }
377         if(edl->session->crop_y1 > edl->session->crop_y2)
378         {
379                 edl->session->crop_y1 ^= edl->session->crop_y2;
380                 edl->session->crop_y2 ^= edl->session->crop_y1;
381                 edl->session->crop_y1 ^= edl->session->crop_y2;
382         }
384         float old_projector_x = (float)edl->session->output_w / 2;
385         float old_projector_y = (float)edl->session->output_h / 2;
386         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
387         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
388         float projector_offset_x = -(new_projector_x - old_projector_x);
389         float projector_offset_y = -(new_projector_y - old_projector_y);
391         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
393         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
394         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
395         edl->session->crop_x1 = 0;
396         edl->session->crop_y1 = 0;
397         edl->session->crop_x2 = edl->session->output_w;
398         edl->session->crop_y2 = edl->session->output_h;
400 // Recalculate aspect ratio
401         if(defaults->get("AUTOASPECT", 0))
402         {
403                 create_aspect_ratio(edl->session->aspect_w, 
404                         edl->session->aspect_h, 
405                         edl->session->output_w, 
406                         edl->session->output_h);
407         }
409         undo->update_undo(_("crop"), LOAD_ALL);
411         restart_brender();
412         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
413                 CHANGE_ALL,
414                 edl,
415                 1);
416         save_backup();
419 void MWindow::cut()
422         double start = edl->local_session->get_selectionstart();
423         double end = edl->local_session->get_selectionend();
425         copy(start, end);
426         edl->clear(start, 
427                 end,
428                 edl->session->labels_follow_edits, 
429                 edl->session->plugins_follow_edits);
432         edl->optimize();
433         save_backup();
434         undo->update_undo(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
436         restart_brender();
437         update_plugin_guis();
438         gui->update(1, 2, 1, 1, 1, 1, 0);
439         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
440                                                         CHANGE_EDL,
441                                                         edl,
442                                                         1);
445 int MWindow::cut_automation()
447         
448         copy_automation();
450         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
451                 edl->local_session->get_selectionend()); 
452         save_backup();
453         undo->update_undo(_("cut keyframes"), LOAD_AUTOMATION); 
456         restart_brender();
457         update_plugin_guis();
458         gui->canvas->draw_overlays();
459         gui->canvas->flash();
460         sync_parameters(CHANGE_PARAMS);
461         gui->patchbay->update();
462         cwindow->update(1, 0, 0);
463         return 0;
466 int MWindow::cut_default_keyframe()
469         copy_default_keyframe();
470         edl->tracks->clear_default_keyframe();
471         undo->update_undo(_("cut default keyframe"), LOAD_AUTOMATION);
473         restart_brender();
474         gui->canvas->draw_overlays();
475         gui->canvas->flash();
476         sync_parameters(CHANGE_PARAMS);
477         gui->patchbay->update();
478         cwindow->update(1, 0, 0);
479         save_backup();
482         return 0;
485 void MWindow::delete_inpoint()
487         edl->local_session->unset_inpoint();
488         save_backup();
491 void MWindow::delete_outpoint()
493         edl->local_session->unset_outpoint();
494         save_backup();
497 void MWindow::delete_track()
499         if (edl->tracks->last)
500                 delete_track(edl->tracks->last);
503 void MWindow::delete_tracks()
505         edl->tracks->delete_tracks();
506         undo->update_undo(_("delete tracks"), LOAD_ALL);
507         save_backup();
509         restart_brender();
510         update_plugin_states();
511         gui->update(1, 1, 1, 0, 1, 0, 0);
512         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
513                            CHANGE_EDL,
514                            edl,
515                            1);
518 void MWindow::delete_track(Track *track)
520         edl->tracks->delete_track(track);
521         undo->update_undo(_("delete track"), LOAD_ALL);
523         restart_brender();
524         update_plugin_states();
525         gui->update(1, 1, 1, 0, 1, 0, 0);
526         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
527                            CHANGE_EDL,
528                            edl,
529                            1);
530         save_backup();
533 void MWindow::detach_transition(Transition *transition)
535         hide_plugin(transition, 1);
536         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
537         transition->edit->detach_transition();
538         save_backup();
539         undo->update_undo(_("detach transition"), LOAD_ALL);
541         if(is_video) restart_brender();
542         gui->update(0,
543                 1,
544                 0,
545                 0,
546                 0, 
547                 0,
548                 0);
549         sync_parameters(CHANGE_EDL);
556 // Insert data from clipboard
557 void MWindow::insert(double position, 
558         FileXML *file,
559         int edit_labels,
560         int edit_plugins,
561         EDL *parent_edl)
563 // For clipboard pasting make the new edl use a separate session 
564 // from the master EDL.  Then it can be resampled to the master rates.
565 // For splice, overwrite, and dragging need same session to get the assets.
566         EDL edl(parent_edl);
567         ArrayList<EDL*> new_edls;
568         uint32_t load_flags = LOAD_ALL;
571         new_edls.append(&edl);
572         edl.create_objects();
577         if(parent_edl) load_flags &= ~LOAD_SESSION;
578         if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
579         if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
581         edl.load_xml(plugindb, file, load_flags);
588         paste_edls(&new_edls, 
589                 LOAD_PASTE, 
590                 0, 
591                 position,
592                 edit_labels,
593                 edit_plugins,
594                 0); // overwrite
595 // if(vwindow->edl)
596 // printf("MWindow::insert 5 %f %f\n", 
597 // vwindow->edl->local_session->in_point,
598 // vwindow->edl->local_session->out_point);
599         new_edls.remove_all();
600 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
603 void MWindow::insert_effects_canvas(double start,
604         double length)
606         Track *dest_track = session->track_highlighted;
607         if(!dest_track) return;
610         for(int i = 0; i < session->drag_pluginservers->total; i++)
611         {
612                 PluginServer *plugin = session->drag_pluginservers->values[i];
614                 insert_effect(plugin->title,
615                         0,
616                         dest_track,
617                         i == 0 ? session->pluginset_highlighted : 0,
618                         start,
619                         length,
620                         PLUGIN_STANDALONE);
621         }
623         save_backup();
624         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
625         restart_brender();
626         sync_parameters(CHANGE_EDL);
627 // GUI updated in TrackCanvas, after current_operations are reset
630 void MWindow::insert_effects_cwindow(Track *dest_track)
632         if(!dest_track) return;
635         double start = 0;
636         double length = dest_track->get_length();
638         if(edl->local_session->get_selectionend() > 
639                 edl->local_session->get_selectionstart())
640         {
641                 start = edl->local_session->get_selectionstart();
642                 length = edl->local_session->get_selectionend() - 
643                         edl->local_session->get_selectionstart();
644         }
646         for(int i = 0; i < session->drag_pluginservers->total; i++)
647         {
648                 PluginServer *plugin = session->drag_pluginservers->values[i];
651                 insert_effect(plugin->title,
652                         0,
653                         dest_track,
654                         0,
655                         start,
656                         length,
657                         PLUGIN_STANDALONE);
658         }
660         save_backup();
661         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
662         restart_brender();
663         sync_parameters(CHANGE_EDL);
664         gui->update(1,
665                 1,
666                 0,
667                 0,
668                 1,
669                 0,
670                 0);
675 void MWindow::insert_effect(char *title, 
676         SharedLocation *shared_location, 
677         Track *track,
678         PluginSet *plugin_set,
679         double start,
680         double length,
681         int plugin_type)
683         KeyFrame *default_keyframe = 0;
684         PluginServer *server = 0;
691 // Get default keyframe
692         if(plugin_type == PLUGIN_STANDALONE)
693         {
694                 default_keyframe = new KeyFrame;
695                 server = new PluginServer(*scan_plugindb(title, track->data_type));
697                 server->open_plugin(0, preferences, edl, 0, -1);
698                 server->save_data(default_keyframe);
699         }
703 // Insert plugin object
704         track->insert_effect(title, 
705                 shared_location, 
706                 default_keyframe, 
707                 plugin_set,
708                 start,
709                 length,
710                 plugin_type);
712         track->optimize();
715         if(plugin_type == PLUGIN_STANDALONE)
716         {
717                 server->close_plugin();
718                 delete server;
719                 delete default_keyframe;
720         }
723 int MWindow::modify_edithandles()
726         edl->modify_edithandles(session->drag_start, 
727                 session->drag_position, 
728                 session->drag_handle, 
729                 edl->session->edit_handle_mode[session->drag_button],
730                 edl->session->labels_follow_edits, 
731                 edl->session->plugins_follow_edits);
733         finish_modify_handles();
736 //printf("MWindow::modify_handles 1\n");
737         return 0;
740 int MWindow::modify_pluginhandles()
743         edl->modify_pluginhandles(session->drag_start, 
744                 session->drag_position, 
745                 session->drag_handle, 
746                 edl->session->edit_handle_mode[session->drag_button],
747                 edl->session->labels_follow_edits,
748                 session->trim_edits);
750         finish_modify_handles();
752         return 0;
756 // Common to edithandles and plugin handles
757 void MWindow::finish_modify_handles()
759         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
761         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
762                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
763         {
764                 edl->local_session->set_selectionstart(session->drag_position);
765                 edl->local_session->set_selectionend(session->drag_position);
766         }
767         else
768         if(edit_mode != MOVE_NO_EDITS)
769         {
770                 edl->local_session->set_selectionstart(session->drag_start);
771                 edl->local_session->set_selectionend(session->drag_start);
772         }
774         if(edl->local_session->get_selectionstart(1) < 0)
775         {
776                 edl->local_session->set_selectionstart(0);
777                 edl->local_session->set_selectionend(0);
778         }
780         save_backup();
781         undo->update_undo(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
782         restart_brender();
783         sync_parameters(CHANGE_EDL);
784         update_plugin_guis();
785         gui->update(1, 2, 1, 1, 1, 1, 0);
786         cwindow->update(1, 0, 0, 0, 1);
789 void MWindow::match_output_size(Track *track)
791         track->track_w = edl->session->output_w;
792         track->track_h = edl->session->output_h;
793         save_backup();
794         undo->update_undo(_("match output size"), LOAD_ALL);
796         restart_brender();
797         sync_parameters(CHANGE_EDL);
801 void MWindow::move_edits(ArrayList<Edit*> *edits, 
802                 Track *track,
803                 double position,
804                 int behaviour)
807         edl->tracks->move_edits(edits, 
808                 track, 
809                 position,
810                 edl->session->labels_follow_edits, 
811                 edl->session->plugins_follow_edits,
812                 behaviour);
814         save_backup();
815         undo->update_undo(_("move edit"), LOAD_ALL);
817         restart_brender();
818         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
819                 CHANGE_EDL,
820                 edl,
821                 1);
823         update_plugin_guis();
824         gui->update(1,
825                 1,      // 1 for incremental drawing.  2 for full refresh
826                 1,
827                 0,
828                 0, 
829                 0,
830                 0);
833 void MWindow::move_effect(Plugin *plugin,
834         PluginSet *dest_plugin_set,
835         Track *dest_track,
836         int64_t dest_position)
839         edl->tracks->move_effect(plugin, 
840                 dest_plugin_set, 
841                 dest_track, 
842                 dest_position);
844         save_backup();
845         undo->update_undo(_("move effect"), LOAD_ALL);
847         restart_brender();
848         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
849                 CHANGE_EDL,
850                 edl,
851                 1);
853         update_plugin_guis();
854         gui->update(1,
855                 1,      // 1 for incremental drawing.  2 for full refresh
856                 0,
857                 0,
858                 0, 
859                 0,
860                 0);
863 void MWindow::move_plugins_up(PluginSet *plugin_set)
866         plugin_set->track->move_plugins_up(plugin_set);
868         save_backup();
869         undo->update_undo(_("move effect up"), LOAD_ALL);
870         restart_brender();
871         gui->update(1,
872                 1,      // 1 for incremental drawing.  2 for full refresh
873                 0,
874                 0,
875                 0, 
876                 0,
877                 0);
878         sync_parameters(CHANGE_EDL);
881 void MWindow::move_plugins_down(PluginSet *plugin_set)
884         plugin_set->track->move_plugins_down(plugin_set);
886         save_backup();
887         undo->update_undo(_("move effect down"), LOAD_ALL);
888         restart_brender();
889         gui->update(1,
890                 1,      // 1 for incremental drawing.  2 for full refresh
891                 0,
892                 0,
893                 0, 
894                 0,
895                 0);
896         sync_parameters(CHANGE_EDL);
899 void MWindow::move_track_down(Track *track)
901         edl->tracks->move_track_down(track);
902         save_backup();
903         undo->update_undo(_("move track down"), LOAD_ALL);
905         restart_brender();
906         gui->update(1, 1, 0, 0, 1, 0, 0);
907         sync_parameters(CHANGE_EDL);
908         save_backup();
911 void MWindow::move_tracks_down()
913         edl->tracks->move_tracks_down();
914         save_backup();
915         undo->update_undo(_("move tracks down"), LOAD_ALL);
917         restart_brender();
918         gui->update(1, 1, 0, 0, 1, 0, 0);
919         sync_parameters(CHANGE_EDL);
920         save_backup();
923 void MWindow::move_track_up(Track *track)
925         edl->tracks->move_track_up(track);
926         save_backup();
927         undo->update_undo(_("move track up"), LOAD_ALL);
928         restart_brender();
929         gui->update(1, 1, 0, 0, 1, 0, 0);
930         sync_parameters(CHANGE_EDL);
931         save_backup();
934 void MWindow::move_tracks_up()
936         edl->tracks->move_tracks_up();
937         save_backup();
938         undo->update_undo(_("move tracks up"), LOAD_ALL);
939         restart_brender();
940         gui->update(1, 1, 0, 0, 1, 0, 0);
941         sync_parameters(CHANGE_EDL);
945 void MWindow::mute_selection()
947         double start = edl->local_session->get_selectionstart();
948         double end = edl->local_session->get_selectionend();
949         if(start != end)
950         {
951                 edl->clear(start, 
952                         end, 
953                         0, 
954                         edl->session->plugins_follow_edits);
955                 edl->local_session->set_selectionend(end);
956                 edl->local_session->set_selectionstart(start);
957                 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
958                 save_backup();
959                 undo->update_undo(_("mute"), LOAD_EDITS);
961                 restart_brender();
962                 update_plugin_guis();
963                 gui->update(1, 2, 1, 1, 1, 1, 0);
964                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
965                                                                 CHANGE_EDL,
966                                                                 edl,
967                                                                 1);
968         }
973 void MWindow::overwrite(EDL *source)
975         FileXML file;
977         double src_start = source->local_session->get_selectionstart();
978         double overwrite_len = source->local_session->get_selectionend() - src_start;
979         double dst_start = edl->local_session->get_selectionstart();
980         double dst_len = edl->local_session->get_selectionend() - dst_start;
982         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
983         {
984 // in/out points or selection present and shorter than overwrite range
985 // shorten the copy range
986                 overwrite_len = dst_len;
987         }
989         source->copy(src_start, 
990                 src_start + overwrite_len, 
991                 1,
992                 0,
993                 0,
994                 &file,
995                 plugindb,
996                 "",
997                 1);
999 // HACK around paste_edl get_start/endselection on its own
1000 // so we need to clear only when not using both io points
1001 // FIXME: need to write simple overwrite_edl to be used for overwrite function
1002         if (edl->local_session->get_inpoint() < 0 || 
1003                 edl->local_session->get_outpoint() < 0)
1004                 edl->clear(dst_start, 
1005                         dst_start + overwrite_len, 
1006                         0, 
1007                         0);
1009         paste(dst_start, 
1010                 dst_start + overwrite_len, 
1011                 &file,
1012                 0,
1013                 0);
1015         edl->local_session->set_selectionstart(dst_start + overwrite_len);
1016         edl->local_session->set_selectionend(dst_start + overwrite_len);
1018         save_backup();
1019         undo->update_undo(_("overwrite"), LOAD_EDITS);
1021         restart_brender();
1022         update_plugin_guis();
1023         gui->update(1, 1, 1, 1, 0, 1, 0);
1024         sync_parameters(CHANGE_EDL);
1027 // For splice and overwrite
1028 int MWindow::paste(double start, 
1029         double end, 
1030         FileXML *file,
1031         int edit_labels,
1032         int edit_plugins)
1034         clear(0);
1036 // Want to insert with assets shared with the master EDL.
1037         insert(start, 
1038                         file,
1039                         edit_labels,
1040                         edit_plugins,
1041                         edl);
1043         return 0;
1046 // For editing use insertion point position
1047 void MWindow::paste()
1050         double start = edl->local_session->get_selectionstart();
1051         double end = edl->local_session->get_selectionend();
1052         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1054         if(len)
1055         {
1056                 char *string = new char[len + 1];
1060                 gui->get_clipboard()->from_clipboard(string, 
1061                         len, 
1062                         SECONDARY_SELECTION);
1063                 FileXML file;
1064                 file.read_from_string(string);
1069                 clear(0);
1071                 insert(start, 
1072                         &file, 
1073                         edl->session->labels_follow_edits, 
1074                         edl->session->plugins_follow_edits);
1076                 edl->optimize();
1079                 delete [] string;
1083                 save_backup();
1086                 undo->update_undo(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1087                 restart_brender();
1088                 update_plugin_guis();
1089                 gui->update(1, 2, 1, 1, 0, 1, 0);
1090                 awindow->gui->async_update_assets();
1091                 sync_parameters(CHANGE_EDL);
1092         }
1096 int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
1098         int result = 0;
1103         if(session->drag_assets->total)
1104         {
1105                 load_assets(session->drag_assets, 
1106                         position, 
1107                         LOAD_PASTE,
1108                         dest_track, 
1109                         0,
1110                         edl->session->labels_follow_edits, 
1111                         edl->session->plugins_follow_edits,
1112                         overwrite);
1113                 result = 1;
1114         }
1117         if(session->drag_clips->total)
1118         {
1119                 paste_edls(session->drag_clips, 
1120                         LOAD_PASTE, 
1121                         dest_track,
1122                         position, 
1123                         edl->session->labels_follow_edits, 
1124                         edl->session->plugins_follow_edits,
1125                         overwrite); // o
1126                 result = 1;
1127         }
1130         save_backup();
1132         undo->update_undo(_("paste assets"), LOAD_EDITS);
1133         restart_brender();
1134         gui->update(1, 
1135                 2,
1136                 1,
1137                 0,
1138                 0,
1139                 1,
1140                 0);
1141         sync_parameters(CHANGE_EDL);
1142         return result;
1145 void MWindow::load_assets(ArrayList<Asset*> *new_assets, 
1146         double position, 
1147         int load_mode,
1148         Track *first_track,
1149         RecordLabels *labels,
1150         int edit_labels,
1151         int edit_plugins,
1152         int overwrite)
1154 //printf("MWindow::load_assets 1\n");
1155         if(position < 0) position = edl->local_session->get_selectionstart();
1157         ArrayList<EDL*> new_edls;
1158         for(int i = 0; i < new_assets->total; i++)
1159         {
1160                 remove_asset_from_caches(new_assets->values[i]);
1161                 EDL *new_edl = new EDL;
1162                 new_edl->create_objects();
1163                 new_edl->copy_session(edl);
1164                 new_edls.append(new_edl);
1167 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1168                 asset_to_edl(new_edl, new_assets->values[i]);
1171                 if(labels)
1172                         for(RecordLabel *label = labels->first; label; label = label->next)
1173                         {
1174                                 new_edl->labels->toggle_label(label->position, label->position);
1175                         }
1176         }
1177 //printf("MWindow::load_assets 3\n");
1179         paste_edls(&new_edls, 
1180                 load_mode, 
1181                 first_track,
1182                 position,
1183                 edit_labels,
1184                 edit_plugins,
1185                 overwrite);
1186 //printf("MWindow::load_assets 4\n");
1189         save_backup();
1190         new_edls.remove_all_objects();
1194 int MWindow::paste_automation()
1196         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1198         if(len)
1199         {
1200                 char *string = new char[len + 1];
1201                 gui->get_clipboard()->from_clipboard(string, 
1202                         len, 
1203                         SECONDARY_SELECTION);
1204                 FileXML file;
1205                 file.read_from_string(string);
1207                 edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
1208                         edl->local_session->get_selectionend()); 
1209                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(), 
1210                         &file,
1211                         0); 
1212                 save_backup();
1213                 undo->update_undo(_("paste keyframes"), LOAD_AUTOMATION);
1214                 delete [] string;
1217                 restart_brender();
1218                 update_plugin_guis();
1219                 gui->canvas->draw_overlays();
1220                 gui->canvas->flash();
1221                 sync_parameters(CHANGE_PARAMS);
1222                 gui->patchbay->update();
1223                 cwindow->update(1, 0, 0);
1224         }
1226         return 0;
1229 int MWindow::paste_default_keyframe()
1231         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1233         if(len)
1234         {
1235                 char *string = new char[len + 1];
1236                 gui->get_clipboard()->from_clipboard(string, 
1237                         len, 
1238                         SECONDARY_SELECTION);
1239                 FileXML file;
1240                 file.read_from_string(string);
1241                 edl->tracks->paste_default_keyframe(&file); 
1242                 undo->update_undo(_("paste default keyframe"), LOAD_AUTOMATION);
1245                 restart_brender();
1246                 update_plugin_guis();
1247                 gui->canvas->draw_overlays();
1248                 gui->canvas->flash();
1249                 sync_parameters(CHANGE_PARAMS);
1250                 gui->patchbay->update();
1251                 cwindow->update(1, 0, 0);
1252                 delete [] string;
1253                 save_backup();
1254         }
1256         return 0;
1260 // Insert edls with project deletion and index file generation.
1261 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, 
1262         int load_mode, 
1263         Track *first_track,
1264         double current_position,
1265         int edit_labels,
1266         int edit_plugins,
1267         int overwrite)
1270         ArrayList<Track*> destination_tracks;
1271         int need_new_tracks = 0;
1273         if(!new_edls->total) return 0;
1276 SET_TRACE
1277         double original_length = edl->tracks->total_playable_length();
1278 SET_TRACE
1279         double original_preview_end = edl->local_session->preview_end;
1280 SET_TRACE
1282 // Delete current project
1283         if(load_mode == LOAD_REPLACE ||
1284                 load_mode == LOAD_REPLACE_CONCATENATE)
1285         {
1286                 reset_caches();
1288                 edl->save_defaults(defaults);
1290                 hide_plugins();
1292                 delete edl;
1294                 edl = new EDL;
1296                 edl->create_objects();
1298                 edl->copy_session(new_edls->values[0]);
1300                 gui->mainmenu->update_toggles(0);
1303                 gui->unlock_window();
1305                 gwindow->gui->update_toggles(1);
1307                 gui->lock_window("MWindow::paste_edls");
1310 // Insert labels for certain modes constitutively
1311                 edit_labels = 1;
1312                 edit_plugins = 1;
1313 // Force reset of preview
1314                 original_length = 0;
1315                 original_preview_end = -1;
1316         }
1318 SET_TRACE
1321 SET_TRACE
1322 // Create new tracks in master EDL
1323         if(load_mode == LOAD_REPLACE || 
1324                 load_mode == LOAD_REPLACE_CONCATENATE ||
1325                 load_mode == LOAD_NEW_TRACKS)
1326         {
1328                 need_new_tracks = 1;
1329                 for(int i = 0; i < new_edls->total; i++)
1330                 {
1331                         EDL *new_edl = new_edls->values[i];
1332                         for(Track *current = new_edl->tracks->first;
1333                                 current;
1334                                 current = NEXT)
1335                         {
1336                                 if(current->data_type == TRACK_VIDEO)
1337                                 {
1338                                         edl->tracks->add_video_track(0, 0);
1339                                         if(current->draw) edl->tracks->last->draw = 1;
1340                                         destination_tracks.append(edl->tracks->last);
1341                                 }
1342                                 else
1343                                 if(current->data_type == TRACK_AUDIO)
1344                                 {
1345                                         edl->tracks->add_audio_track(0, 0);
1346                                         destination_tracks.append(edl->tracks->last);
1347                                 }
1348                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1349                         }
1351 // Base track count on first EDL only for concatenation
1352                         if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1353                 }
1355         }
1356         else
1357 // Recycle existing tracks of master EDL
1358         if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1359         {
1361 // The point of this is to shift forward labels after the selection so they can
1362 // then be shifted back to their original locations without recursively
1363 // shifting back every paste.
1364                 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1365                         edl->labels->clear(edl->local_session->get_selectionstart(),
1366                                                 edl->local_session->get_selectionend(),
1367                                                 1);
1368         
1369                 Track *current = first_track ? first_track : edl->tracks->first;
1370                 for( ; current; current = NEXT)
1371                 {
1372                         if(current->record)
1373                         {
1374                                 destination_tracks.append(current);
1376 // This should be done in the caller so we don't get recursive clear disease.
1377 //                              if(load_mode == LOAD_PASTE)
1378 //                                      current->clear(edl->local_session->get_selectionstart(),
1379 //                                              edl->local_session->get_selectionend(),
1380 //                                              1,
1381 //                                              edl->session->labels_follow_edits, 
1382 //                                              edl->session->plugins_follow_edits,
1383 //                                              1);
1384                         }
1385                 }
1387         }
1392         int destination_track = 0;
1393         double *paste_position = new double[destination_tracks.total];
1397 SET_TRACE
1400 // Iterate through the edls
1401         for(int i = 0; i < new_edls->total; i++)
1402         {
1404                 EDL *new_edl = new_edls->values[i];
1405 SET_TRACE
1406                 double edl_length = new_edl->local_session->clipboard_length ?
1407                         new_edl->local_session->clipboard_length :
1408                         new_edl->tracks->total_length();
1409 // printf("MWindow::paste_edls 2\n");
1410 // new_edl->dump();
1412 SET_TRACE
1416 // Resample EDL to master rates
1417                 new_edl->resample(new_edl->session->sample_rate, 
1418                         edl->session->sample_rate, 
1419                         TRACK_AUDIO);
1420                 new_edl->resample(new_edl->session->frame_rate, 
1421                         edl->session->frame_rate, 
1422                         TRACK_VIDEO);
1424 SET_TRACE
1428 // Add assets and prepare index files
1429                 for(Asset *new_asset = new_edl->assets->first;
1430                         new_asset;
1431                         new_asset = new_asset->next)
1432                 {
1433                         mainindexes->add_next_asset(0, new_asset);
1434                 }
1435 SET_TRACE
1436 // Capture index file status from mainindex test
1437                 edl->update_assets(new_edl);
1439 SET_TRACE
1442 // Get starting point of insertion.  Need this to paste labels.
1443                 switch(load_mode)
1444                 {
1445                         case LOAD_REPLACE:
1446                         case LOAD_NEW_TRACKS:
1447                                 current_position = 0;
1448                                 break;
1450                         case LOAD_CONCATENATE:
1451                         case LOAD_REPLACE_CONCATENATE:
1452                                 destination_track = 0;
1453                                 if(destination_tracks.total)
1454                                         current_position = destination_tracks.values[0]->get_length();
1455                                 else
1456                                         current_position = 0;
1457                                 break;
1459                         case LOAD_PASTE:
1460                                 destination_track = 0;
1461                                 if(i == 0)
1462                                 {
1463                                         for(int j = 0; j < destination_tracks.total; j++)
1464                                         {
1465                                                 paste_position[j] = (current_position >= 0) ? 
1466                                                         current_position :
1467                                                         edl->local_session->get_selectionstart();
1468                                         }
1469                                 }
1470                                 break;
1472                         case LOAD_RESOURCESONLY:
1473                                 edl->add_clip(new_edl);
1474                                 break;
1475                 }
1480 SET_TRACE
1482 // Insert edl
1483                 if(load_mode != LOAD_RESOURCESONLY)
1484                 {
1485 // Insert labels
1486 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1487                         if(load_mode == LOAD_PASTE)
1488                                 edl->labels->insert_labels(new_edl->labels, 
1489                                         destination_tracks.total ? paste_position[0] : 0.0,
1490                                         edl_length,
1491                                         edit_labels);
1492                         else
1493                                 edl->labels->insert_labels(new_edl->labels, 
1494                                         current_position,
1495                                         edl_length,
1496                                         edit_labels);
1498                         for(Track *new_track = new_edl->tracks->first; 
1499                                 new_track; 
1500                                 new_track = new_track->next)
1501                         {
1502 // Get destination track of same type as new_track
1503                                 for(int k = 0; 
1504                                         k < destination_tracks.total &&
1505                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1506                                         k++, destination_track++)
1507                                 {
1508                                         if(destination_track >= destination_tracks.total - 1)
1509                                                 destination_track = 0;
1510                                 }
1512 // Insert data into destination track
1513                                 if(destination_track < destination_tracks.total &&
1514                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1515                                 {
1516                                         Track *track = destination_tracks.values[destination_track];
1518 // Replace default keyframes if first EDL and new tracks were created.
1519 // This means data copied from one track and pasted to another won't retain
1520 // the camera position unless it's a keyframe.  If it did, previous data in the
1521 // track might get unknowingly corrupted.  Ideally we would detect when differing
1522 // default keyframes existed and create discrete keyframes for both.
1523                                         int replace_default = (i == 0) && need_new_tracks;
1525 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1526 // Insert new track at current position
1527                                         switch(load_mode)
1528                                         {
1529                                                 case LOAD_REPLACE_CONCATENATE:
1530                                                 case LOAD_CONCATENATE:
1531                                                         current_position = track->get_length();
1532                                                         break;
1534                                                 case LOAD_PASTE:
1535                                                         current_position = paste_position[destination_track];
1536                                                         paste_position[destination_track] += new_track->get_length();
1537                                                         break;
1538                                         }
1539                                         if (overwrite)
1540                                                 track->clear(current_position, 
1541                                                                 current_position + new_track->get_length(), 
1542                                                                 1, // edit edits
1543                                                                 edit_labels,
1544                                                                 edit_plugins, 
1545                                                                 1, // convert units
1546                                                                 0); // trim edits
1549                                         track->insert_track(new_track, 
1550                                                 current_position, 
1551                                                 replace_default,
1552                                                 edit_plugins);
1553                                 }
1555 // Get next destination track
1556                                 destination_track++;
1557                                 if(destination_track >= destination_tracks.total)
1558                                         destination_track = 0;
1559                         }
1560                 }
1562 SET_TRACE
1563                 if(load_mode == LOAD_PASTE)
1564                         current_position += edl_length;
1565         }
1568 // Move loading of clips and vwindow to the end - this fixes some
1569 // strange issue, for index not being shown
1570 // Assume any paste operation from the same EDL won't contain any clips.
1571 // If it did it would duplicate every clip here.
1572         for(int i = 0; i < new_edls->total; i++)
1573         {
1574                 EDL *new_edl = new_edls->values[i];
1576                 for(int j = 0; j < new_edl->clips.total; j++)
1577                 {
1578                         edl->add_clip(new_edl->clips.values[j]);
1579                 }
1581                 if(new_edl->vwindow_edl)
1582                 {
1583                         if(edl->vwindow_edl) delete edl->vwindow_edl;
1584                         edl->vwindow_edl = new EDL(edl);
1585                         edl->vwindow_edl->create_objects();
1586                         edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1587                 }
1588         }
1591 SET_TRACE
1592         if(paste_position) delete [] paste_position;
1595 SET_TRACE
1596 // This is already done in load_filenames and everything else that uses paste_edls
1597 //      update_project(load_mode);
1599 // Fix preview range
1600         if(EQUIV(original_length, original_preview_end))
1601         {
1602                 edl->local_session->preview_end = edl->tracks->total_playable_length();
1603         }
1606 SET_TRACE
1607 // Start examining next batch of index files
1608         mainindexes->start_build();
1609 SET_TRACE
1612 // Don't save a backup after loading since the loaded file is on disk already.
1615         return 0;
1618 void MWindow::paste_silence()
1620         double start = edl->local_session->get_selectionstart();
1621         double end = edl->local_session->get_selectionend();
1622         edl->paste_silence(start, 
1623                 end, 
1624                 edl->session->labels_follow_edits, 
1625                 edl->session->plugins_follow_edits);
1626         edl->optimize();
1627         save_backup();
1628         undo->update_undo(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1630         update_plugin_guis();
1631         restart_brender();
1632         gui->update(1, 2, 1, 1, 1, 1, 0);
1633         cwindow->update(1, 0, 0, 0, 1);
1634         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1635                                                         CHANGE_EDL,
1636                                                         edl,
1637                                                         1);
1640 void MWindow::paste_transition()
1642 // Only the first transition gets dropped.
1643         PluginServer *server = session->drag_pluginservers->values[0];
1644         if(server->audio)
1645                 strcpy(edl->session->default_atransition, server->title);
1646         else
1647                 strcpy(edl->session->default_vtransition, server->title);
1649         edl->tracks->paste_transition(server, session->edit_highlighted);
1650         save_backup();
1651         undo->update_undo(_("transition"), LOAD_EDITS);
1653         if(server->video) restart_brender();
1654         sync_parameters(CHANGE_ALL);
1657 void MWindow::paste_transition_cwindow(Track *dest_track)
1659         PluginServer *server = session->drag_pluginservers->values[0];
1660         edl->tracks->paste_video_transition(server, 1);
1661         save_backup();
1662         undo->update_undo(_("transition"), LOAD_EDITS);
1663         restart_brender();
1664         gui->update(0, 1, 0, 0, 0, 0, 0);
1665         sync_parameters(CHANGE_ALL);
1668 void MWindow::paste_audio_transition()
1670         PluginServer *server = scan_plugindb(edl->session->default_atransition,
1671                 TRACK_AUDIO);
1672         if(!server)
1673         {
1674                 char string[BCTEXTLEN];
1675                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1676                 gui->show_message(string);
1677                 return;
1678         }
1680         edl->tracks->paste_audio_transition(server);
1681         save_backup();
1682         undo->update_undo(_("transition"), LOAD_EDITS);
1684         sync_parameters(CHANGE_ALL);
1685         gui->update(0, 1, 0, 0, 0, 0, 0);
1688 void MWindow::paste_video_transition()
1690         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1691                 TRACK_VIDEO);
1692         if(!server)
1693         {
1694                 char string[BCTEXTLEN];
1695                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1696                 gui->show_message(string);
1697                 return;
1698         }
1701         edl->tracks->paste_video_transition(server);
1702         save_backup();
1703         undo->update_undo(_("transition"), LOAD_EDITS);
1705         sync_parameters(CHANGE_ALL);
1706         restart_brender();
1707         gui->update(0, 1, 0, 0, 0, 0, 0);
1711 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1714         calling_window_gui->unlock_window();
1716         cwindow->playback_engine->que->send_command(STOP,
1717                 CHANGE_NONE, 
1718                 0,
1719                 0);
1720         vwindow->playback_engine->que->send_command(STOP,
1721                 CHANGE_NONE, 
1722                 0,
1723                 0);
1724         cwindow->playback_engine->interrupt_playback(0);
1725         vwindow->playback_engine->interrupt_playback(0);
1728         cwindow->gui->lock_window("MWindow::redo_entry");
1729         vwindow->gui->lock_window("MWindow::undo_entry 2");
1730         gui->lock_window();
1732         undo->redo(); 
1734         save_backup();
1735         update_plugin_states();
1736         update_plugin_guis();
1737         restart_brender();
1738         gui->update(1, 2, 1, 1, 1, 1, 1);
1739         cwindow->update(1, 1, 1, 1, 1);
1741         if (calling_window_gui != cwindow->gui) 
1742                 cwindow->gui->unlock_window();
1743         if (calling_window_gui != gui)
1744                 gui->unlock_window();
1745         if (calling_window_gui != vwindow->gui)
1746                 vwindow->gui->unlock_window();
1748         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1749                            CHANGE_ALL,
1750                            edl,
1751                            1);
1752         
1756 void MWindow::resize_track(Track *track, int w, int h)
1758 // We have to move all maskpoints so they do not move in relation to image areas
1759         ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1760                 (w - track->track_w) / 2, 
1761                 (h - track->track_h) / 2);
1762         track->track_w = w;
1763         track->track_h = h;
1764         undo->update_undo(_("resize track"), LOAD_ALL);
1765         save_backup();
1767         restart_brender();
1768         sync_parameters(CHANGE_EDL);
1772 class InPointUndoItem : public UndoStackItem
1774 public:
1775         InPointUndoItem(double old_position, double new_position, EDL *edl);
1776         void undo();
1777         int get_size();
1778 private:
1779         double old_position;
1780         double new_position;
1781         EDL *edl;
1784 InPointUndoItem::InPointUndoItem(
1785       double old_position, double new_position, EDL *edl)
1787    set_description(_("in point"));
1788    this->old_position = old_position;
1789    this->new_position = new_position;
1790    this->edl = edl;
1793 void InPointUndoItem::undo()
1795    edl->set_inpoint(old_position);
1796 // prepare to undo the undo
1797         double tmp = new_position;
1798         new_position = old_position;
1799         old_position = tmp;
1802 int InPointUndoItem::get_size()
1804    return 20;
1807 void MWindow::set_inpoint(int is_mwindow)
1809    InPointUndoItem *undo_item;
1811    undo_item = new InPointUndoItem(edl->local_session->get_inpoint(),
1812          edl->local_session->get_selectionstart(1), edl);
1813    undo->push_undo_item(undo_item);
1815         edl->set_inpoint(edl->local_session->get_selectionstart(1));
1816         save_backup();
1818         if(!is_mwindow)
1819         {
1820                 gui->lock_window("MWindow::set_inpoint 1");
1821         }
1822         gui->timebar->update();
1823         gui->flush();
1824         if(!is_mwindow)
1825         {
1826                 gui->unlock_window();
1827         }
1829         if(is_mwindow)
1830         {
1831                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1832         }
1833         cwindow->gui->timebar->update();
1834         cwindow->gui->flush();
1835         if(is_mwindow)
1836         {
1837                 cwindow->gui->unlock_window();
1838         }
1841 class OutPointUndoItem : public UndoStackItem
1843 public:
1844         OutPointUndoItem(double old_position, double new_position, EDL *edl);
1845         void undo();
1846         int get_size();
1847 private:
1848         double old_position;
1849         double new_position;
1850         EDL *edl;
1853 OutPointUndoItem::OutPointUndoItem(
1854       double old_position, double new_position, EDL *edl)
1856    set_description(_("out point"));
1857    this->old_position = old_position;
1858    this->new_position = new_position;
1859    this->edl = edl;
1862 void OutPointUndoItem::undo()
1864    edl->set_outpoint(old_position);
1865 // prepare to undo the undo
1866         double tmp = new_position;
1867         new_position = old_position;
1868         old_position = tmp;
1871 int OutPointUndoItem::get_size()
1873    return 20;
1876 void MWindow::set_outpoint(int is_mwindow)
1878    OutPointUndoItem *undo_item;
1880    undo_item = new OutPointUndoItem(edl->local_session->get_outpoint(),
1881          edl->local_session->get_selectionend(1), edl);
1882    undo->push_undo_item(undo_item);
1884         edl->set_outpoint(edl->local_session->get_selectionend(1));
1885         save_backup();
1887         if(!is_mwindow)
1888         {
1889                 gui->lock_window("MWindow::set_outpoint 1");
1890         }
1891         gui->timebar->update();
1892         gui->flush();
1893         if(!is_mwindow)
1894         {
1895                 gui->unlock_window();
1896         }
1898         if(is_mwindow)
1899         {
1900                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1901         }
1902         cwindow->gui->timebar->update();
1903         cwindow->gui->flush();
1904         if(is_mwindow)
1905         {
1906                 cwindow->gui->unlock_window();
1907         }
1910 void MWindow::splice(EDL *source)
1912         FileXML file;
1914         source->copy(source->local_session->get_selectionstart(), 
1915                 source->local_session->get_selectionend(), 
1916                 1,
1917                 0,
1918                 0,
1919                 &file,
1920                 plugindb,
1921                 "",
1922                 1);
1926 //file.dump();
1927         double start = edl->local_session->get_selectionstart();
1928         double end = edl->local_session->get_selectionend();
1929         double source_start = source->local_session->get_selectionstart();
1930         double source_end = source->local_session->get_selectionend();
1932         paste(start, 
1933                 start, 
1934                 &file,
1935                 edl->session->labels_follow_edits,
1936                 edl->session->plugins_follow_edits);
1938 // Position at end of clip
1939         edl->local_session->set_selectionstart(start + 
1940                 source_end - 
1941                 source_start);
1942         edl->local_session->set_selectionend(start + 
1943                 source_end - 
1944                 source_start);
1946         save_backup();
1947         undo->update_undo(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1948         update_plugin_guis();
1949         restart_brender();
1950         gui->update(1, 1, 1, 1, 0, 1, 0);
1951         sync_parameters(CHANGE_EDL);
1954 void MWindow::to_clip()
1956         FileXML file;
1957         double start, end;
1958         
1959         start = edl->local_session->get_selectionstart();
1960         end = edl->local_session->get_selectionend();
1962         if(EQUIV(end, start)) 
1963         {
1964                 start = 0;
1965                 end = edl->tracks->total_length();
1966         }
1968 // Don't copy all since we don't want the clips twice.
1969         edl->copy(start, 
1970                 end, 
1971                 0,
1972                 0,
1973                 0,
1974                 &file,
1975                 plugindb,
1976                 "",
1977                 1);
1980         EDL *new_edl = new EDL(edl);
1981         new_edl->create_objects();
1982         new_edl->load_xml(plugindb, &file, LOAD_ALL);
1983         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1984         char string[BCTEXTLEN];
1985         Units::totext(string, 
1986                         end - start, 
1987                         edl->session->time_format, 
1988                         edl->session->sample_rate, 
1989                         edl->session->frame_rate,
1990                         edl->session->frames_per_foot);
1992         sprintf(new_edl->local_session->clip_notes, _("%s\nCreated from main window"), string);
1994         new_edl->local_session->set_selectionstart(0);
1995         new_edl->local_session->set_selectionend(0);
1997         awindow->clip_edit->create_clip(new_edl);
1998         save_backup();
2001 class LabelUndoItem : public UndoStackItem
2003 public:
2004       LabelUndoItem(double position1, double position2, EDL *edl);
2005       void undo();
2006       int get_size();
2007 private:
2008       double position1;
2009       double position2;
2010       EDL *edl;
2013 LabelUndoItem::LabelUndoItem(
2014       double position1, double position2, EDL *edl)
2016    set_description(_("label"));
2017    this->position1 = position1;
2018    this->position2 = position2;
2019    this->edl = edl;
2022 void LabelUndoItem::undo()
2024         edl->labels->toggle_label(position1, position2);
2027 int LabelUndoItem::get_size()
2029    return 20;
2032 int MWindow::toggle_label(int is_mwindow)
2034    LabelUndoItem *undo_item;
2035         double position1, position2;
2037         if(cwindow->playback_engine->is_playing_back)
2038         {
2039                 position1 = position2 = 
2040                         cwindow->playback_engine->get_tracking_position();
2041         }
2042         else
2043         {
2044                 position1 = edl->local_session->get_selectionstart(1);
2045                 position2 = edl->local_session->get_selectionend(1);
2046         }
2048         position1 = edl->align_to_frame(position1, 0);
2049         position2 = edl->align_to_frame(position2, 0);
2051 //printf("MWindow::toggle_label 1\n");
2052    undo_item = new LabelUndoItem(position1, position2, edl);
2053    undo->push_undo_item(undo_item);
2055         edl->labels->toggle_label(position1, position2);
2056         save_backup();
2058         if(!is_mwindow)
2059         {
2060                 gui->lock_window("MWindow::toggle_label 1");
2061         }
2062         gui->timebar->update();
2063         gui->canvas->activate();
2064         gui->flush();
2065         if(!is_mwindow)
2066         {
2067                 gui->unlock_window();
2068         }
2070         if(is_mwindow)
2071         {
2072                 cwindow->gui->lock_window("MWindow::toggle_label 2");
2073         }
2074         cwindow->gui->timebar->update();
2075         cwindow->gui->flush();
2076         if(is_mwindow)
2077         {
2078                 cwindow->gui->unlock_window();
2079         }
2081         return 0;
2084 void MWindow::trim_selection()
2088         edl->trim_selection(edl->local_session->get_selectionstart(), 
2089                 edl->local_session->get_selectionend(), 
2090                 edl->session->labels_follow_edits, 
2091                 edl->session->plugins_follow_edits);
2093         save_backup();
2094         undo->update_undo(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
2095         update_plugin_guis();
2096         gui->update(1, 2, 1, 1, 1, 1, 0);
2097         restart_brender();
2098         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2099                                                         CHANGE_EDL,
2100                                                         edl,
2101                                                         1);
2106 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2108 //      if(is_mwindow)
2109 //              gui->unlock_window();
2110 //      else
2111 //              cwindow->gui->unlock_window();
2112         calling_window_gui->unlock_window();
2114         cwindow->playback_engine->que->send_command(STOP,
2115                 CHANGE_NONE, 
2116                 0,
2117                 0);
2118         vwindow->playback_engine->que->send_command(STOP,
2119                 CHANGE_NONE, 
2120                 0,
2121                 0);
2122         cwindow->playback_engine->interrupt_playback(0);
2123         vwindow->playback_engine->interrupt_playback(0);
2125         cwindow->gui->lock_window("MWindow::undo_entry 1");
2126         vwindow->gui->lock_window("MWindow::undo_entry 4");
2127         gui->lock_window("MWindow::undo_entry 2");
2129         undo->undo(); 
2131         save_backup();
2132         restart_brender();
2133         update_plugin_states();
2134         update_plugin_guis();
2135         gui->update(1, 2, 1, 1, 1, 1, 1);
2136         cwindow->update(1, 1, 1, 1, 1);
2138 //      if(is_mwindow)
2139 //              cwindow->gui->unlock_window();
2140 //      else
2141 //              gui->unlock_window();
2142         if (calling_window_gui != cwindow->gui) 
2143                 cwindow->gui->unlock_window();
2144         if (calling_window_gui != gui)
2145                 gui->unlock_window();
2146         if (calling_window_gui != vwindow->gui)
2147                 vwindow->gui->unlock_window();
2148         
2150         awindow->gui->async_update_assets();
2151         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2152                            CHANGE_ALL,
2153                            edl,
2154                            1);
2159 void MWindow::new_folder(char *new_folder)
2161         edl->new_folder(new_folder);
2162         undo->update_undo(_("new folder"), LOAD_ALL);
2163         awindow->gui->async_update_assets();
2166 void MWindow::delete_folder(char *folder)
2168 //      undo->update_undo(_("delete folder"), LOAD_ALL);
2171 void MWindow::select_point(double position)
2173         edl->local_session->set_selectionstart(position);
2174         edl->local_session->set_selectionend(position);
2176 // Que the CWindow
2177         cwindow->update(1, 0, 0, 0, 1);
2178         update_plugin_guis();
2179         gui->patchbay->update();
2180         gui->cursor->hide(0);
2181         gui->cursor->draw(1);
2182         gui->mainclock->update(edl->local_session->get_selectionstart(1));
2183         gui->zoombar->update();
2184         gui->canvas->flash();
2185         gui->flush();
2191 void MWindow::map_audio(int pattern)
2193         int current_channel = 0;
2194         int current_track = 0;
2195         for(Track *current = edl->tracks->first; current; current = NEXT)
2196         {
2197                 if(current->data_type == TRACK_AUDIO && 
2198                         current->record)
2199                 {
2200                         Autos *pan_autos = current->automation->autos[AUTOMATION_PAN];
2201                         PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1);
2203                         for(int i = 0; i < MAXCHANNELS; i++)
2204                         {
2205                                 pan_auto->values[i] = 0.0;
2206                         }
2208                         if(pattern == MWindow::AUDIO_1_TO_1)
2209                         {
2210                                 pan_auto->values[current_channel] = 1.0;
2211                         }
2212                         else
2213                         if(pattern == MWindow::AUDIO_5_1_TO_2)
2214                         {
2215                                 switch(current_track)
2216                                 {
2217                                         case 0:
2218                                                 pan_auto->values[0] = 0.5;
2219                                                 pan_auto->values[1] = 0.5;
2220                                                 break;
2221                                         case 1:
2222                                                 pan_auto->values[0] = 1;
2223                                                 break;
2224                                         case 2:
2225                                                 pan_auto->values[1] = 1;
2226                                                 break;
2227                                         case 3:
2228                                                 pan_auto->values[0] = 1;
2229                                                 break;
2230                                         case 4:
2231                                                 pan_auto->values[1] = 1;
2232                                                 break;
2233                                         case 5:
2234                                                 pan_auto->values[0] = 0.5;
2235                                                 pan_auto->values[1] = 0.5;
2236                                                 break;
2237                                 }
2238                         }
2239                         
2240                         BC_Pan::calculate_stick_position(edl->session->audio_channels, 
2241                                 edl->session->achannel_positions, 
2242                                 pan_auto->values, 
2243                                 MAX_PAN, 
2244                                 PAN_RADIUS,
2245                                 pan_auto->handle_x,
2246                                 pan_auto->handle_y);
2247                 
2248                         current_channel++;
2249                         current_track++;
2250                         if(current_channel >= edl->session->audio_channels)
2251                                 current_channel = 0;
2252                 }
2253         }
2254         undo->update_undo(_("map 1:1"), LOAD_AUTOMATION, 0);
2255         sync_parameters(CHANGE_PARAMS);
2256         gui->update(0,
2257                 1,
2258                 0,
2259                 0,
2260                 1,
2261                 0,
2262                 0);