r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / mwindowedit.C
blobf510825e9d801bada9d17e24fd6e79cf2e9d460e
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 "defaults.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 "mainindexes.h"
27 #include "mainmenu.h"
28 #include "mainsession.h"
29 #include "mainundo.h"
30 #include "maskautos.h"
31 #include "mtimebar.h"
32 #include "mwindowgui.h"
33 #include "mwindow.h"
34 #include "patchbay.h"
35 #include "playbackengine.h"
36 #include "pluginset.h"
37 #include "recordlabel.h"
38 #include "samplescroll.h"
39 #include "trackcanvas.h"
40 #include "track.h"
41 #include "trackscroll.h"
42 #include "tracks.h"
43 #include "transition.h"
44 #include "transportque.h"
45 #include "units.h"
46 #include "undostackitem.h"
47 #include "vplayback.h"
48 #include "vwindow.h"
49 #include "vwindowgui.h"
50 #include "zoombar.h"
51 #include "automation.h"
52 #include "maskautos.h"
55 #include <string.h>
62 void MWindow::add_audio_track_entry(int above, Track *dst)
64         add_audio_track(above, dst);
65         save_backup();
66         undo->update_undo(_("add track"), LOAD_ALL);
68         restart_brender();
69         gui->get_scrollbars();
70         gui->canvas->draw();
71         gui->patchbay->update();
72         gui->cursor->draw();
73         gui->canvas->flash();
74         gui->canvas->activate();
75         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
76                 CHANGE_EDL,
77                 edl,
78                 1);
81 void MWindow::add_video_track_entry(Track *dst)
83         add_video_track(1, dst);
84         undo->update_undo(_("add track"), LOAD_ALL);
86         restart_brender();
87         gui->get_scrollbars();
88         gui->canvas->draw();
89         gui->patchbay->update();
90         gui->cursor->draw();
91         gui->canvas->flash();
92         gui->canvas->activate();
93         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
94                                                         CHANGE_EDL,
95                                                         edl,
96                                                         1);
97         save_backup();
101 int MWindow::add_audio_track(int above, Track *dst)
103         edl->tracks->add_audio_track(above, dst);
104         edl->tracks->update_y_pixels(theme);
105         save_backup();
106         return 0;
109 int MWindow::add_video_track(int above, Track *dst)
111         edl->tracks->add_video_track(above, dst);
112         edl->tracks->update_y_pixels(theme);
113         save_backup();
114         return 0;
121 void MWindow::asset_to_size()
123         if(session->drag_assets->total &&
124                 session->drag_assets->values[0]->video_data)
125         {
126                 int w, h;
128 // Get w and h
129                 w = session->drag_assets->values[0]->width;
130                 h = session->drag_assets->values[0]->height;
133                 edl->session->output_w = w;
134                 edl->session->output_h = h;
136 // Get aspect ratio
137                 if(defaults->get("AUTOASPECT", 0))
138                 {
139                         create_aspect_ratio(edl->session->aspect_w, 
140                                 edl->session->aspect_h, 
141                                 w, 
142                                 h);
143                 }
145                 save_backup();
147                 undo->update_undo(_("asset to size"), LOAD_ALL);
148                 restart_brender();
149                 sync_parameters(CHANGE_ALL);
150         }
155 void MWindow::clear_entry()
157         clear(1);
159         edl->optimize();
160         save_backup();
161         undo->update_undo(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
163         restart_brender();
164         update_plugin_guis();
165         gui->update(1, 2, 1, 1, 1, 1, 0);
166         cwindow->update(1, 0, 0, 0, 1);
167         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
168                            CHANGE_EDL,
169                            edl,
170                            1);
173 void MWindow::clear(int clear_handle)
175         double start = edl->local_session->get_selectionstart();
176         double end = edl->local_session->get_selectionend();
177         if(clear_handle || !EQUIV(start, end))
178         {
179                 edl->clear(start, 
180                         end, 
181                         edl->session->labels_follow_edits, 
182                         edl->session->plugins_follow_edits);
183         }
186 void MWindow::clear_automation()
188         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
189                 edl->local_session->get_selectionend()); 
190         save_backup();
191         undo->update_undo(_("clear keyframes"), LOAD_AUTOMATION); 
193         restart_brender();
194         update_plugin_guis();
195         gui->canvas->draw_overlays();
196         gui->canvas->flash();
197         sync_parameters(CHANGE_PARAMS);
198         gui->patchbay->update();
199         cwindow->update(1, 0, 0);
202 int MWindow::clear_default_keyframe()
204         edl->tracks->clear_default_keyframe();
205         save_backup();
206         undo->update_undo(_("clear default keyframe"), LOAD_AUTOMATION);
207         
208         restart_brender();
209         gui->canvas->draw_overlays();
210         gui->canvas->flash();
211         sync_parameters(CHANGE_PARAMS);
212         gui->patchbay->update();
213         cwindow->update(1, 0, 0);
214         
215         return 0;
218 void MWindow::clear_labels()
220         clear_labels(edl->local_session->get_selectionstart(), 
221                 edl->local_session->get_selectionend()); 
222         undo->update_undo(_("clear labels"), LOAD_TIMEBAR);
223         
224         gui->timebar->update();
225         cwindow->update(0, 0, 0, 0, 1);
226         save_backup();
229 int MWindow::clear_labels(double start, double end)
231         edl->labels->clear(start, end, 0);
232         return 0;
235 void MWindow::concatenate_tracks()
237         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
238         save_backup();
239         undo->update_undo(_("concatenate tracks"), LOAD_EDITS);
241         restart_brender();
242         gui->update(1, 1, 0, 0, 1, 0, 0);
243         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
244                 CHANGE_EDL,
245                 edl,
246                 1);
250 void MWindow::copy()
252         copy(edl->local_session->get_selectionstart(), 
253                 edl->local_session->get_selectionend());
256 int MWindow::copy(double start, double end)
258         if(start == end) return 1;
260 //printf("MWindow::copy 1\n");
261         FileXML file;
262 //printf("MWindow::copy 1\n");
263         edl->copy(start, 
264                 end, 
265                 0,
266                 0,
267                 0,
268                 &file, 
269                 plugindb,
270                 "",
271                 1);
272 //printf("MWindow::copy 1\n");
274 // File is now terminated and rewound
276 //printf("MWindow::copy 1\n");
277         gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
278 //printf("MWindow::copy\n%s\n", file.string);
279 //printf("MWindow::copy 2\n");
280         save_backup();
281         return 0;
284 int MWindow::copy_automation()
286         FileXML file;
287         edl->tracks->copy_automation(edl->local_session->get_selectionstart(), 
288                 edl->local_session->get_selectionend(),
289                 &file,
290                 0,
291                 0); 
292         gui->get_clipboard()->to_clipboard(file.string, 
293                 strlen(file.string), 
294                 SECONDARY_SELECTION);
295         return 0;
298 int MWindow::copy_default_keyframe()
300         FileXML file;
301         edl->tracks->copy_default_keyframe(&file);
302         gui->get_clipboard()->to_clipboard(file.string,
303                 strlen(file.string),
304                 SECONDARY_SELECTION);
305         return 0;
309 // Uses cropping coordinates in edl session to crop and translate video.
310 // We modify the projector since camera automation depends on the track size.
311 void MWindow::crop_video()
314 // Clamp EDL crop region
315         if(edl->session->crop_x1 > edl->session->crop_x2)
316         {
317                 edl->session->crop_x1 ^= edl->session->crop_x2;
318                 edl->session->crop_x2 ^= edl->session->crop_x1;
319                 edl->session->crop_x1 ^= edl->session->crop_x2;
320         }
321         if(edl->session->crop_y1 > edl->session->crop_y2)
322         {
323                 edl->session->crop_y1 ^= edl->session->crop_y2;
324                 edl->session->crop_y2 ^= edl->session->crop_y1;
325                 edl->session->crop_y1 ^= edl->session->crop_y2;
326         }
328         float old_projector_x = (float)edl->session->output_w / 2;
329         float old_projector_y = (float)edl->session->output_h / 2;
330         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
331         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
332         float projector_offset_x = -(new_projector_x - old_projector_x);
333         float projector_offset_y = -(new_projector_y - old_projector_y);
335         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
337         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
338         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
339         edl->session->crop_x1 = 0;
340         edl->session->crop_y1 = 0;
341         edl->session->crop_x2 = edl->session->output_w;
342         edl->session->crop_y2 = edl->session->output_h;
344 // Recalculate aspect ratio
345         if(defaults->get("AUTOASPECT", 0))
346         {
347                 create_aspect_ratio(edl->session->aspect_w, 
348                         edl->session->aspect_h, 
349                         edl->session->output_w, 
350                         edl->session->output_h);
351         }
353         undo->update_undo(_("crop"), LOAD_ALL);
355         restart_brender();
356         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
357                 CHANGE_ALL,
358                 edl,
359                 1);
360         save_backup();
363 void MWindow::cut()
366         double start = edl->local_session->get_selectionstart();
367         double end = edl->local_session->get_selectionend();
369         copy(start, end);
370         edl->clear(start, 
371                 end,
372                 edl->session->labels_follow_edits, 
373                 edl->session->plugins_follow_edits);
376         edl->optimize();
377         save_backup();
378         undo->update_undo(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
380         restart_brender();
381         update_plugin_guis();
382         gui->update(1, 2, 1, 1, 1, 1, 0);
383         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
384                                                         CHANGE_EDL,
385                                                         edl,
386                                                         1);
389 int MWindow::cut_automation()
391         
392         copy_automation();
394         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
395                 edl->local_session->get_selectionend()); 
396         save_backup();
397         undo->update_undo(_("cut keyframes"), LOAD_AUTOMATION); 
400         restart_brender();
401         update_plugin_guis();
402         gui->canvas->draw_overlays();
403         gui->canvas->flash();
404         sync_parameters(CHANGE_PARAMS);
405         gui->patchbay->update();
406         cwindow->update(1, 0, 0);
407         return 0;
410 int MWindow::cut_default_keyframe()
413         copy_default_keyframe();
414         edl->tracks->clear_default_keyframe();
415         undo->update_undo(_("cut default keyframe"), LOAD_AUTOMATION);
417         restart_brender();
418         gui->canvas->draw_overlays();
419         gui->canvas->flash();
420         sync_parameters(CHANGE_PARAMS);
421         gui->patchbay->update();
422         cwindow->update(1, 0, 0);
423         save_backup();
426         return 0;
429 void MWindow::delete_inpoint()
431         edl->local_session->unset_inpoint();
432         save_backup();
435 void MWindow::delete_outpoint()
437         edl->local_session->unset_outpoint();
438         save_backup();
441 void MWindow::delete_track()
443         if (edl->tracks->last)
444                 delete_track(edl->tracks->last);
447 void MWindow::delete_tracks()
449         edl->tracks->delete_tracks();
450         undo->update_undo(_("delete tracks"), LOAD_ALL);
451         save_backup();
453         restart_brender();
454         update_plugin_states();
455         gui->update(1, 1, 1, 0, 1, 0, 0);
456         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
457                            CHANGE_EDL,
458                            edl,
459                            1);
462 void MWindow::delete_track(Track *track)
464         edl->tracks->delete_track(track);
465         undo->update_undo(_("delete track"), LOAD_ALL);
467         restart_brender();
468         update_plugin_states();
469         gui->update(1, 1, 1, 0, 1, 0, 0);
470         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
471                            CHANGE_EDL,
472                            edl,
473                            1);
474         save_backup();
477 void MWindow::detach_transition(Transition *transition)
479         hide_plugin(transition, 1);
480         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
481         transition->edit->detach_transition();
482         save_backup();
483         undo->update_undo(_("detach transition"), LOAD_ALL);
485         if(is_video) restart_brender();
486         gui->update(0,
487                 1,
488                 0,
489                 0,
490                 0, 
491                 0,
492                 0);
493         sync_parameters(CHANGE_EDL);
500 // Insert data from clipboard
501 void MWindow::insert(double position, 
502         FileXML *file,
503         int edit_labels,
504         int edit_plugins,
505         EDL *parent_edl)
507 // For clipboard pasting make the new edl use a separate session 
508 // from the master EDL.  Then it can be resampled to the master rates.
509 // For splice, overwrite, and dragging need same session to get the assets.
510         EDL edl(parent_edl);
511         ArrayList<EDL*> new_edls;
512         uint32_t load_flags = LOAD_ALL;
513 SET_TRACE
515         new_edls.append(&edl);
516         edl.create_objects();
517 SET_TRACE
521         if(parent_edl) load_flags &= ~LOAD_SESSION;
522         if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
523         if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
524 SET_TRACE
525         edl.load_xml(plugindb, file, load_flags);
527 SET_TRACE
532         paste_edls(&new_edls, 
533                 LOAD_PASTE, 
534                 0, 
535                 position,
536                 edit_labels,
537                 edit_plugins);
538 // if(vwindow->edl)
539 // printf("MWindow::insert 5 %f %f\n", 
540 // vwindow->edl->local_session->in_point,
541 // vwindow->edl->local_session->out_point);
542         new_edls.remove_all();
543 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
546 void MWindow::insert_effects_canvas(double start,
547         double length)
549         Track *dest_track = session->track_highlighted;
550         if(!dest_track) return;
553         for(int i = 0; i < session->drag_pluginservers->total; i++)
554         {
555                 PluginServer *plugin = session->drag_pluginservers->values[i];
557                 insert_effect(plugin->title,
558                         0,
559                         dest_track,
560                         i == 0 ? session->pluginset_highlighted : 0,
561                         start,
562                         length,
563                         PLUGIN_STANDALONE);
564         }
566         save_backup();
567         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
568         restart_brender();
569         sync_parameters(CHANGE_EDL);
570 // GUI updated in TrackCanvas, after current_operations are reset
573 void MWindow::insert_effects_cwindow(Track *dest_track)
575         if(!dest_track) return;
578         double start = 0;
579         double length = dest_track->get_length();
581         if(edl->local_session->get_selectionend() > 
582                 edl->local_session->get_selectionstart())
583         {
584                 start = edl->local_session->get_selectionstart();
585                 length = edl->local_session->get_selectionend() - 
586                         edl->local_session->get_selectionstart();
587         }
589         for(int i = 0; i < session->drag_pluginservers->total; i++)
590         {
591                 PluginServer *plugin = session->drag_pluginservers->values[i];
594                 insert_effect(plugin->title,
595                         0,
596                         dest_track,
597                         0,
598                         start,
599                         length,
600                         PLUGIN_STANDALONE);
601         }
603         save_backup();
604         undo->update_undo(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
605         restart_brender();
606         sync_parameters(CHANGE_EDL);
607         gui->update(1,
608                 1,
609                 0,
610                 0,
611                 1,
612                 0,
613                 0);
618 void MWindow::insert_effect(char *title, 
619         SharedLocation *shared_location, 
620         Track *track,
621         PluginSet *plugin_set,
622         double start,
623         double length,
624         int plugin_type)
626         KeyFrame *default_keyframe = 0;
627         PluginServer *server = 0;
634 // Get default keyframe
635         if(plugin_type == PLUGIN_STANDALONE)
636         {
637                 default_keyframe = new KeyFrame;
638                 server = new PluginServer(*scan_plugindb(title, track->data_type));
640                 server->open_plugin(0, preferences, edl, 0, -1);
641                 server->save_data(default_keyframe);
642         }
646 // Insert plugin object
647         track->insert_effect(title, 
648                 shared_location, 
649                 default_keyframe, 
650                 plugin_set,
651                 start,
652                 length,
653                 plugin_type);
655         track->optimize();
658         if(plugin_type == PLUGIN_STANDALONE)
659         {
660                 server->close_plugin();
661                 delete server;
662                 delete default_keyframe;
663         }
666 int MWindow::modify_edithandles()
673         edl->modify_edithandles(session->drag_start, 
674                 session->drag_position, 
675                 session->drag_handle, 
676                 edl->session->edit_handle_mode[session->drag_button],
677                 edl->session->labels_follow_edits, 
678                 edl->session->plugins_follow_edits);
680         finish_modify_handles();
683 //printf("MWindow::modify_handles 1\n");
684         return 0;
687 int MWindow::modify_pluginhandles()
690         edl->modify_pluginhandles(session->drag_start, 
691                 session->drag_position, 
692                 session->drag_handle, 
693                 edl->session->edit_handle_mode[session->drag_button],
694                 edl->session->labels_follow_edits,
695                 session->trim_edits);
697         finish_modify_handles();
699         return 0;
703 // Common to edithandles and plugin handles
704 void MWindow::finish_modify_handles()
706         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
708         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
709                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
710         {
711                 edl->local_session->set_selectionstart(session->drag_position);
712                 edl->local_session->set_selectionend(session->drag_position);
713         }
714         else
715         if(edit_mode != MOVE_NO_EDITS)
716         {
717                 edl->local_session->set_selectionstart(session->drag_start);
718                 edl->local_session->set_selectionend(session->drag_start);
719         }
721         if(edl->local_session->get_selectionstart(1) < 0)
722         {
723                 edl->local_session->set_selectionstart(0);
724                 edl->local_session->set_selectionend(0);
725         }
727         save_backup();
728         undo->update_undo(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
729         restart_brender();
730         sync_parameters(CHANGE_EDL);
731         update_plugin_guis();
732         gui->update(1, 2, 1, 1, 1, 1, 0);
733         cwindow->update(1, 0, 0, 0, 1);
736 void MWindow::match_output_size(Track *track)
738         track->track_w = edl->session->output_w;
739         track->track_h = edl->session->output_h;
740         save_backup();
741         undo->update_undo(_("match output size"), LOAD_ALL);
743         restart_brender();
744         sync_parameters(CHANGE_EDL);
748 void MWindow::move_edits(ArrayList<Edit*> *edits, 
749                 Track *track,
750                 double position,
751                 int behaviour)
754         edl->tracks->move_edits(edits, 
755                 track, 
756                 position,
757                 edl->session->labels_follow_edits, 
758                 edl->session->plugins_follow_edits,
759                 behaviour);
761         save_backup();
762         undo->update_undo(_("move edit"), LOAD_ALL);
764         restart_brender();
765         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
766                 CHANGE_EDL,
767                 edl,
768                 1);
770         update_plugin_guis();
771         gui->update(1,
772                 1,      // 1 for incremental drawing.  2 for full refresh
773                 1,
774                 0,
775                 0, 
776                 0,
777                 0);
780 void MWindow::move_effect(Plugin *plugin,
781         PluginSet *dest_plugin_set,
782         Track *dest_track,
783         int64_t dest_position)
786         edl->tracks->move_effect(plugin, 
787                 dest_plugin_set, 
788                 dest_track, 
789                 dest_position);
791         save_backup();
792         undo->update_undo(_("move effect"), LOAD_ALL);
794         restart_brender();
795         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
796                 CHANGE_EDL,
797                 edl,
798                 1);
800         update_plugin_guis();
801         gui->update(1,
802                 1,      // 1 for incremental drawing.  2 for full refresh
803                 0,
804                 0,
805                 0, 
806                 0,
807                 0);
810 void MWindow::move_plugins_up(PluginSet *plugin_set)
813         plugin_set->track->move_plugins_up(plugin_set);
815         save_backup();
816         undo->update_undo(_("move effect up"), LOAD_ALL);
817         restart_brender();
818         gui->update(1,
819                 1,      // 1 for incremental drawing.  2 for full refresh
820                 0,
821                 0,
822                 0, 
823                 0,
824                 0);
825         sync_parameters(CHANGE_EDL);
828 void MWindow::move_plugins_down(PluginSet *plugin_set)
831         plugin_set->track->move_plugins_down(plugin_set);
833         save_backup();
834         undo->update_undo(_("move effect down"), LOAD_ALL);
835         restart_brender();
836         gui->update(1,
837                 1,      // 1 for incremental drawing.  2 for full refresh
838                 0,
839                 0,
840                 0, 
841                 0,
842                 0);
843         sync_parameters(CHANGE_EDL);
846 void MWindow::move_track_down(Track *track)
848         edl->tracks->move_track_down(track);
849         save_backup();
850         undo->update_undo(_("move track down"), LOAD_ALL);
852         restart_brender();
853         gui->update(1, 1, 0, 0, 1, 0, 0);
854         sync_parameters(CHANGE_EDL);
855         save_backup();
858 void MWindow::move_tracks_down()
860         edl->tracks->move_tracks_down();
861         save_backup();
862         undo->update_undo(_("move tracks down"), LOAD_ALL);
864         restart_brender();
865         gui->update(1, 1, 0, 0, 1, 0, 0);
866         sync_parameters(CHANGE_EDL);
867         save_backup();
870 void MWindow::move_track_up(Track *track)
872         edl->tracks->move_track_up(track);
873         save_backup();
874         undo->update_undo(_("move track up"), LOAD_ALL);
875         restart_brender();
876         gui->update(1, 1, 0, 0, 1, 0, 0);
877         sync_parameters(CHANGE_EDL);
878         save_backup();
881 void MWindow::move_tracks_up()
883         edl->tracks->move_tracks_up();
884         save_backup();
885         undo->update_undo(_("move tracks up"), LOAD_ALL);
886         restart_brender();
887         gui->update(1, 1, 0, 0, 1, 0, 0);
888         sync_parameters(CHANGE_EDL);
892 void MWindow::mute_selection()
894         double start = edl->local_session->get_selectionstart();
895         double end = edl->local_session->get_selectionend();
896         if(start != end)
897         {
898                 edl->clear(start, 
899                         end, 
900                         0, 
901                         edl->session->plugins_follow_edits);
902                 edl->local_session->set_selectionend(end);
903                 edl->local_session->set_selectionstart(start);
904                 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
905                 save_backup();
906                 undo->update_undo(_("mute"), LOAD_EDITS);
908                 restart_brender();
909                 update_plugin_guis();
910                 gui->update(1, 2, 1, 1, 1, 1, 0);
911                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
912                                                                 CHANGE_EDL,
913                                                                 edl,
914                                                                 1);
915         }
920 void MWindow::overwrite(EDL *source)
922         FileXML file;
924         double src_start = source->local_session->get_selectionstart();
925         double overwrite_len = source->local_session->get_selectionend() - src_start;
926         double dst_start = edl->local_session->get_selectionstart();
927         double dst_len = edl->local_session->get_selectionend() - dst_start;
929         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
930         {
931 // in/out points or selection present and shorter than overwrite range
932 // shorten the copy range
933                 overwrite_len = dst_len;
934         }
936         source->copy(src_start, 
937                 src_start + overwrite_len, 
938                 1,
939                 0,
940                 0,
941                 &file,
942                 plugindb,
943                 "",
944                 1);
946 // HACK around paste_edl get_start/endselection on its own
947 // so we need to clear only when not using both io points
948 // FIXME: need to write simple overwrite_edl to be used for overwrite function
949         if (edl->local_session->get_inpoint() < 0 || 
950                 edl->local_session->get_outpoint() < 0)
951                 edl->clear(dst_start, 
952                         dst_start + overwrite_len, 
953                         0, 
954                         0);
956         paste(dst_start, 
957                 dst_start + overwrite_len, 
958                 &file,
959                 0,
960                 0);
962         edl->local_session->set_selectionstart(dst_start + overwrite_len);
963         edl->local_session->set_selectionend(dst_start + overwrite_len);
965         save_backup();
966         undo->update_undo(_("overwrite"), LOAD_EDITS);
968         restart_brender();
969         update_plugin_guis();
970         gui->update(1, 1, 1, 1, 0, 1, 0);
971         sync_parameters(CHANGE_EDL);
974 // For splice and overwrite
975 int MWindow::paste(double start, 
976         double end, 
977         FileXML *file,
978         int edit_labels,
979         int edit_plugins)
981         clear(0);
983 // Want to insert with assets shared with the master EDL.
984         insert(start, 
985                         file,
986                         edit_labels,
987                         edit_plugins,
988                         edl);
990         return 0;
993 // For editing use insertion point position
994 void MWindow::paste()
996 SET_TRACE
997         double start = edl->local_session->get_selectionstart();
998         double end = edl->local_session->get_selectionend();
999         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1001         if(len)
1002         {
1003                 char *string = new char[len + 1];
1005 SET_TRACE
1007                 gui->get_clipboard()->from_clipboard(string, 
1008                         len, 
1009                         SECONDARY_SELECTION);
1010                 FileXML file;
1011                 file.read_from_string(string);
1013 SET_TRACE
1016                 clear(0);
1017 SET_TRACE
1018                 insert(start, 
1019                         &file, 
1020                         edl->session->labels_follow_edits, 
1021                         edl->session->plugins_follow_edits);
1022 SET_TRACE
1023                 edl->optimize();
1024 SET_TRACE
1026                 delete [] string;
1028 SET_TRACE
1030                 save_backup();
1033                 undo->update_undo(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1034                 restart_brender();
1035                 update_plugin_guis();
1036                 gui->update(1, 2, 1, 1, 0, 1, 0);
1037                 awindow->gui->update_assets();
1038                 sync_parameters(CHANGE_EDL);
1039         }
1040 SET_TRACE
1043 int MWindow::paste_assets(double position, Track *dest_track)
1045         int result = 0;
1050         if(session->drag_assets->total)
1051         {
1052                 load_assets(session->drag_assets, 
1053                         position, 
1054                         LOAD_PASTE,
1055                         dest_track, 
1056                         0,
1057                         edl->session->labels_follow_edits, 
1058                         edl->session->plugins_follow_edits);
1059                 result = 1;
1060         }
1063         if(session->drag_clips->total)
1064         {
1065                 paste_edls(session->drag_clips, 
1066                         LOAD_PASTE, 
1067                         dest_track,
1068                         position, 
1069                         edl->session->labels_follow_edits, 
1070                         edl->session->plugins_follow_edits);
1071                 result = 1;
1072         }
1075         save_backup();
1077         undo->update_undo(_("paste assets"), LOAD_EDITS);
1078         restart_brender();
1079         gui->update(1, 
1080                 2,
1081                 1,
1082                 0,
1083                 0,
1084                 1,
1085                 0);
1086         sync_parameters(CHANGE_EDL);
1087         return result;
1090 void MWindow::load_assets(ArrayList<Asset*> *new_assets, 
1091         double position, 
1092         int load_mode,
1093         Track *first_track,
1094         RecordLabels *labels,
1095         int edit_labels,
1096         int edit_plugins)
1098 //printf("MWindow::load_assets 1\n");
1099         if(position < 0) position = edl->local_session->get_selectionstart();
1101         ArrayList<EDL*> new_edls;
1102         for(int i = 0; i < new_assets->total; i++)
1103         {
1104                 EDL *new_edl = new EDL;
1105                 new_edl->create_objects();
1106                 new_edl->copy_session(edl);
1107                 new_edls.append(new_edl);
1110 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1111                 asset_to_edl(new_edl, new_assets->values[i]);
1114                 if(labels)
1115                         for(RecordLabel *label = labels->first; label; label = label->next)
1116                         {
1117                                 new_edl->labels->toggle_label(label->position, label->position);
1118                         }
1119         }
1120 //printf("MWindow::load_assets 3\n");
1122         paste_edls(&new_edls, 
1123                 load_mode, 
1124                 first_track,
1125                 position,
1126                 edit_labels,
1127                 edit_plugins);
1128 //printf("MWindow::load_assets 4\n");
1131         save_backup();
1132         new_edls.remove_all_objects();
1136 int MWindow::paste_automation()
1138         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1140         if(len)
1141         {
1142                 char *string = new char[len + 1];
1143                 gui->get_clipboard()->from_clipboard(string, 
1144                         len, 
1145                         SECONDARY_SELECTION);
1146                 FileXML file;
1147                 file.read_from_string(string);
1149                 edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
1150                         edl->local_session->get_selectionend()); 
1151                 edl->tracks->paste_automation(edl->local_session->get_selectionstart(), 
1152                         &file,
1153                         0); 
1154                 save_backup();
1155                 undo->update_undo(_("paste keyframes"), LOAD_AUTOMATION);
1156                 delete [] string;
1159                 restart_brender();
1160                 update_plugin_guis();
1161                 gui->canvas->draw_overlays();
1162                 gui->canvas->flash();
1163                 sync_parameters(CHANGE_PARAMS);
1164                 gui->patchbay->update();
1165                 cwindow->update(1, 0, 0);
1166         }
1168         return 0;
1171 int MWindow::paste_default_keyframe()
1173         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1175         if(len)
1176         {
1177                 char *string = new char[len + 1];
1178                 gui->get_clipboard()->from_clipboard(string, 
1179                         len, 
1180                         SECONDARY_SELECTION);
1181                 FileXML file;
1182                 file.read_from_string(string);
1183                 edl->tracks->paste_default_keyframe(&file); 
1184                 undo->update_undo(_("paste default keyframe"), LOAD_AUTOMATION);
1187                 restart_brender();
1188                 update_plugin_guis();
1189                 gui->canvas->draw_overlays();
1190                 gui->canvas->flash();
1191                 sync_parameters(CHANGE_PARAMS);
1192                 gui->patchbay->update();
1193                 cwindow->update(1, 0, 0);
1194                 delete [] string;
1195                 save_backup();
1196         }
1198         return 0;
1202 // Insert edls with project deletion and index file generation.
1203 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, 
1204         int load_mode, 
1205         Track *first_track,
1206         double current_position,
1207         int edit_labels,
1208         int edit_plugins)
1210 SET_TRACE
1211         ArrayList<Track*> destination_tracks;
1212         int need_new_tracks = 0;
1214         if(!new_edls->total) return 0;
1215 SET_TRACE
1216 //printf("MWindow::paste_edls 1\n");
1218 // Delete current project
1219         if(load_mode == LOAD_REPLACE ||
1220                 load_mode == LOAD_REPLACE_CONCATENATE)
1221         {
1222 SET_TRACE
1223                 edl->save_defaults(defaults);
1224 SET_TRACE
1225                 hide_plugins();
1226 SET_TRACE
1227                 delete edl;
1228 SET_TRACE
1229                 edl = new EDL;
1230 SET_TRACE
1231                 edl->create_objects();
1232 SET_TRACE
1233                 edl->copy_session(new_edls->values[0]);
1234 SET_TRACE
1235                 gui->mainmenu->update_toggles(0);
1236 SET_TRACE
1238                 gui->unlock_window();
1239 SET_TRACE
1240                 gwindow->gui->update_toggles(1);
1241 SET_TRACE
1242                 gui->lock_window("MWindow::paste_edls");
1243 SET_TRACE
1245 // Insert labels for certain modes constitutively
1246                 edit_labels = 1;
1247                 edit_plugins = 1;
1248         }
1249 SET_TRACE
1252 // Create new tracks in master EDL
1253         if(load_mode == LOAD_REPLACE || 
1254                 load_mode == LOAD_REPLACE_CONCATENATE ||
1255                 load_mode == LOAD_NEW_TRACKS)
1256         {
1257 SET_TRACE
1258                 need_new_tracks = 1;
1259                 for(int i = 0; i < new_edls->total; i++)
1260                 {
1261                         EDL *new_edl = new_edls->values[i];
1262                         for(Track *current = new_edl->tracks->first;
1263                                 current;
1264                                 current = NEXT)
1265                         {
1266                                 if(current->data_type == TRACK_VIDEO)
1267                                 {
1268                                         edl->tracks->add_video_track(0, 0);
1269                                         if(current->draw) edl->tracks->last->draw = 1;
1270                                         destination_tracks.append(edl->tracks->last);
1271                                 }
1272                                 else
1273                                 if(current->data_type == TRACK_AUDIO)
1274                                 {
1275                                         edl->tracks->add_audio_track(0, 0);
1276                                         destination_tracks.append(edl->tracks->last);
1277                                 }
1278                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1279                         }
1281 // Base track count on first EDL only for concatenation
1282                         if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1283                 }
1284 SET_TRACE
1285         }
1286         else
1287 // Recycle existing tracks of master EDL
1288         if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1289         {
1290 SET_TRACE
1291 // The point of this is to shift forward labels after the selection so they can
1292 // then be shifted back to their original locations without recursively
1293 // shifting back every paste.
1294                 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1295                         edl->labels->clear(edl->local_session->get_selectionstart(),
1296                                                 edl->local_session->get_selectionend(),
1297                                                 1);
1298         
1299                 Track *current = first_track ? first_track : edl->tracks->first;
1300                 for( ; current; current = NEXT)
1301                 {
1302                         if(current->record)
1303                         {
1304                                 destination_tracks.append(current);
1306 // This should be done in the caller so we don't get recursive clear disease.
1307 //                              if(load_mode == LOAD_PASTE)
1308 //                                      current->clear(edl->local_session->get_selectionstart(),
1309 //                                              edl->local_session->get_selectionend(),
1310 //                                              1,
1311 //                                              edl->session->labels_follow_edits, 
1312 //                                              edl->session->plugins_follow_edits,
1313 //                                              1);
1314                         }
1315                 }
1316 SET_TRACE
1317         }
1320 SET_TRACE
1322         int destination_track = 0;
1323         double *paste_position = new double[destination_tracks.total];
1325 SET_TRACE
1329 // Iterate through the edls
1330         for(int i = 0; i < new_edls->total; i++)
1331         {
1332 SET_TRACE
1333                 EDL *new_edl = new_edls->values[i];
1334                 double edl_length = new_edl->local_session->clipboard_length ?
1335                         new_edl->local_session->clipboard_length :
1336                         new_edl->tracks->total_length();
1337 // printf("MWindow::paste_edls 2\n");
1338 // new_edl->dump();
1341 SET_TRACE
1343 // Resample EDL to master rates
1344                 new_edl->resample(new_edl->session->sample_rate, 
1345                         edl->session->sample_rate, 
1346                         TRACK_AUDIO);
1347                 new_edl->resample(new_edl->session->frame_rate, 
1348                         edl->session->frame_rate, 
1349                         TRACK_VIDEO);
1351 SET_TRACE
1354 // Add assets and prepare index files
1355                 for(Asset *new_asset = new_edl->assets->first;
1356                         new_asset;
1357                         new_asset = new_asset->next)
1358                 {
1359                         mainindexes->add_next_asset(0, new_asset);
1360                 }
1361 // Capture index file status from mainindex test
1362                 edl->update_assets(new_edl);
1364 SET_TRACE
1366 // Get starting point of insertion.  Need this to paste labels.
1367                 switch(load_mode)
1368                 {
1369                         case LOAD_REPLACE:
1370                         case LOAD_NEW_TRACKS:
1371                                 current_position = 0;
1372                                 break;
1374                         case LOAD_CONCATENATE:
1375                         case LOAD_REPLACE_CONCATENATE:
1376                                 destination_track = 0;
1377                                 if(destination_tracks.total)
1378                                         current_position = destination_tracks.values[0]->get_length();
1379                                 else
1380                                         current_position = 0;
1381                                 break;
1383                         case LOAD_PASTE:
1384                                 destination_track = 0;
1385                                 if(i == 0)
1386                                 {
1387                                         for(int j = 0; j < destination_tracks.total; j++)
1388                                         {
1389                                                 paste_position[j] = (current_position >= 0) ? 
1390                                                         current_position :
1391                                                         edl->local_session->get_selectionstart();
1392                                         }
1393                                 }
1394                                 break;
1396                         case LOAD_RESOURCESONLY:
1397                                 edl->add_clip(new_edl);
1398                                 break;
1399                 }
1402 SET_TRACE
1405 // Insert edl
1406                 if(load_mode != LOAD_RESOURCESONLY)
1407                 {
1408 // Insert labels
1409 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1410                         if(load_mode == LOAD_PASTE)
1411                                 edl->labels->insert_labels(new_edl->labels, 
1412                                         destination_tracks.total ? paste_position[0] : 0.0,
1413                                         edl_length,
1414                                         edit_labels);
1415                         else
1416                                 edl->labels->insert_labels(new_edl->labels, 
1417                                         current_position,
1418                                         edl_length,
1419                                         edit_labels);
1421                         for(Track *new_track = new_edl->tracks->first; 
1422                                 new_track; 
1423                                 new_track = new_track->next)
1424                         {
1425 // Get destination track of same type as new_track
1426                                 for(int k = 0; 
1427                                         k < destination_tracks.total &&
1428                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1429                                         k++, destination_track++)
1430                                 {
1431                                         if(destination_track >= destination_tracks.total - 1)
1432                                                 destination_track = 0;
1433                                 }
1435 // Insert data into destination track
1436                                 if(destination_track < destination_tracks.total &&
1437                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1438                                 {
1439                                         Track *track = destination_tracks.values[destination_track];
1441 // Replace default keyframes if first EDL and new tracks were created.
1442 // This means data copied from one track and pasted to another won't retain
1443 // the camera position unless it's a keyframe.  If it did, previous data in the
1444 // track might get unknowingly corrupted.  Ideally we would detect when differing
1445 // default keyframes existed and create discrete keyframes for both.
1446                                         int replace_default = (i == 0) && need_new_tracks;
1448 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1449 // Insert new track at current position
1450                                         switch(load_mode)
1451                                         {
1452                                                 case LOAD_REPLACE_CONCATENATE:
1453                                                 case LOAD_CONCATENATE:
1454                                                         current_position = track->get_length();
1455                                                         break;
1457                                                 case LOAD_PASTE:
1458                                                         current_position = paste_position[destination_track];
1459                                                         paste_position[destination_track] += new_track->get_length();
1460                                                         break;
1461                                         }
1463                                         track->insert_track(new_track, 
1464                                                 current_position, 
1465                                                 replace_default,
1466                                                 edit_plugins);
1467                                 }
1469 // Get next destination track
1470                                 destination_track++;
1471                                 if(destination_track >= destination_tracks.total)
1472                                         destination_track = 0;
1473                         }
1474                 }
1476                 if(load_mode == LOAD_PASTE)
1477                         current_position += edl_length;
1478         }
1480 // Move loading of clips and vwindow to the end - this fixes some strange issue, for index not being shown
1481 // Assume any paste operation from the same EDL won't contain any clips.
1482 // If it did it would duplicate every clip here.
1483         for(int i = 0; i < new_edls->total; i++)
1484         {
1485                 EDL *new_edl = new_edls->values[i];
1487                 for(int j = 0; j < new_edl->clips.total; j++)
1488                 {
1489                         edl->add_clip(new_edl->clips.values[j]);
1490                 }
1492                 if(new_edl->vwindow_edl)
1493                 {
1494                         if(edl->vwindow_edl) delete edl->vwindow_edl;
1495                         edl->vwindow_edl = new EDL(edl);
1496                         edl->vwindow_edl->create_objects();
1497                         edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1498                 }
1499         }
1500 SET_TRACE
1503 SET_TRACE
1504         if(paste_position) delete [] paste_position;
1506 SET_TRACE
1507 // This is already done in load_filenames and everything else that uses paste_edls
1508 //      update_project(load_mode);
1510 SET_TRACE
1512 // Start examining next batch of index files
1513         mainindexes->start_build();
1514 SET_TRACE
1516 // Don't save a backup after loading since the loaded file is on disk already.
1518 SET_TRACE
1519         return 0;
1522 void MWindow::paste_silence()
1524         double start = edl->local_session->get_selectionstart();
1525         double end = edl->local_session->get_selectionend();
1526         edl->paste_silence(start, 
1527                 end, 
1528                 edl->session->labels_follow_edits, 
1529                 edl->session->plugins_follow_edits);
1530         edl->optimize();
1531         save_backup();
1532         undo->update_undo(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1534         update_plugin_guis();
1535         restart_brender();
1536         gui->update(1, 2, 1, 1, 1, 1, 0);
1537         cwindow->update(1, 0, 0, 0, 1);
1538         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1539                                                         CHANGE_EDL,
1540                                                         edl,
1541                                                         1);
1544 void MWindow::paste_transition()
1546 // Only the first transition gets dropped.
1547         PluginServer *server = session->drag_pluginservers->values[0];
1548         if(server->audio)
1549                 strcpy(edl->session->default_atransition, server->title);
1550         else
1551                 strcpy(edl->session->default_vtransition, server->title);
1553         edl->tracks->paste_transition(server, session->edit_highlighted);
1554         save_backup();
1555         undo->update_undo(_("transition"), LOAD_EDITS);
1557         if(server->video) restart_brender();
1558         sync_parameters(CHANGE_ALL);
1561 void MWindow::paste_transition_cwindow(Track *dest_track)
1563         PluginServer *server = session->drag_pluginservers->values[0];
1564         edl->tracks->paste_video_transition(server, 1);
1565         save_backup();
1566         undo->update_undo(_("transition"), LOAD_EDITS);
1567         restart_brender();
1568         gui->update(0, 1, 0, 0, 0, 0, 0);
1569         sync_parameters(CHANGE_ALL);
1572 void MWindow::paste_audio_transition()
1574         PluginServer *server = scan_plugindb(edl->session->default_atransition,
1575                 TRACK_AUDIO);
1576         if(!server)
1577         {
1578                 char string[BCTEXTLEN];
1579                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1580                 gui->show_message(string);
1581                 return;
1582         }
1584         edl->tracks->paste_audio_transition(server);
1585         save_backup();
1586         undo->update_undo(_("transition"), LOAD_EDITS);
1588         sync_parameters(CHANGE_ALL);
1589         gui->update(0, 1, 0, 0, 0, 0, 0);
1592 void MWindow::paste_video_transition()
1594         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1595                 TRACK_VIDEO);
1596         if(!server)
1597         {
1598                 char string[BCTEXTLEN];
1599                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1600                 gui->show_message(string);
1601                 return;
1602         }
1605         edl->tracks->paste_video_transition(server);
1606         save_backup();
1607         undo->update_undo(_("transition"), LOAD_EDITS);
1609         sync_parameters(CHANGE_ALL);
1610         restart_brender();
1611         gui->update(0, 1, 0, 0, 0, 0, 0);
1615 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1618         calling_window_gui->unlock_window();
1620         cwindow->playback_engine->que->send_command(STOP,
1621                 CHANGE_NONE, 
1622                 0,
1623                 0);
1624         vwindow->playback_engine->que->send_command(STOP,
1625                 CHANGE_NONE, 
1626                 0,
1627                 0);
1628         cwindow->playback_engine->interrupt_playback(0);
1629         vwindow->playback_engine->interrupt_playback(0);
1632         cwindow->gui->lock_window("MWindow::redo_entry");
1633         vwindow->gui->lock_window("MWindow::undo_entry 2");
1634         gui->lock_window();
1636         undo->redo(); 
1638         save_backup();
1639         update_plugin_states();
1640         update_plugin_guis();
1641         restart_brender();
1642         gui->update(1, 2, 1, 1, 1, 1, 1);
1643         cwindow->update(1, 1, 1, 1, 1);
1645         if (calling_window_gui != cwindow->gui) 
1646                 cwindow->gui->unlock_window();
1647         if (calling_window_gui != gui)
1648                 gui->unlock_window();
1649         if (calling_window_gui != vwindow->gui)
1650                 vwindow->gui->unlock_window();
1652         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1653                            CHANGE_ALL,
1654                            edl,
1655                            1);
1656         
1660 void MWindow::resize_track(Track *track, int w, int h)
1662 // We have to move all maskpoints so they do not move in relation to image areas
1663         ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->translate_masks(
1664                 (w - track->track_w) / 2, 
1665                 (h - track->track_h) / 2);
1666         track->track_w = w;
1667         track->track_h = h;
1668         undo->update_undo(_("resize track"), LOAD_ALL);
1669         save_backup();
1671         restart_brender();
1672         sync_parameters(CHANGE_EDL);
1676 class InPointUndoItem : public UndoStackItem
1678 public:
1679         InPointUndoItem(double old_position, double new_position, EDL *edl);
1680         void undo();
1681         int get_size();
1682 private:
1683         double old_position;
1684         double new_position;
1685         EDL *edl;
1688 InPointUndoItem::InPointUndoItem(
1689       double old_position, double new_position, EDL *edl)
1691    set_description(_("in point"));
1692    this->old_position = old_position;
1693    this->new_position = new_position;
1694    this->edl = edl;
1697 void InPointUndoItem::undo()
1699    edl->set_inpoint(old_position);
1700 // prepare to undo the undo
1701         double tmp = new_position;
1702         new_position = old_position;
1703         old_position = tmp;
1706 int InPointUndoItem::get_size()
1708    return 20;
1711 void MWindow::set_inpoint(int is_mwindow)
1713    InPointUndoItem *undo_item;
1715    undo_item = new InPointUndoItem(edl->local_session->get_inpoint(),
1716          edl->local_session->get_selectionstart(1), edl);
1717    undo->push_undo_item(undo_item);
1719         edl->set_inpoint(edl->local_session->get_selectionstart(1));
1720         save_backup();
1722         if(!is_mwindow)
1723         {
1724                 gui->lock_window("MWindow::set_inpoint 1");
1725         }
1726         gui->timebar->update();
1727         gui->flush();
1728         if(!is_mwindow)
1729         {
1730                 gui->unlock_window();
1731         }
1733         if(is_mwindow)
1734         {
1735                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1736         }
1737         cwindow->gui->timebar->update();
1738         cwindow->gui->flush();
1739         if(is_mwindow)
1740         {
1741                 cwindow->gui->unlock_window();
1742         }
1745 class OutPointUndoItem : public UndoStackItem
1747 public:
1748         OutPointUndoItem(double old_position, double new_position, EDL *edl);
1749         void undo();
1750         int get_size();
1751 private:
1752         double old_position;
1753         double new_position;
1754         EDL *edl;
1757 OutPointUndoItem::OutPointUndoItem(
1758       double old_position, double new_position, EDL *edl)
1760    set_description(_("out point"));
1761    this->old_position = old_position;
1762    this->new_position = new_position;
1763    this->edl = edl;
1766 void OutPointUndoItem::undo()
1768    edl->set_outpoint(old_position);
1769 // prepare to undo the undo
1770         double tmp = new_position;
1771         new_position = old_position;
1772         old_position = tmp;
1775 int OutPointUndoItem::get_size()
1777    return 20;
1780 void MWindow::set_outpoint(int is_mwindow)
1782    OutPointUndoItem *undo_item;
1784    undo_item = new OutPointUndoItem(edl->local_session->get_outpoint(),
1785          edl->local_session->get_selectionend(1), edl);
1786    undo->push_undo_item(undo_item);
1788         edl->set_outpoint(edl->local_session->get_selectionend(1));
1789         save_backup();
1791         if(!is_mwindow)
1792         {
1793                 gui->lock_window("MWindow::set_outpoint 1");
1794         }
1795         gui->timebar->update();
1796         gui->flush();
1797         if(!is_mwindow)
1798         {
1799                 gui->unlock_window();
1800         }
1802         if(is_mwindow)
1803         {
1804                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1805         }
1806         cwindow->gui->timebar->update();
1807         cwindow->gui->flush();
1808         if(is_mwindow)
1809         {
1810                 cwindow->gui->unlock_window();
1811         }
1814 void MWindow::splice(EDL *source)
1816         FileXML file;
1818         source->copy(source->local_session->get_selectionstart(), 
1819                 source->local_session->get_selectionend(), 
1820                 1,
1821                 0,
1822                 0,
1823                 &file,
1824                 plugindb,
1825                 "",
1826                 1);
1830 //file.dump();
1831         double start = edl->local_session->get_selectionstart();
1832         double end = edl->local_session->get_selectionend();
1833         double source_start = source->local_session->get_selectionstart();
1834         double source_end = source->local_session->get_selectionend();
1836         paste(start, 
1837                 start, 
1838                 &file,
1839                 edl->session->labels_follow_edits,
1840                 edl->session->plugins_follow_edits);
1842 // Position at end of clip
1843         edl->local_session->set_selectionstart(start + 
1844                 source_end - 
1845                 source_start);
1846         edl->local_session->set_selectionend(start + 
1847                 source_end - 
1848                 source_start);
1850         save_backup();
1851         undo->update_undo(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1852         update_plugin_guis();
1853         restart_brender();
1854         gui->update(1, 1, 1, 1, 0, 1, 0);
1855         sync_parameters(CHANGE_EDL);
1858 void MWindow::to_clip()
1860         FileXML file;
1861         double start, end;
1862         
1863         start = edl->local_session->get_selectionstart();
1864         end = edl->local_session->get_selectionend();
1866         if(EQUIV(end, start)) 
1867         {
1868                 start = 0;
1869                 end = edl->tracks->total_length();
1870         }
1872 // Don't copy all since we don't want the clips twice.
1873         edl->copy(start, 
1874                 end, 
1875                 0,
1876                 0,
1877                 0,
1878                 &file,
1879                 plugindb,
1880                 "",
1881                 1);
1884         EDL *new_edl = new EDL(edl);
1885         new_edl->create_objects();
1886         new_edl->load_xml(plugindb, &file, LOAD_ALL);
1887         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1888         new_edl->local_session->set_selectionstart(0);
1889         new_edl->local_session->set_selectionend(0);
1891         awindow->clip_edit->create_clip(new_edl);
1892         save_backup();
1895 class LabelUndoItem : public UndoStackItem
1897 public:
1898       LabelUndoItem(double position1, double position2, EDL *edl);
1899       void undo();
1900       int get_size();
1901 private:
1902       double position1;
1903       double position2;
1904       EDL *edl;
1907 LabelUndoItem::LabelUndoItem(
1908       double position1, double position2, EDL *edl)
1910    set_description(_("label"));
1911    this->position1 = position1;
1912    this->position2 = position2;
1913    this->edl = edl;
1916 void LabelUndoItem::undo()
1918         edl->labels->toggle_label(position1, position2);
1921 int LabelUndoItem::get_size()
1923    return 20;
1926 int MWindow::toggle_label(int is_mwindow)
1928    LabelUndoItem *undo_item;
1929         double position1, position2;
1931         if(cwindow->playback_engine->is_playing_back)
1932         {
1933                 position1 = position2 = 
1934                         cwindow->playback_engine->get_tracking_position();
1935         }
1936         else
1937         {
1938                 position1 = edl->local_session->get_selectionstart(1);
1939                 position2 = edl->local_session->get_selectionend(1);
1940         }
1942         position1 = edl->align_to_frame(position1, 0);
1943         position2 = edl->align_to_frame(position2, 0);
1945 //printf("MWindow::toggle_label 1\n");
1946    undo_item = new LabelUndoItem(position1, position2, edl);
1947    undo->push_undo_item(undo_item);
1949         edl->labels->toggle_label(position1, position2);
1950         save_backup();
1952         if(!is_mwindow)
1953         {
1954                 gui->lock_window("MWindow::toggle_label 1");
1955         }
1956         gui->timebar->update();
1957         gui->canvas->activate();
1958         gui->flush();
1959         if(!is_mwindow)
1960         {
1961                 gui->unlock_window();
1962         }
1964         if(is_mwindow)
1965         {
1966                 cwindow->gui->lock_window("MWindow::toggle_label 2");
1967         }
1968         cwindow->gui->timebar->update();
1969         cwindow->gui->flush();
1970         if(is_mwindow)
1971         {
1972                 cwindow->gui->unlock_window();
1973         }
1975         return 0;
1978 void MWindow::trim_selection()
1982         edl->trim_selection(edl->local_session->get_selectionstart(), 
1983                 edl->local_session->get_selectionend(), 
1984                 edl->session->labels_follow_edits, 
1985                 edl->session->plugins_follow_edits);
1987         save_backup();
1988         undo->update_undo(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
1989         update_plugin_guis();
1990         gui->update(1, 2, 1, 1, 1, 1, 0);
1991         restart_brender();
1992         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1993                                                         CHANGE_EDL,
1994                                                         edl,
1995                                                         1);
2000 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
2002 //      if(is_mwindow)
2003 //              gui->unlock_window();
2004 //      else
2005 //              cwindow->gui->unlock_window();
2006         calling_window_gui->unlock_window();
2008         cwindow->playback_engine->que->send_command(STOP,
2009                 CHANGE_NONE, 
2010                 0,
2011                 0);
2012         vwindow->playback_engine->que->send_command(STOP,
2013                 CHANGE_NONE, 
2014                 0,
2015                 0);
2016         cwindow->playback_engine->interrupt_playback(0);
2017         vwindow->playback_engine->interrupt_playback(0);
2019         cwindow->gui->lock_window("MWindow::undo_entry 1");
2020         vwindow->gui->lock_window("MWindow::undo_entry 4");
2021         gui->lock_window("MWindow::undo_entry 2");
2023         undo->undo(); 
2025         save_backup();
2026         restart_brender();
2027         update_plugin_states();
2028         update_plugin_guis();
2029         gui->update(1, 2, 1, 1, 1, 1, 1);
2030         cwindow->update(1, 1, 1, 1, 1);
2032 //      if(is_mwindow)
2033 //              cwindow->gui->unlock_window();
2034 //      else
2035 //              gui->unlock_window();
2036         if (calling_window_gui != cwindow->gui) 
2037                 cwindow->gui->unlock_window();
2038         if (calling_window_gui != gui)
2039                 gui->unlock_window();
2040         if (calling_window_gui != vwindow->gui)
2041                 vwindow->gui->unlock_window();
2042         
2044         awindow->gui->lock_window("MWindow::undo_entry 3");
2045         awindow->gui->update_assets();
2046         awindow->gui->flush();
2047         awindow->gui->unlock_window();
2048         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2049                            CHANGE_ALL,
2050                            edl,
2051                            1);
2056 void MWindow::new_folder(char *new_folder)
2058         edl->new_folder(new_folder);
2059         undo->update_undo(_("new folder"), LOAD_ALL);
2060         awindow->gui->lock_window("MWindow::new_folder");
2061         awindow->gui->update_assets();
2062         awindow->gui->unlock_window();
2065 void MWindow::delete_folder(char *folder)
2067 //      undo->update_undo(_("delete folder"), LOAD_ALL);
2070 void MWindow::select_point(double position)
2072         edl->local_session->set_selectionstart(position);
2073         edl->local_session->set_selectionend(position);
2075 // Que the CWindow
2076         cwindow->update(1, 0, 0, 0, 1);
2077         update_plugin_guis();
2078         gui->patchbay->update();
2079         gui->cursor->hide();
2080         gui->cursor->draw();
2081         gui->mainclock->update(edl->local_session->get_selectionstart(1));
2082         gui->zoombar->update();
2083         gui->canvas->flash();
2084         gui->flush();