cin_db Makefile tweak, awdw vicon stop draw lock rework,
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mwindowedit.C
index d0a1259484fe7aa4cf088d8690452f962fed1a65..d424d60879335f2f4dc267f2b57dedb9f88f47dc 100644 (file)
@@ -85,7 +85,8 @@
 void MWindow::add_audio_track_entry(int above, Track *dst)
 {
        undo_before();
-       add_audio_track(above, dst);
+       Track *track = add_audio_track(above, dst);
+       track->master = 1;
        save_backup();
        undo_after(_("add track"), LOAD_ALL);
 
@@ -95,10 +96,11 @@ void MWindow::add_audio_track_entry(int above, Track *dst)
        cwindow->refresh_frame(CHANGE_EDL);
 }
 
-void MWindow::add_video_track_entry(Track *dst)
+void MWindow::add_video_track_entry(int above, Track *dst)
 {
        undo_before();
-       add_video_track(1, dst);
+       Track *track = add_video_track(above, dst);
+       track->master = 1;
        undo_after(_("add track"), LOAD_ALL);
 
        restart_brender();
@@ -109,10 +111,11 @@ void MWindow::add_video_track_entry(Track *dst)
        save_backup();
 }
 
-void MWindow::add_subttl_track_entry(Track *dst)
+void MWindow::add_subttl_track_entry(int above, Track *dst)
 {
        undo_before();
-       add_subttl_track(1, dst);
+       Track *track = add_subttl_track(above, dst);
+       track->master = 1;
        undo_after(_("add track"), LOAD_ALL);
 
        restart_brender();
@@ -124,28 +127,28 @@ void MWindow::add_subttl_track_entry(Track *dst)
 }
 
 
-int MWindow::add_audio_track(int above, Track *dst)
+Track *MWindow::add_audio_track(int above, Track *dst)
 {
-       edl->tracks->add_audio_track(above, dst);
+       Track *track = edl->tracks->add_audio_track(above, dst);
        edl->tracks->update_y_pixels(theme);
        save_backup();
-       return 0;
+       return track;
 }
 
-int MWindow::add_video_track(int above, Track *dst)
+Track *MWindow::add_video_track(int above, Track *dst)
 {
-       edl->tracks->add_video_track(above, dst);
+       Track *track = edl->tracks->add_video_track(above, dst);
        edl->tracks->update_y_pixels(theme);
        save_backup();
-       return 0;
+       return track;
 }
 
-int MWindow::add_subttl_track(int above, Track *dst)
+Track *MWindow::add_subttl_track(int above, Track *dst)
 {
-       edl->tracks->add_subttl_track(above, dst);
+       Track *track = edl->tracks->add_subttl_track(above, dst);
        edl->tracks->update_y_pixels(theme);
        save_backup();
-       return 0;
+       return track;
 }
 
 void MWindow::asset_to_all()
@@ -774,17 +777,17 @@ void MWindow::insert_effects_canvas(Track *dest_track, double start, double leng
        for( Track *track=dest_track; track; track=track->next ) {
                if( gang && track->master && !first_track ) break;
                if( track->data_type != data_type ) continue;
-               if( !track->armed ) continue;
+               if( !track->is_armed() ) continue;
                int module = edl->tracks->number_of(track);
                for( int i=0; i<session->drag_pluginservers->total; ++i ) {
                        PluginServer *plugin = session->drag_pluginservers->values[i];
-                       int shared = gang && plugin->multichannel ? 1 : 0;
+                       int shared = gang; // && plugin->multichannel ? 1 : 0;
                        int plugin_type = !first_track && shared ?
                                PLUGIN_SHAREDPLUGIN : PLUGIN_STANDALONE;
                        SharedLocation *shared_location = !first_track ?
                                &shared_locations[i] : &shared_locations.append();
                        insert_effect(plugin->title, shared_location, track,
-                               pluginset, start, length, plugin_type);
+                                       pluginset, start, length, plugin_type);
                        if( first_track && shared ) {
                                shared_location->module = module;
                                shared_location->plugin = pluginset ?
@@ -829,38 +832,34 @@ void MWindow::insert_effect(char *title, SharedLocation *shared_location,
        SharedLocation shared_location_local;
        shared_location_local.copy_from(shared_location);
        int first_track = 1;
+       double start_pos = edl->local_session->get_selectionstart(1);
+       double end_pos = edl->local_session->get_selectionend(1);
        for( ; current; current=NEXT ) {
-               if( current->data_type == data_type && current->is_armed() ) {
-                       double start =  edl->local_session->get_selectionstart(1);
-                       double end = edl->local_session->get_selectionend(1);
-                       double length = end - start;
-                       if( start >= end ) {
-                               start = 0;
-                               length = current->get_length();
-                       }
-                       insert_effect(title, &shared_location_local,
+               if( current->data_type != data_type ) continue;
+               if( !current->is_armed() ) continue;
+               double start = start_pos, end = end_pos;
+               if( plugin_type == PLUGIN_STANDALONE && start >= end ) {
+                       start = 0;
+                       end = current->get_length();
+               }
+               double length = end - start;
+               insert_effect(title, &shared_location_local,
                                current, 0, start, length, plugin_type);
-
-                       if( first_track ) {
-                               if( plugin_type == PLUGIN_STANDALONE && single_standalone ) {
-                                       plugin_type = PLUGIN_SHAREDPLUGIN;
-                                       shared_location_local.module = edl->tracks->number_of(current);
-                                       shared_location_local.plugin = current->plugin_set.total - 1;
-                               }
-                               first_track = 0;
+               if( first_track ) {
+                       if( plugin_type == PLUGIN_STANDALONE && single_standalone ) {
+                               plugin_type = PLUGIN_SHAREDPLUGIN;
+                               shared_location_local.module = edl->tracks->number_of(current);
+                               shared_location_local.plugin = current->plugin_set.total - 1;
+                               start_pos = start;  end_pos = end;
                        }
+                       first_track = 0;
                }
        }
 }
 
-
 void MWindow::insert_effect(char *title,
-       SharedLocation *shared_location,
-       Track *track,
-       PluginSet *plugin_set,
-       double start,
-       double length,
-       int plugin_type)
+               SharedLocation *shared_location, Track *track, PluginSet *plugin_set,
+               double start, double length, int plugin_type)
 {
        KeyFrame *default_keyframe = 0;
        PluginServer *server = 0;
@@ -873,9 +872,8 @@ void MWindow::insert_effect(char *title,
                server->save_data(default_keyframe);
        }
 // Insert plugin object
-       track->insert_effect(title, shared_location,
-               default_keyframe, plugin_set,
-               start, length, plugin_type);
+       track->insert_effect(title, shared_location, default_keyframe,
+                       plugin_set, start, length, plugin_type);
        track->optimize();
 
        if( plugin_type == PLUGIN_STANDALONE ) {
@@ -1207,6 +1205,56 @@ void MWindow::move_tracks_up()
 }
 
 
+void MWindow::swap_track_down(Track *track)
+{
+       undo_before();
+       edl->tracks->swap_track_down(track);
+       save_backup();
+       undo_after(_("swap track down"), LOAD_ALL);
+
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       sync_parameters(CHANGE_EDL);
+       save_backup();
+}
+
+void MWindow::swap_tracks_down()
+{
+       undo_before();
+       edl->tracks->swap_tracks_down();
+       save_backup();
+       undo_after(_("swap tracks down"), LOAD_ALL);
+
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       sync_parameters(CHANGE_EDL);
+       save_backup();
+}
+
+void MWindow::swap_track_up(Track *track)
+{
+       undo_before();
+       edl->tracks->swap_track_up(track);
+       save_backup();
+       undo_after(_("swap track up"), LOAD_ALL);
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       sync_parameters(CHANGE_EDL);
+       save_backup();
+}
+
+void MWindow::swap_tracks_up()
+{
+       undo_before();
+       edl->tracks->swap_tracks_up();
+       save_backup();
+       undo_after(_("swap tracks up"), LOAD_ALL);
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       sync_parameters(CHANGE_EDL);
+}
+
+
 void MWindow::mute_selection()
 {
        double start = edl->local_session->get_selectionstart();
@@ -2662,3 +2710,103 @@ void MWindow::paste_effects()
        group->remove_user();
 }
 
+void MWindow::align_timecodes()
+{
+       undo_before();
+       double offset = edl->tracks->align_timecodes();
+       set_timecode_offset(offset);
+       save_backup();
+       undo_after(_("align timecodes"), LOAD_ALL);
+       restart_brender();
+       cwindow->refresh_frame(CHANGE_EDL);
+       update_plugin_guis();
+}
+
+
+int MWindow::masters_to_mixers()
+{
+       Track *master_track = edl->tracks->first;
+       while( master_track && !master_track->master )
+               master_track = master_track->next;
+       while( master_track ) { // test for track/mixer conflicts
+               int failed = 0;
+               Track *mixer_last = master_track;
+               Track *track = master_track->next;
+               for( ; track && !track->master; track=track->next )
+                       mixer_last = track;
+               Track *next_track = track;
+               Mixer *master_mixer = 0;
+               for( int i=0, n=edl->mixers.size(); i<n; ++i ) {
+                       if( master_track->index_in(edl->mixers[i]) >= 0 ) {
+                               master_mixer = edl->mixers[i];
+                               break;
+                       }
+               }
+               if( master_mixer ) { // existing mixer track group
+                       for( track=master_track; !failed && track; track=track->next ) {
+                               if( track->index_in(master_mixer) < 0 ) {
+                                       eprintf("Mixer: %s missing track: %s",
+                                               master_mixer->title, track->title);
+                                       failed = 1;
+                               }
+                               if( track == mixer_last ) break;
+                       }
+                       for( int i=0, n=master_mixer->mixer_ids.size(); !failed && i<n; ++i ) {
+                               int mixer_id = master_mixer->mixer_ids[i], found = 0;
+                               for( track=master_track; track; track=track->next ) {
+                                       if( track->mixer_id == mixer_id ) {
+                                               found = 1;
+                                               break;
+                                       }
+                                       if( track == mixer_last ) break;
+                               }
+                               if( !found ) {
+                                       eprintf("Mixer: %s track missing: %s",
+                                               master_mixer->title, track->title);
+                                       failed = 1;
+                               }
+                       }
+               }
+               else { // create mixer
+                       for( track=master_track->next; !failed && track; track=track->next ) {
+                               for( int i=0, n=edl->mixers.size(); !failed && i<n; ++i ) {
+                                       Mixer *mixer = edl->mixers[i];
+                                       if( track->index_in(mixer) >= 0 ) {
+                                               eprintf("Track: %s already exists in mixer: %s",
+                                                       track->title, mixer->title);
+                                               failed = 1;
+                                               break;
+                                       }
+                               }
+                               if( track == mixer_last ) break;
+                       }
+                       if( !failed ) { // new mixer
+                               ZWindow *zwindow = get_mixer(master_mixer);
+                               zwindow->set_title(master_track->title);
+                               sprintf(master_track->title, _("Mixer %d"), zwindow->idx);
+                               for( track=master_track; track; track=track->next ) {
+                                       track->play = track->armed = 0;
+                                       master_mixer->mixer_ids.append(track->get_mixer_id());
+                                       if( track == mixer_last ) break;
+                               }
+                               zwindow->start();
+                       }
+               }
+               master_track = next_track;
+        }
+       return 0;
+}
+
+void MWindow::mix_masters()
+{
+       undo_before();
+       masters_to_mixers();
+       undo_after(_("mix masters"), LOAD_ALL);
+
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       gui->activate_timeline();
+       cwindow->refresh_frame(CHANGE_EDL);
+       save_backup();
+}
+