r578: Factored UndoStackItem into an interface class UndoStackItem and
[cinelerra_cv.git] / cinelerra / mwindowedit.C
blob062c5a1d04aeb03426a4870a6d2603c47a37765b
1 #include "asset.h"
2 #include "assets.h"
3 #include "awindowgui.h"
4 #include "awindow.h"
5 #include "cache.h"
6 #include "clip.h"
7 #include "clipedit.h"
8 #include "cplayback.h"
9 #include "ctimebar.h"
10 #include "cwindow.h"
11 #include "cwindowgui.h"
12 #include "edl.h"
13 #include "edlsession.h"
14 #include "filexml.h"
15 #include "keyframe.h"
16 #include "language.h"
17 #include "labels.h"
18 #include "levelwindow.h"
19 #include "localsession.h"
20 #include "mainclock.h"
21 #include "maincursor.h"
22 #include "mainindexes.h"
23 #include "mainmenu.h"
24 #include "mainsession.h"
25 #include "mainundo.h"
26 #include "mtimebar.h"
27 #include "mwindowgui.h"
28 #include "mwindow.h"
29 #include "patchbay.h"
30 #include "playbackengine.h"
31 #include "pluginset.h"
32 #include "recordlabel.h"
33 #include "samplescroll.h"
34 #include "trackcanvas.h"
35 #include "track.h"
36 #include "trackscroll.h"
37 #include "tracks.h"
38 #include "transition.h"
39 #include "transportque.h"
40 #include "units.h"
41 #include "undostackitem.h"
42 #include "vplayback.h"
43 #include "vwindow.h"
44 #include "vwindowgui.h"
45 #include "zoombar.h"
49 #include <string.h>
56 void MWindow::add_audio_track_entry(int above, Track *dst)
58         undo->update_undo_before(_("add track"), LOAD_ALL);
59         add_audio_track(above, dst);
60         save_backup();
61         undo->update_undo_after();
63         restart_brender();
64         gui->get_scrollbars();
65         gui->canvas->draw();
66         gui->patchbay->update();
67         gui->cursor->draw();
68         gui->canvas->flash();
69         gui->canvas->activate();
70         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
71                 CHANGE_EDL,
72                 edl,
73                 1);
76 void MWindow::add_video_track_entry(Track *dst)
78         undo->update_undo_before(_("add track"), LOAD_ALL);
79         add_video_track(1, dst);
80         undo->update_undo_after();
82         restart_brender();
83         gui->get_scrollbars();
84         gui->canvas->draw();
85         gui->patchbay->update();
86         gui->cursor->draw();
87         gui->canvas->flash();
88         gui->canvas->activate();
89         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
90                                                         CHANGE_EDL,
91                                                         edl,
92                                                         1);
93         save_backup();
97 int MWindow::add_audio_track(int above, Track *dst)
99         edl->tracks->add_audio_track(above, dst);
100         edl->tracks->update_y_pixels(theme);
101         save_backup();
102         return 0;
105 int MWindow::add_video_track(int above, Track *dst)
107         edl->tracks->add_video_track(above, dst);
108         edl->tracks->update_y_pixels(theme);
109         save_backup();
110         return 0;
117 void MWindow::asset_to_size()
119         if(session->drag_assets->total &&
120                 session->drag_assets->values[0]->video_data)
121         {
122                 int w, h;
124                 w = session->drag_assets->values[0]->width;
125                 h = session->drag_assets->values[0]->height;
127                 undo->update_undo_before(_("asset to size"), LOAD_ALL);
128                 edl->session->output_w = w;
129                 edl->session->output_h = h;
130                 save_backup();
132                 undo->update_undo_after();
133                 restart_brender();
134                 sync_parameters(CHANGE_ALL);
135         }
140 void MWindow::clear_entry()
142         undo->update_undo_before(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
143         clear(1);
145         edl->optimize();
146         save_backup();
147         undo->update_undo_after();
149         restart_brender();
150         update_plugin_guis();
151         gui->update(1, 2, 1, 1, 1, 1, 0);
152         cwindow->update(1, 0, 0, 0, 1);
153         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
154                            CHANGE_EDL,
155                            edl,
156                            1);
159 void MWindow::clear(int clear_handle)
161         double start = edl->local_session->get_selectionstart();
162         double end = edl->local_session->get_selectionend();
163         if(clear_handle || !EQUIV(start, end))
164         {
165                 edl->clear(start, 
166                         end, 
167                         edl->session->labels_follow_edits, 
168                         edl->session->plugins_follow_edits);
169         }
172 void MWindow::clear_automation()
174         undo->update_undo_before(_("clear keyframes"), LOAD_AUTOMATION); 
175         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
176                 edl->local_session->get_selectionend()); 
177         save_backup();
178         undo->update_undo_after(); 
180         restart_brender();
181         update_plugin_guis();
182         gui->canvas->draw_overlays();
183         gui->canvas->flash();
184         sync_parameters(CHANGE_PARAMS);
185         gui->patchbay->update();
186         cwindow->update(1, 0, 0);
189 int MWindow::clear_default_keyframe()
191         undo->update_undo_before(_("clear default keyframe"), LOAD_AUTOMATION); 
192         edl->tracks->clear_default_keyframe();
193         save_backup();
194         undo->update_undo_after();
195         
196         restart_brender();
197         gui->canvas->draw_overlays();
198         gui->canvas->flash();
199         sync_parameters(CHANGE_PARAMS);
200         gui->patchbay->update();
201         cwindow->update(1, 0, 0);
202         
203         return 0;
206 void MWindow::clear_labels()
208         undo->update_undo_before(_("clear"), LOAD_TIMEBAR);
209         clear_labels(edl->local_session->get_selectionstart(), 
210                 edl->local_session->get_selectionend()); 
211         undo->update_undo_after(); 
212         
213         gui->timebar->update();
214         cwindow->update(0, 0, 0, 0, 1);
215         save_backup();
218 int MWindow::clear_labels(double start, double end)
220         edl->labels->clear(start, end, 0);
221         return 0;
224 void MWindow::concatenate_tracks()
226         undo->update_undo_before(_("concatenate tracks"), LOAD_EDITS);
227         edl->tracks->concatenate_tracks(edl->session->plugins_follow_edits);
228         save_backup();
229         undo->update_undo_after();
231         restart_brender();
232         gui->update(1, 1, 0, 0, 1, 0, 0);
233         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
234                 CHANGE_EDL,
235                 edl,
236                 1);
240 void MWindow::copy()
242         copy(edl->local_session->get_selectionstart(), 
243                 edl->local_session->get_selectionend());
246 int MWindow::copy(double start, double end)
248         if(start == end) return 1;
250 //printf("MWindow::copy 1\n");
251         FileXML file;
252 //printf("MWindow::copy 1\n");
253         edl->copy(start, 
254                 end, 
255                 0,
256                 0,
257                 0,
258                 &file, 
259                 plugindb,
260                 "",
261                 1);
262 //printf("MWindow::copy 1\n");
264 // File is now terminated and rewound
266 //printf("MWindow::copy 1\n");
267         gui->get_clipboard()->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
268 //printf("MWindow::copy\n%s\n", file.string);
269 //printf("MWindow::copy 2\n");
270         save_backup();
271         return 0;
274 int MWindow::copy_automation()
276         FileXML file;
277         edl->tracks->copy_automation(edl->local_session->get_selectionstart(), 
278                 edl->local_session->get_selectionend(),
279                 &file,
280                 0,
281                 0); 
282         gui->get_clipboard()->to_clipboard(file.string, 
283                 strlen(file.string), 
284                 SECONDARY_SELECTION);
285         return 0;
288 int MWindow::copy_default_keyframe()
290         FileXML file;
291         edl->tracks->copy_default_keyframe(&file);
292         gui->get_clipboard()->to_clipboard(file.string,
293                 strlen(file.string),
294                 SECONDARY_SELECTION);
295         return 0;
299 // Uses cropping coordinates in edl session to crop and translate video.
300 // We modify the projector since camera automation depends on the track size.
301 void MWindow::crop_video()
303         undo->update_undo_before(_("crop"), LOAD_ALL);
305 // Clamp EDL crop region
306         if(edl->session->crop_x1 > edl->session->crop_x2)
307         {
308                 edl->session->crop_x1 ^= edl->session->crop_x2;
309                 edl->session->crop_x2 ^= edl->session->crop_x1;
310                 edl->session->crop_x1 ^= edl->session->crop_x2;
311         }
312         if(edl->session->crop_y1 > edl->session->crop_y2)
313         {
314                 edl->session->crop_y1 ^= edl->session->crop_y2;
315                 edl->session->crop_y2 ^= edl->session->crop_y1;
316                 edl->session->crop_y1 ^= edl->session->crop_y2;
317         }
319         float old_projector_x = (float)edl->session->output_w / 2;
320         float old_projector_y = (float)edl->session->output_h / 2;
321         float new_projector_x = (float)(edl->session->crop_x1 + edl->session->crop_x2) / 2;
322         float new_projector_y = (float)(edl->session->crop_y1 + edl->session->crop_y2) / 2;
323         float projector_offset_x = -(new_projector_x - old_projector_x);
324         float projector_offset_y = -(new_projector_y - old_projector_y);
326         edl->tracks->translate_projector(projector_offset_x, projector_offset_y);
328         edl->session->output_w = edl->session->crop_x2 - edl->session->crop_x1;
329         edl->session->output_h = edl->session->crop_y2 - edl->session->crop_y1;
330         edl->session->crop_x1 = 0;
331         edl->session->crop_y1 = 0;
332         edl->session->crop_x2 = edl->session->output_w;
333         edl->session->crop_y2 = edl->session->output_h;
334         undo->update_undo_after();
336         restart_brender();
337         cwindow->playback_engine->que->send_command(CURRENT_FRAME,
338                 CHANGE_ALL,
339                 edl,
340                 1);
341         save_backup();
344 void MWindow::cut()
346         undo->update_undo_before(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
348         double start = edl->local_session->get_selectionstart();
349         double end = edl->local_session->get_selectionend();
351         copy(start, end);
352         edl->clear(start, 
353                 end,
354                 edl->session->labels_follow_edits, 
355                 edl->session->plugins_follow_edits);
358         edl->optimize();
359         save_backup();
360         undo->update_undo_after();
362         restart_brender();
363         update_plugin_guis();
364         gui->update(1, 2, 1, 1, 1, 1, 0);
365         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
366                                                         CHANGE_EDL,
367                                                         edl,
368                                                         1);
371 int MWindow::cut_automation()
373         undo->update_undo_before(_("cut keyframes"), LOAD_AUTOMATION);
374         
375         copy_automation();
377         edl->tracks->clear_automation(edl->local_session->get_selectionstart(), 
378                 edl->local_session->get_selectionend()); 
379         save_backup();
380         undo->update_undo_after(); 
383         restart_brender();
384         update_plugin_guis();
385         gui->canvas->draw_overlays();
386         gui->canvas->flash();
387         sync_parameters(CHANGE_PARAMS);
388         gui->patchbay->update();
389         cwindow->update(1, 0, 0);
390         return 0;
393 int MWindow::cut_default_keyframe()
395         undo->update_undo_before(_("cut default keyframe"), LOAD_AUTOMATION);
397         copy_default_keyframe();
398         edl->tracks->clear_default_keyframe();
399         undo->update_undo_after();
401         restart_brender();
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         save_backup();
410         return 0;
413 void MWindow::delete_inpoint()
415         edl->local_session->in_point = -1;
416         save_backup();
419 void MWindow::delete_outpoint()
421         edl->local_session->out_point = -1;
422         save_backup();
425 void MWindow::delete_track()
427         if (edl->tracks->last)
428                 delete_track(edl->tracks->last);
431 void MWindow::delete_tracks()
433         undo->update_undo_before(_("delete tracks"), LOAD_ALL);
434         edl->tracks->delete_tracks();
435         undo->update_undo_after();
436         save_backup();
438         restart_brender();
439         update_plugin_states();
440         gui->update(1, 1, 1, 0, 1, 0, 0);
441         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
442                            CHANGE_EDL,
443                            edl,
444                            1);
445 //printf("MWindow::delete_tracks 5\n");
448 void MWindow::delete_track(Track *track)
450         undo->update_undo_before(_("delete track"), LOAD_ALL);
451         edl->tracks->delete_track(track);
452         undo->update_undo_after();
454         restart_brender();
455         update_plugin_states();
456         gui->update(1, 1, 1, 0, 1, 0, 0);
457         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
458                            CHANGE_EDL,
459                            edl,
460                            1);
461         save_backup();
464 void MWindow::detach_transition(Transition *transition)
466         undo->update_undo_before(_("detach transition"), LOAD_ALL);
467         hide_plugin(transition, 1);
468         int is_video = (transition->edit->track->data_type == TRACK_VIDEO);
469         transition->edit->detach_transition();
470         save_backup();
471         undo->update_undo_after();
473         if(is_video) restart_brender();
474         gui->update(0,
475                 1,
476                 0,
477                 0,
478                 0, 
479                 0,
480                 0);
481         sync_parameters(CHANGE_EDL);
488 // Insert data from clipboard
489 void MWindow::insert(double position, 
490         FileXML *file,
491         int edit_labels,
492         int edit_plugins,
493         EDL *parent_edl)
495 // For clipboard pasting make the new edl use a separate session 
496 // from the master EDL.  Then it can be resampled to the master rates.
497 // For splice, overwrite, and dragging need same session to get the assets.
498         EDL edl(parent_edl);
499         ArrayList<EDL*> new_edls;
500         uint32_t load_flags = LOAD_ALL;
502         new_edls.append(&edl);
503         edl.create_objects();
507         if(parent_edl) load_flags &= ~LOAD_SESSION;
508         if(!edl.session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
509         if(!edl.session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
510         edl.load_xml(plugindb, file, load_flags);
516         paste_edls(&new_edls, 
517                 LOAD_PASTE, 
518                 0, 
519                 position,
520                 edit_labels,
521                 edit_plugins);
522 // if(vwindow->edl)
523 // printf("MWindow::insert 5 %f %f\n", 
524 // vwindow->edl->local_session->in_point,
525 // vwindow->edl->local_session->out_point);
526         new_edls.remove_all();
527 //printf("MWindow::insert 6 %p\n", vwindow->get_edl());
530 void MWindow::insert_effects_canvas(double start,
531         double length)
533         Track *dest_track = session->track_highlighted;
534         if(!dest_track) return;
536         undo->update_undo_before(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
538         for(int i = 0; i < session->drag_pluginservers->total; i++)
539         {
540                 PluginServer *plugin = session->drag_pluginservers->values[i];
542                 insert_effect(plugin->title,
543                         0,
544                         dest_track,
545                         i == 0 ? session->pluginset_highlighted : 0,
546                         start,
547                         length,
548                         PLUGIN_STANDALONE);
549         }
551         save_backup();
552         undo->update_undo_after();
553         restart_brender();
554         sync_parameters(CHANGE_EDL);
555 // GUI updated in TrackCanvas, after current_operations are reset
558 void MWindow::insert_effects_cwindow(Track *dest_track)
560         if(!dest_track) return;
562         undo->update_undo_before(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
564         double start = 0;
565         double length = dest_track->get_length();
567         if(edl->local_session->get_selectionend() > 
568                 edl->local_session->get_selectionstart())
569         {
570                 start = edl->local_session->get_selectionstart();
571                 length = edl->local_session->get_selectionend() - 
572                         edl->local_session->get_selectionstart();
573         }
575         for(int i = 0; i < session->drag_pluginservers->total; i++)
576         {
577                 PluginServer *plugin = session->drag_pluginservers->values[i];
580                 insert_effect(plugin->title,
581                         0,
582                         dest_track,
583                         0,
584                         start,
585                         length,
586                         PLUGIN_STANDALONE);
587         }
589         save_backup();
590         undo->update_undo_after();
591         restart_brender();
592         sync_parameters(CHANGE_EDL);
593         gui->update(1,
594                 1,
595                 0,
596                 0,
597                 1,
598                 0,
599                 0);
604 void MWindow::insert_effect(char *title, 
605         SharedLocation *shared_location, 
606         Track *track,
607         PluginSet *plugin_set,
608         double start,
609         double length,
610         int plugin_type)
612         KeyFrame *default_keyframe = 0;
613         PluginServer *server = 0;
620 // Get default keyframe
621         if(plugin_type == PLUGIN_STANDALONE)
622         {
623                 default_keyframe = new KeyFrame;
624                 server = new PluginServer(*scan_plugindb(title, track->data_type));
626                 server->open_plugin(0, preferences, edl, 0, -1);
627                 server->save_data(default_keyframe);
628         }
632 // Insert plugin object
633         track->insert_effect(title, 
634                 shared_location, 
635                 default_keyframe, 
636                 plugin_set,
637                 start,
638                 length,
639                 plugin_type);
641         track->optimize();
644         if(plugin_type == PLUGIN_STANDALONE)
645         {
646                 server->close_plugin();
647                 delete server;
648                 delete default_keyframe;
649         }
652 int MWindow::modify_edithandles()
654         undo->update_undo_before(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
660         edl->modify_edithandles(session->drag_start, 
661                 session->drag_position, 
662                 session->drag_handle, 
663                 edl->session->edit_handle_mode[session->drag_button],
664                 edl->session->labels_follow_edits, 
665                 edl->session->plugins_follow_edits);
667         finish_modify_handles();
670 //printf("MWindow::modify_handles 1\n");
671         return 0;
674 int MWindow::modify_pluginhandles()
676         undo->update_undo_before(_("drag handle"), LOAD_EDITS | LOAD_TIMEBAR);
678         edl->modify_pluginhandles(session->drag_start, 
679                 session->drag_position, 
680                 session->drag_handle, 
681                 edl->session->edit_handle_mode[session->drag_button],
682                 edl->session->labels_follow_edits,
683                 session->trim_edits);
685         finish_modify_handles();
687         return 0;
691 // Common to edithandles and plugin handles
692 void MWindow::finish_modify_handles()
694         int edit_mode = edl->session->edit_handle_mode[session->drag_button];
696 //printf("TrackCanvas::end_handle_selection 1\n");
697         if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
698                 (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
699         {
700                 edl->local_session->selectionstart = 
701                         edl->local_session->selectionend = 
702                         session->drag_position;
703         }
704         else
705         if(edit_mode != MOVE_NO_EDITS)
706         {
707                 edl->local_session->selectionstart = 
708                         edl->local_session->selectionend = 
709                         session->drag_start;
710         }
712 //printf("TrackCanvas::end_handle_selection 1\n");
713         if(edl->local_session->selectionstart < 0) 
714                 edl->local_session->selectionstart = 
715                         edl->local_session->selectionend = 0;
716 //printf("TrackCanvas::end_handle_selection 1\n");
718         save_backup();
719         undo->update_undo_after();
720         restart_brender();
721         sync_parameters(CHANGE_EDL);
722 //printf("TrackCanvas::end_handle_selection 1\n");
723         update_plugin_guis();
724         gui->update(1, 2, 1, 1, 1, 1, 0);
725         cwindow->update(1, 0, 0, 0, 1);
726 //printf("TrackCanvas::end_handle_selection 2\n");
731 void MWindow::match_output_size(Track *track)
733     undo->update_undo_before(_("match output size"), LOAD_ALL);
734         track->track_w = edl->session->output_w;
735         track->track_h = edl->session->output_h;
736         save_backup();
737         undo->update_undo_after();
739         restart_brender();
740         sync_parameters(CHANGE_EDL);
744 void MWindow::move_edits(ArrayList<Edit*> *edits, 
745                 Track *track,
746                 double position)
748         undo->update_undo_before(_("move edit"), LOAD_ALL);
750         edl->tracks->move_edits(edits, 
751                 track, 
752                 position,
753                 edl->session->labels_follow_edits, 
754                 edl->session->plugins_follow_edits);
756         save_backup();
757         undo->update_undo_after();
759         restart_brender();
760         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
761                 CHANGE_EDL,
762                 edl,
763                 1);
765         update_plugin_guis();
766         gui->update(1,
767                 1,      // 1 for incremental drawing.  2 for full refresh
768                 1,
769                 0,
770                 0, 
771                 0,
772                 0);
775 void MWindow::move_effect(Plugin *plugin,
776         PluginSet *dest_plugin_set,
777         Track *dest_track,
778         int64_t dest_position)
780         undo->update_undo_before(_("move effect"), LOAD_ALL);
782         edl->tracks->move_effect(plugin, 
783                 dest_plugin_set, 
784                 dest_track, 
785                 dest_position);
787         save_backup();
788         undo->update_undo_after();
790         restart_brender();
791         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
792                 CHANGE_EDL,
793                 edl,
794                 1);
796         update_plugin_guis();
797         gui->update(1,
798                 1,      // 1 for incremental drawing.  2 for full refresh
799                 0,
800                 0,
801                 0, 
802                 0,
803                 0);
806 void MWindow::move_plugins_up(PluginSet *plugin_set)
808         undo->update_undo_before(_("move effect up"), LOAD_ALL);
810         plugin_set->track->move_plugins_up(plugin_set);
812         save_backup();
813         undo->update_undo_after();
814         restart_brender();
815         gui->update(1,
816                 1,      // 1 for incremental drawing.  2 for full refresh
817                 0,
818                 0,
819                 0, 
820                 0,
821                 0);
822         sync_parameters(CHANGE_EDL);
825 void MWindow::move_plugins_down(PluginSet *plugin_set)
827         undo->update_undo_before(_("move effect down"), LOAD_ALL);
829         plugin_set->track->move_plugins_down(plugin_set);
831         save_backup();
832         undo->update_undo_after();
833         restart_brender();
834         gui->update(1,
835                 1,      // 1 for incremental drawing.  2 for full refresh
836                 0,
837                 0,
838                 0, 
839                 0,
840                 0);
841         sync_parameters(CHANGE_EDL);
844 void MWindow::move_track_down(Track *track)
846         undo->update_undo_before(_("move track down"), LOAD_ALL);
847         edl->tracks->move_track_down(track);
848         save_backup();
849         undo->update_undo_after();
851         restart_brender();
852         gui->update(1, 1, 0, 0, 1, 0, 0);
853         sync_parameters(CHANGE_EDL);
854         save_backup();
857 void MWindow::move_tracks_down()
859         undo->update_undo_before(_("move tracks down"), LOAD_ALL);
860         edl->tracks->move_tracks_down();
861         save_backup();
862         undo->update_undo_after();
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         undo->update_undo_before(_("move track up"), LOAD_ALL);
873         edl->tracks->move_track_up(track);
874         save_backup();
875         undo->update_undo_after();
876         restart_brender();
877         gui->update(1, 1, 0, 0, 1, 0, 0);
878         sync_parameters(CHANGE_EDL);
879         save_backup();
882 void MWindow::move_tracks_up()
884         undo->update_undo_before(_("move tracks up"), LOAD_ALL);
885         edl->tracks->move_tracks_up();
886         save_backup();
887         undo->update_undo_after();
888         restart_brender();
889         gui->update(1, 1, 0, 0, 1, 0, 0);
890         sync_parameters(CHANGE_EDL);
894 void MWindow::mute_selection()
896         double start = edl->local_session->get_selectionstart();
897         double end = edl->local_session->get_selectionend();
898         if(start != end)
899         {
900                 undo->update_undo_before(_("mute"), LOAD_EDITS);
903                 edl->clear(start, 
904                         end, 
905                         0, 
906                         edl->session->plugins_follow_edits);
907                 edl->local_session->selectionend = end;
908                 edl->local_session->selectionstart = start;
909                 edl->paste_silence(start, end, 0, edl->session->plugins_follow_edits);
910                 save_backup();
911                 undo->update_undo_after();
913                 restart_brender();
914                 update_plugin_guis();
915                 gui->update(1, 2, 1, 1, 1, 1, 0);
916                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
917                                                                 CHANGE_EDL,
918                                                                 edl,
919                                                                 1);
920         }
925 void MWindow::overwrite(EDL *source)
927         FileXML file;
928         undo->update_undo_before(_("overwrite"), LOAD_EDITS | LOAD_TIMEBAR);
930         double src_start = source->local_session->in_point;
931         double overwrite_len = source->local_session->out_point - src_start;
932         double dst_start = edl->local_session->get_selectionstart();
933         double dst_len = edl->local_session->get_selectionend() - dst_start;
935         if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
936         {
937 // in/out points or selection present and shorter than overwrite range
938 // shorten the copy range
939                 overwrite_len = dst_len;
940         }
941         source->copy(src_start, 
942                 src_start + overwrite_len, 
943                 1,
944                 0,
945                 0,
946                 &file,
947                 plugindb,
948                 "",
949                 1);
951 // HACK around paste_edl get_start/endselection on its own
952 // so we need to clear only when not using both io points
953 // FIXME: need to write simple overwrite_edl to be used for overwrite function
954         if (edl->local_session->in_point < 0 || edl->local_session < 0)
955                 edl->clear(dst_start, 
956                         dst_start + overwrite_len, 
957                         0, 
958                         0);
959         paste(dst_start, 
960                 dst_start + overwrite_len, 
961                 &file,
962                 0,
963                 0);
964         edl->local_session->selectionstart = 
965                 edl->local_session->selectionend =
966                 dst_start + overwrite_len;
967                 
968         save_backup();
969         undo->update_undo_after();
971         restart_brender();
972         update_plugin_guis();
973         gui->update(1, 1, 1, 1, 0, 1, 0);
974         sync_parameters(CHANGE_EDL);
977 // For splice and overwrite
978 int MWindow::paste(double start, 
979         double end, 
980         FileXML *file,
981         int edit_labels,
982         int edit_plugins)
984 //printf("MWindow::paste 1\n");
985         clear(0);
987 // Want to insert with assets shared with the master EDL.
988         insert(start, 
989                         file,
990                         edit_labels,
991                         edit_plugins,
992                         edl);
994 //printf("MWindow::paste 2\n");
995         return 0;
998 // For editing use insertion point position
999 void MWindow::paste()
1001         double start = edl->local_session->get_selectionstart();
1002         double end = edl->local_session->get_selectionend();
1003         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1005         if(len)
1006         {
1007                 char *string = new char[len + 1];
1010                 gui->get_clipboard()->from_clipboard(string, 
1011                         len, 
1012                         SECONDARY_SELECTION);
1013                 FileXML file;
1014                 file.read_from_string(string);
1017                 undo->update_undo_before(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
1019                 clear(0);
1020                 insert(start, 
1021                         &file, 
1022                         edl->session->labels_follow_edits, 
1023                         edl->session->plugins_follow_edits);
1024                 edl->optimize();
1026                 delete [] string;
1029                 save_backup();
1032                 undo->update_undo_after();
1033                 restart_brender();
1034                 update_plugin_guis();
1035                 gui->update(1, 2, 1, 1, 0, 1, 0);
1036                 awindow->gui->update_assets();
1037                 sync_parameters(CHANGE_EDL);
1038         }
1041 int MWindow::paste_assets(double position, Track *dest_track)
1043         int result = 0;
1045         undo->update_undo_before(_("paste assets"), LOAD_EDITS);
1049         if(session->drag_assets->total)
1050         {
1051                 load_assets(session->drag_assets, 
1052                         position, 
1053                         LOAD_PASTE,
1054                         dest_track, 
1055                         0,
1056                         edl->session->labels_follow_edits, 
1057                         edl->session->plugins_follow_edits);
1058                 result = 1;
1059         }
1062         if(session->drag_clips->total)
1063         {
1064                 paste_edls(session->drag_clips, 
1065                         LOAD_PASTE, 
1066                         dest_track,
1067                         position, 
1068                         edl->session->labels_follow_edits, 
1069                         edl->session->plugins_follow_edits);
1070                 result = 1;
1071         }
1074         save_backup();
1076         undo->update_undo_after();
1077         restart_brender();
1078         gui->update(1, 
1079                 2,
1080                 1,
1081                 0,
1082                 0,
1083                 1,
1084                 0);
1085         sync_parameters(CHANGE_EDL);
1086         return result;
1089 void MWindow::load_assets(ArrayList<Asset*> *new_assets, 
1090         double position, 
1091         int load_mode,
1092         Track *first_track,
1093         RecordLabels *labels,
1094         int edit_labels,
1095         int edit_plugins)
1097 //printf("MWindow::load_assets 1\n");
1098         if(position < 0) position = edl->local_session->get_selectionstart();
1100         ArrayList<EDL*> new_edls;
1101         for(int i = 0; i < new_assets->total; i++)
1102         {
1103                 EDL *new_edl = new EDL;
1104                 new_edl->create_objects();
1105                 new_edl->copy_session(edl);
1106                 new_edls.append(new_edl);
1109 //printf("MWindow::load_assets 2 %d %d\n", new_assets->values[i]->audio_length, new_assets->values[i]->video_length);
1110                 asset_to_edl(new_edl, new_assets->values[i]);
1113                 if(labels)
1114                         for(RecordLabel *label = labels->first; label; label = label->next)
1115                         {
1116                                 new_edl->labels->toggle_label(label->position, label->position);
1117                         }
1118         }
1119 //printf("MWindow::load_assets 3\n");
1121         paste_edls(&new_edls, 
1122                 load_mode, 
1123                 first_track,
1124                 position,
1125                 edit_labels,
1126                 edit_plugins);
1127 //printf("MWindow::load_assets 4\n");
1130         save_backup();
1131         new_edls.remove_all_objects();
1135 int MWindow::paste_automation()
1137         int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
1139         if(len)
1140         {
1141                 char *string = new char[len + 1];
1142                 gui->get_clipboard()->from_clipboard(string, 
1143                         len, 
1144                         SECONDARY_SELECTION);
1145                 FileXML file;
1146                 file.read_from_string(string);
1148                 undo->update_undo_before(_("paste keyframes"), LOAD_AUTOMATION); 
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_after(); 
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                 undo->update_undo_before(_("paste default keyframe"), LOAD_AUTOMATION); 
1184                 edl->tracks->paste_default_keyframe(&file); 
1185                 undo->update_undo_after(); 
1188                 restart_brender();
1189                 update_plugin_guis();
1190                 gui->canvas->draw_overlays();
1191                 gui->canvas->flash();
1192                 sync_parameters(CHANGE_PARAMS);
1193                 gui->patchbay->update();
1194                 cwindow->update(1, 0, 0);
1195                 delete [] string;
1196                 save_backup();
1197         }
1199         return 0;
1203 // Insert edls with project deletion and index file generation.
1204 int MWindow::paste_edls(ArrayList<EDL*> *new_edls, 
1205         int load_mode, 
1206         Track *first_track,
1207         double current_position,
1208         int edit_labels,
1209         int edit_plugins)
1211         ArrayList<Track*> destination_tracks;
1212         int need_new_tracks = 0;
1214         if(!new_edls->total) return 0;
1215 //printf("MWindow::paste_edls 1\n");
1217 // Delete current project
1218         if(load_mode == LOAD_REPLACE ||
1219                 load_mode == LOAD_REPLACE_CONCATENATE)
1220         {
1221                 edl->save_defaults(defaults);
1222                 hide_plugins();
1223 // this has to be cleaned because patches[x]->track points nowhere 
1224 // after next call
1225                 patches->delete_all_patches();    
1226                 delete edl;
1227                 edl = new EDL;
1228                 edl->create_objects();
1229                 edl->copy_session(new_edls->values[0]);
1230                 gui->mainmenu->update_toggles();
1232 // Insert labels for certain modes constitutively
1233                 edit_labels = 1;
1234                 edit_plugins = 1;
1235         }
1236 //printf("MWindow::paste_edls 2\n");
1238 // Assume any paste operation from the same EDL won't contain any clips.
1239 // If it did it would duplicate every clip here.
1240         for(int i = 0; i < new_edls->total; i++)
1241         {
1242                 EDL *new_edl = new_edls->values[i];
1244                 for(int j = 0; j < new_edl->clips.total; j++)
1245                 {
1246                         edl->add_clip(new_edl->clips.values[j]);
1247                 }
1249                 if(new_edl->vwindow_edl)
1250                 {
1251                         if(edl->vwindow_edl) delete edl->vwindow_edl;
1252                         edl->vwindow_edl = new EDL(edl);
1253                         edl->vwindow_edl->create_objects();
1254                         edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
1255                 }
1256         }
1257 //printf("MWindow::paste_edls 2\n");
1259 // Create new tracks in master EDL
1260         if(load_mode == LOAD_REPLACE || 
1261                 load_mode == LOAD_REPLACE_CONCATENATE ||
1262                 load_mode == LOAD_NEW_TRACKS)
1263         {
1264                 need_new_tracks = 1;
1265                 for(int i = 0; i < new_edls->total; i++)
1266                 {
1267                         EDL *new_edl = new_edls->values[i];
1268                         for(Track *current = new_edl->tracks->first;
1269                                 current;
1270                                 current = NEXT)
1271                         {
1272                                 if(current->data_type == TRACK_VIDEO)
1273                                 {
1274                                         edl->tracks->add_video_track(0, 0);
1275                                         if(current->draw) edl->tracks->last->draw = 1;
1276                                         destination_tracks.append(edl->tracks->last);
1277                                 }
1278                                 else
1279                                 if(current->data_type == TRACK_AUDIO)
1280                                 {
1281                                         edl->tracks->add_audio_track(0, 0);
1282                                         destination_tracks.append(edl->tracks->last);
1283                                 }
1284                                 edl->session->highlighted_track = edl->tracks->total() - 1;
1285                         }
1287 // Base track count on first EDL only for concatenation
1288                         if(load_mode == LOAD_REPLACE_CONCATENATE) break;
1289                 }
1290         }
1291         else
1292 // Recycle existing tracks of master EDL
1293         if(load_mode == LOAD_CONCATENATE || load_mode == LOAD_PASTE)
1294         {
1295 // The point of this is to shift forward labels after the selection so they can
1296 // then be shifted back to their original locations without recursively
1297 // shifting back every paste.
1298                 if(load_mode == LOAD_PASTE && edl->session->labels_follow_edits)
1299                         edl->labels->clear(edl->local_session->get_selectionstart(),
1300                                                 edl->local_session->get_selectionend(),
1301                                                 1);
1302         
1303                 Track *current = first_track ? first_track : edl->tracks->first;
1304                 for( ; current; current = NEXT)
1305                 {
1306                         if(current->record)
1307                         {
1308                                 destination_tracks.append(current);
1310 // This should be done in the caller so we don't get recursive clear disease.
1311 //                              if(load_mode == LOAD_PASTE)
1312 //                                      current->clear(edl->local_session->get_selectionstart(),
1313 //                                              edl->local_session->get_selectionend(),
1314 //                                              1,
1315 //                                              edl->session->labels_follow_edits, 
1316 //                                              edl->session->plugins_follow_edits,
1317 //                                              1);
1318                         }
1319                 }
1320         }
1323 //printf("MWindow::paste_edls 2\n");
1325         int destination_track = 0;
1326         double *paste_position = new double[destination_tracks.total];
1332 // Iterate through the edls
1333         for(int i = 0; i < new_edls->total; i++)
1334         {
1335                 EDL *new_edl = new_edls->values[i];
1336                 double edl_length = new_edl->local_session->clipboard_length ?
1337                         new_edl->local_session->clipboard_length :
1338                         new_edl->tracks->total_length();
1339 // printf("MWindow::paste_edls 2\n");
1340 // new_edl->dump();
1344 // Resample EDL to master rates
1345                 new_edl->resample(new_edl->session->sample_rate, 
1346                         edl->session->sample_rate, 
1347                         TRACK_AUDIO);
1348                 new_edl->resample(new_edl->session->frame_rate, 
1349                         edl->session->frame_rate, 
1350                         TRACK_VIDEO);
1354 //printf("MWindow::paste_edls 2 %d\n", new_edl->assets->total());
1355 // Add assets and prepare index files
1356                 edl->update_assets(new_edl);
1357                 for(Asset *new_asset = edl->assets->first;
1358                         new_asset;
1359                         new_asset = new_asset->next)
1360                 {
1361                         mainindexes->add_next_asset(new_asset);
1362                 }
1365 // Get starting point of insertion.  Need this to paste labels.
1366                 switch(load_mode)
1367                 {
1368                         case LOAD_REPLACE:
1369                         case LOAD_NEW_TRACKS:
1370                                 current_position = 0;
1371                                 break;
1373                         case LOAD_CONCATENATE:
1374                         case LOAD_REPLACE_CONCATENATE:
1375                                 destination_track = 0;
1376                                 if(destination_tracks.total)
1377                                         current_position = destination_tracks.values[0]->get_length();
1378                                 else
1379                                         current_position = 0;
1380                                 break;
1382                         case LOAD_PASTE:
1383                                 destination_track = 0;
1384                                 if(i == 0)
1385                                 {
1386                                         for(int j = 0; j < destination_tracks.total; j++)
1387                                         {
1388                                                 paste_position[j] = (current_position >= 0) ? 
1389                                                         current_position :
1390                                                         edl->local_session->get_selectionstart();
1391                                         }
1392                                 }
1393                                 break;
1395                         case LOAD_RESOURCESONLY:
1396                                 edl->add_clip(new_edl);
1397                                 break;
1398                 }
1403 // Insert edl
1404                 if(load_mode != LOAD_RESOURCESONLY)
1405                 {
1406 // Insert labels
1407 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
1408                         if(load_mode == LOAD_PASTE)
1409                                 edl->labels->insert_labels(new_edl->labels, 
1410                                         destination_tracks.total ? paste_position[0] : 0.0,
1411                                         edl_length,
1412                                         edit_labels);
1413                         else
1414                                 edl->labels->insert_labels(new_edl->labels, 
1415                                         current_position,
1416                                         edl_length,
1417                                         edit_labels);
1419                         for(Track *new_track = new_edl->tracks->first; 
1420                                 new_track; 
1421                                 new_track = new_track->next)
1422                         {
1423 // Get destination track of same type as new_track
1424                                 for(int k = 0; 
1425                                         k < destination_tracks.total &&
1426                                         destination_tracks.values[destination_track]->data_type != new_track->data_type;
1427                                         k++, destination_track++)
1428                                 {
1429                                         if(destination_track >= destination_tracks.total - 1)
1430                                                 destination_track = 0;
1431                                 }
1433 // Insert data into destination track
1434                                 if(destination_track < destination_tracks.total &&
1435                                         destination_tracks.values[destination_track]->data_type == new_track->data_type)
1436                                 {
1437                                         Track *track = destination_tracks.values[destination_track];
1439 // Replace default keyframes if first EDL and new tracks were created.
1440 // This means data copied from one track and pasted to another won't retain
1441 // the camera position unless it's a keyframe.  If it did, previous data in the
1442 // track might get unknowingly corrupted.  Ideally we would detect when differing
1443 // default keyframes existed and create discrete keyframes for both.
1444                                         int replace_default = (i == 0) && need_new_tracks;
1446 //printf("MWindow::paste_edls 1 %d\n", replace_default);
1447 // Insert new track at current position
1448                                         switch(load_mode)
1449                                         {
1450                                                 case LOAD_REPLACE_CONCATENATE:
1451                                                 case LOAD_CONCATENATE:
1452                                                         current_position = track->get_length();
1453                                                         break;
1455                                                 case LOAD_PASTE:
1456                                                         current_position = paste_position[destination_track];
1457                                                         paste_position[destination_track] += new_track->get_length();
1458                                                         break;
1459                                         }
1461                                         track->insert_track(new_track, 
1462                                                 current_position, 
1463                                                 replace_default,
1464                                                 edit_plugins);
1465                                 }
1467 // Get next destination track
1468                                 destination_track++;
1469                                 if(destination_track >= destination_tracks.total)
1470                                         destination_track = 0;
1471                         }
1472                 }
1474                 if(load_mode == LOAD_PASTE)
1475                         current_position += edl_length;
1476         }
1477 //printf("MWindow::paste_edls 3\n");
1479         if(paste_position) delete [] paste_position;
1481 // This is already done in load_filenames and everything else that uses paste_edls
1482 //      update_project(load_mode);
1484 //printf("MWindow::paste_edls 5\n");
1486 // Start examining next batch of index files
1487         mainindexes->start_build();
1488 //printf("MWindow::paste_edls 6\n");
1490 // Don't save a backup after loading since the loaded file is on disk already.
1492         return 0;
1495 void MWindow::paste_silence()
1497         double start = edl->local_session->get_selectionstart();
1498         double end = edl->local_session->get_selectionend();
1499     undo->update_undo_before(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
1500         edl->paste_silence(start, 
1501                 end, 
1502                 edl->session->labels_follow_edits, 
1503                 edl->session->plugins_follow_edits);
1504         edl->optimize();
1505         save_backup();
1506         undo->update_undo_after();
1508         update_plugin_guis();
1509         restart_brender();
1510         gui->update(1, 2, 1, 1, 1, 1, 0);
1511         cwindow->update(1, 0, 0, 0, 1);
1512         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1513                                                         CHANGE_EDL,
1514                                                         edl,
1515                                                         1);
1518 void MWindow::paste_transition()
1520     undo->update_undo_before(_("transition"), LOAD_EDITS);
1521 // Only the first transition gets dropped.
1522         PluginServer *server = session->drag_pluginservers->values[0];
1523         if(server->audio)
1524                 strcpy(edl->session->default_atransition, server->title);
1525         else
1526                 strcpy(edl->session->default_vtransition, server->title);
1528         edl->tracks->paste_transition(server, session->edit_highlighted);
1529         save_backup();
1530         undo->update_undo_after();
1532         if(server->video) restart_brender();
1533         sync_parameters(CHANGE_ALL);
1536 void MWindow::paste_transition_cwindow(Track *dest_track)
1538         undo->update_undo_before(_("transition"), LOAD_EDITS);
1539         PluginServer *server = session->drag_pluginservers->values[0];
1540         edl->tracks->paste_video_transition(server, 1);
1541         save_backup();
1542         restart_brender();
1543         gui->update(0, 1, 0, 0, 0, 0, 0);
1544         sync_parameters(CHANGE_ALL);
1547 void MWindow::paste_audio_transition()
1549         PluginServer *server = scan_plugindb(edl->session->default_atransition,
1550                 TRACK_AUDIO);
1551         if(!server)
1552         {
1553                 char string[BCTEXTLEN];
1554                 sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
1555                 gui->show_message(string);
1556                 return;
1557         }
1559     undo->update_undo_before(_("paste transition"), LOAD_EDITS);
1560         edl->tracks->paste_audio_transition(server);
1561         save_backup();
1562         undo->update_undo_after();
1564         sync_parameters(CHANGE_ALL);
1565         gui->update(0, 1, 0, 0, 0, 0, 0);
1568 void MWindow::paste_video_transition()
1570         PluginServer *server = scan_plugindb(edl->session->default_vtransition,
1571                 TRACK_VIDEO);
1572         if(!server)
1573         {
1574                 char string[BCTEXTLEN];
1575                 sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
1576                 gui->show_message(string);
1577                 return;
1578         }
1581     undo->update_undo_before(_("paste transition"), LOAD_EDITS);
1582         edl->tracks->paste_video_transition(server);
1583         save_backup();
1584         undo->update_undo_after();
1586         sync_parameters(CHANGE_ALL);
1587         restart_brender();
1588         gui->update(0, 1, 0, 0, 0, 0, 0);
1592 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
1595         calling_window_gui->unlock_window();
1597         cwindow->playback_engine->que->send_command(STOP,
1598                 CHANGE_NONE, 
1599                 0,
1600                 0);
1601         vwindow->playback_engine->que->send_command(STOP,
1602                 CHANGE_NONE, 
1603                 0,
1604                 0);
1605         cwindow->playback_engine->interrupt_playback(0);
1606         vwindow->playback_engine->interrupt_playback(0);
1609         cwindow->gui->lock_window("MWindow::redo_entry");
1610         vwindow->gui->lock_window("MWindow::undo_entry 2");
1611         gui->lock_window();
1613         undo->redo(); 
1615         save_backup();
1616         update_plugin_states();
1617         update_plugin_guis();
1618         restart_brender();
1619         gui->update(1, 2, 1, 1, 1, 1, 0);
1620         cwindow->update(1, 1, 1, 1, 1);
1622         if (calling_window_gui != cwindow->gui) 
1623                 cwindow->gui->unlock_window();
1624         if (calling_window_gui != gui)
1625                 gui->unlock_window();
1626         if (calling_window_gui != vwindow->gui)
1627                 vwindow->gui->unlock_window();
1629         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1630                            CHANGE_ALL,
1631                            edl,
1632                            1);
1633         
1637 void MWindow::resize_track(Track *track, int w, int h)
1639         undo->update_undo_before(_("resize track"), LOAD_ALL);
1640         track->track_w = w;
1641         track->track_h = h;
1642         undo->update_undo_after();
1643         save_backup();
1645         restart_brender();
1646         sync_parameters(CHANGE_EDL);
1650 class InPointUndoItem : public UndoStackItem
1652 public:
1653         InPointUndoItem(double old_position, double new_position, EDL *edl);
1654         void undo();
1655         void redo();
1656         int get_size();
1657 private:
1658         double old_position;
1659         double new_position;
1660         EDL *edl;
1663 InPointUndoItem::InPointUndoItem(
1664       double old_position, double new_position, EDL *edl)
1666    set_description(_("in point"));
1667    this->old_position = old_position;
1668    this->new_position = new_position;
1669    this->edl = edl;
1672 void InPointUndoItem::undo()
1674    edl->set_inpoint(old_position);
1677 void InPointUndoItem::redo()
1679    edl->set_inpoint(new_position);
1682 int InPointUndoItem::get_size()
1684    return 20;
1687 void MWindow::set_inpoint(int is_mwindow)
1689    InPointUndoItem *undo_item;
1691    undo_item = new InPointUndoItem(edl->local_session->in_point,
1692          edl->local_session->selectionstart, edl);
1693    undo->push_undo_item(undo_item);
1695         edl->set_inpoint(edl->local_session->selectionstart);
1696         save_backup();
1698         if(!is_mwindow)
1699         {
1700                 gui->lock_window("MWindow::set_inpoint 1");
1701         }
1702         gui->timebar->update();
1703         gui->flush();
1704         if(!is_mwindow)
1705         {
1706                 gui->unlock_window();
1707         }
1709         if(is_mwindow)
1710         {
1711                 cwindow->gui->lock_window("MWindow::set_inpoint 2");
1712         }
1713         cwindow->gui->timebar->update();
1714         cwindow->gui->flush();
1715         if(is_mwindow)
1716         {
1717                 cwindow->gui->unlock_window();
1718         }
1721 class OutPointUndoItem : public UndoStackItem
1723 public:
1724         OutPointUndoItem(double old_position, double new_position, EDL *edl);
1725         void undo();
1726         void redo();
1727         int get_size();
1728 private:
1729         double old_position;
1730         double new_position;
1731         EDL *edl;
1734 OutPointUndoItem::OutPointUndoItem(
1735       double old_position, double new_position, EDL *edl)
1737    set_description(_("out point"));
1738    this->old_position = old_position;
1739    this->new_position = new_position;
1740    this->edl = edl;
1743 void OutPointUndoItem::undo()
1745    edl->set_outpoint(old_position);
1748 void OutPointUndoItem::redo()
1750    edl->set_outpoint(new_position);
1753 int OutPointUndoItem::get_size()
1755    return 20;
1758 void MWindow::set_outpoint(int is_mwindow)
1760    OutPointUndoItem *undo_item;
1762    undo_item = new OutPointUndoItem(edl->local_session->out_point,
1763          edl->local_session->selectionend, edl);
1764    undo->push_undo_item(undo_item);
1766         edl->set_outpoint(edl->local_session->selectionend);
1767         save_backup();
1769         if(!is_mwindow)
1770         {
1771                 gui->lock_window("MWindow::set_outpoint 1");
1772         }
1773         gui->timebar->update();
1774         gui->flush();
1775         if(!is_mwindow)
1776         {
1777                 gui->unlock_window();
1778         }
1780         if(is_mwindow)
1781         {
1782                 cwindow->gui->lock_window("MWindow::set_outpoint 2");
1783         }
1784         cwindow->gui->timebar->update();
1785         cwindow->gui->flush();
1786         if(is_mwindow)
1787         {
1788                 cwindow->gui->unlock_window();
1789         }
1792 void MWindow::splice(EDL *source)
1794         FileXML file;
1796         source->copy(source->local_session->in_point, 
1797                 source->local_session->out_point, 
1798                 1,
1799                 0,
1800                 0,
1801                 &file,
1802                 plugindb,
1803                 "",
1804                 1);
1806         undo->update_undo_before(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
1809 //file.dump();
1810         double start = edl->local_session->get_selectionstart();
1811         double end = edl->local_session->get_selectionend();
1813         paste(start, 
1814                 start, 
1815                 &file,
1816                 edl->session->labels_follow_edits,
1817                 edl->session->plugins_follow_edits);
1819         edl->local_session->selectionstart = 
1820                 edl->local_session->selectionend =
1821                 start + 
1822                 source->local_session->out_point - 
1823                 source->local_session->in_point;
1825         save_backup();
1826         undo->update_undo_after();
1827         update_plugin_guis();
1828         restart_brender();
1829         gui->update(1, 1, 1, 1, 0, 1, 0);
1830         sync_parameters(CHANGE_EDL);
1833 void MWindow::to_clip()
1835         FileXML file;
1836         double start, end;
1837         
1838         start = edl->local_session->get_selectionstart();
1839         end = edl->local_session->get_selectionend();
1841         if(EQUIV(end, start)) 
1842         {
1843                 start = 0;
1844                 end = edl->tracks->total_length();
1845         }
1847 // Don't copy all since we don't want the clips twice.
1848         edl->copy(start, 
1849                 end, 
1850                 0,
1851                 0,
1852                 0,
1853                 &file,
1854                 plugindb,
1855                 "",
1856                 1);
1858 //printf("MWindow::to_clip 1 %s\n", edl->local_session->clip_title);
1860 //file.dump();
1863         EDL *new_edl = new EDL(edl);
1864         new_edl->create_objects();
1865         new_edl->load_xml(plugindb, &file, LOAD_ALL);
1866         sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
1867         new_edl->local_session->selectionstart = new_edl->local_session->selectionend = 0.0;
1869 //printf("VWindowEditing::to_clip 2 %d\n", edl->assets->total());
1870         awindow->clip_edit->create_clip(new_edl);
1871         save_backup();
1872 //printf("VWindowEditing::to_clip 3 %d\n", edl->assets->total());
1875 class LabelUndoItem : public UndoStackItem
1877 public:
1878       LabelUndoItem(double position1, double position2, EDL *edl);
1879       void undo();
1880       void redo();
1881       int get_size();
1882 private:
1883       double position1;
1884       double position2;
1885       EDL *edl;
1888 LabelUndoItem::LabelUndoItem(
1889       double position1, double position2, EDL *edl)
1891    set_description(_("label"));
1892    this->position1 = position1;
1893    this->position2 = position2;
1894    this->edl = edl;
1897 void LabelUndoItem::undo()
1899         edl->labels->toggle_label(position1, position2);
1902 void LabelUndoItem::redo()
1904         edl->labels->toggle_label(position1, position2);
1907 int LabelUndoItem::get_size()
1909    return 20;
1912 int MWindow::toggle_label(int is_mwindow)
1914    LabelUndoItem *undo_item;
1915         double position1, position2;
1917 //printf("MWindow::toggle_label 1\n");
1919         if(cwindow->playback_engine->is_playing_back)
1920         {
1921                 position1 = position2 = 
1922                         cwindow->playback_engine->get_tracking_position();
1923         }
1924         else
1925         {
1926                 position1 = edl->local_session->selectionstart;
1927                 position2 = edl->local_session->selectionend;
1928         }
1930 //printf("MWindow::toggle_label 1 %f %f\n", position1,position2 );
1931         position1 = edl->align_to_frame(position1, 0);
1932         position2 = edl->align_to_frame(position2, 0);
1934 //printf("MWindow::toggle_label 1\n");
1935    undo_item = new LabelUndoItem(position1, position2, edl);
1936    undo->push_undo_item(undo_item);
1938         edl->labels->toggle_label(position1, position2);
1939         save_backup();
1941 //printf("MWindow::toggle_label 1\n");
1942         if(!is_mwindow)
1943         {
1944                 gui->lock_window("MWindow::toggle_label 1");
1945         }
1946         gui->timebar->update();
1947         gui->canvas->activate();
1948         gui->flush();
1949         if(!is_mwindow)
1950         {
1951                 gui->unlock_window();
1952         }
1954 //printf("MWindow::toggle_label 1\n");
1955         if(is_mwindow)
1956         {
1957                 cwindow->gui->lock_window("MWindow::toggle_label 2");
1958         }
1959         cwindow->gui->timebar->update();
1960         cwindow->gui->flush();
1961         if(is_mwindow)
1962         {
1963                 cwindow->gui->unlock_window();
1964         }
1966 //printf("MWindow::toggle_label 1\n");
1967 //printf("MWindow::toggle_label 2\n");
1968         return 0;
1971 void MWindow::trim_selection()
1973         undo->update_undo_before(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
1976         edl->trim_selection(edl->local_session->get_selectionstart(), 
1977                 edl->local_session->get_selectionend(), 
1978                 edl->session->labels_follow_edits, 
1979                 edl->session->plugins_follow_edits);
1981         save_backup();
1982         undo->update_undo_after();
1983         update_plugin_guis();
1984         gui->update(1, 2, 1, 1, 1, 1, 0);
1985         restart_brender();
1986         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1987                                                         CHANGE_EDL,
1988                                                         edl,
1989                                                         1);
1994 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
1996 //      if(is_mwindow)
1997 //              gui->unlock_window();
1998 //      else
1999 //              cwindow->gui->unlock_window();
2000         calling_window_gui->unlock_window();
2002         cwindow->playback_engine->que->send_command(STOP,
2003                 CHANGE_NONE, 
2004                 0,
2005                 0);
2006         vwindow->playback_engine->que->send_command(STOP,
2007                 CHANGE_NONE, 
2008                 0,
2009                 0);
2010         cwindow->playback_engine->interrupt_playback(0);
2011         vwindow->playback_engine->interrupt_playback(0);
2013         cwindow->gui->lock_window("MWindow::undo_entry 1");
2014         vwindow->gui->lock_window("MWindow::undo_entry 4");
2015         gui->lock_window("MWindow::undo_entry 2");
2017         undo->undo(); 
2019         save_backup();
2020         restart_brender();
2021         update_plugin_states();
2022         update_plugin_guis();
2023         gui->update(1, 2, 1, 1, 1, 1, 0);
2024         cwindow->update(1, 1, 1, 1, 1);
2026 //      if(is_mwindow)
2027 //              cwindow->gui->unlock_window();
2028 //      else
2029 //              gui->unlock_window();
2030         if (calling_window_gui != cwindow->gui) 
2031                 cwindow->gui->unlock_window();
2032         if (calling_window_gui != gui)
2033                 gui->unlock_window();
2034         if (calling_window_gui != vwindow->gui)
2035                 vwindow->gui->unlock_window();
2036         
2038         awindow->gui->lock_window("MWindow::undo_entry 3");
2039         awindow->gui->update_assets();
2040         awindow->gui->flush();
2041         awindow->gui->unlock_window();
2042         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2043                            CHANGE_ALL,
2044                            edl,
2045                            1);
2050 void MWindow::new_folder(char *new_folder)
2052         undo->update_undo_before(_("new folder"), LOAD_ALL);
2053         edl->new_folder(new_folder);
2054         undo->update_undo_after();
2055         awindow->gui->lock_window("MWindow::new_folder");
2056         awindow->gui->update_assets();
2057         awindow->gui->unlock_window();
2060 void MWindow::delete_folder(char *folder)
2062         undo->update_undo_before(_("new folder"), LOAD_ALL);
2063         undo->update_undo_after();
2066 void MWindow::select_point(double position)
2068         edl->local_session->selectionstart = 
2069                 edl->local_session->selectionend = position;
2070 // Que the CWindow
2071         cwindow->update(1, 0, 0, 0, 1);
2072         update_plugin_guis();
2073         gui->patchbay->update();
2074         gui->cursor->hide();
2075         gui->cursor->draw();
2076         gui->mainclock->update(edl->local_session->selectionstart);
2077         gui->zoombar->update();
2078         gui->canvas->flash();
2079         gui->flush();