rework undo compression, add shift viewer overwr/copy/clip/splice, fix paste edl...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / mwindowedit.C
index f4df668bf192ac8a55d30ba30cd457fc48cf663a..b406c7b207f12c4d421eedb58e25b045e3292519 100644 (file)
@@ -34,6 +34,7 @@
 #include "bchash.h"
 #include "edl.h"
 #include "edlsession.h"
+#include "filesystem.h"
 #include "filexml.h"
 #include "floatauto.h"
 #include "floatautos.h"
 #include "vwindow.h"
 #include "vwindowgui.h"
 #include "zoombar.h"
+#include "zwindow.h"
 #include "automation.h"
 #include "maskautos.h"
 
-
 #include <string.h>
 
-
-
-
-
-
 void MWindow::add_audio_track_entry(int above, Track *dst)
 {
        undo->update_undo_before();
@@ -92,13 +88,7 @@ void MWindow::add_audio_track_entry(int above, Track *dst)
        undo->update_undo_after(_("add track"), LOAD_ALL);
 
        restart_brender();
-       gui->update(1,
-               1,
-               0,
-               0,
-               1,
-               0,
-               0);
+       gui->update(1, 1, 0, 0, 1, 0, 0);
        gui->activate_timeline();
 
 //     gui->get_scrollbars(0);
@@ -107,10 +97,7 @@ void MWindow::add_audio_track_entry(int above, Track *dst)
 //     gui->cursor->draw(1);
 //     gui->canvas->flash();
 //     gui->canvas->activate();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-               CHANGE_EDL,
-               edl,
-               1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 void MWindow::add_video_track_entry(Track *dst)
@@ -121,13 +108,7 @@ void MWindow::add_video_track_entry(Track *dst)
 
        restart_brender();
 
-       gui->update(1,
-               1,
-               0,
-               0,
-               1,
-               0,
-               0);
+       gui->update(1, 1, 0, 0, 1, 0, 0);
        gui->activate_timeline();
 //     gui->get_scrollbars(0);
 //     gui->canvas->draw();
@@ -135,10 +116,7 @@ void MWindow::add_video_track_entry(Track *dst)
 //     gui->cursor->draw(1);
 //     gui->canvas->flash();
 //     gui->canvas->activate();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                       CHANGE_EDL,
-                                                       edl,
-                                                       1);
+       cwindow->refresh_frame(CHANGE_EDL);
        save_backup();
 }
 
@@ -149,16 +127,16 @@ void MWindow::add_subttl_track_entry(Track *dst)
        undo->update_undo_after(_("add track"), LOAD_ALL);
 
        restart_brender();
+
+       gui->update(1, 1, 0, 0, 1, 0, 0);
+       gui->activate_timeline();
 //     gui->get_scrollbars(0);
 //     gui->canvas->draw();
 //     gui->patchbay->update();
 //     gui->cursor->draw(1);
 //     gui->canvas->flash();
 //     gui->canvas->activate();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                       CHANGE_EDL,
-                                                       edl,
-                                                       1);
+       cwindow->refresh_frame(CHANGE_EDL);
        save_backup();
 }
 
@@ -187,15 +165,12 @@ int MWindow::add_subttl_track(int above, Track *dst)
        return 0;
 }
 
-
-
-
 void MWindow::asset_to_all()
 {
-       if(!session->drag_assets->size()) return;
+       if( !session->drag_assets->size() ) return;
        Indexable *indexable = session->drag_assets->get(0);
 
-//     if(indexable->have_video())
+//     if( indexable->have_video() )
        {
                int w, h;
 
@@ -210,108 +185,81 @@ void MWindow::asset_to_all()
                int new_samplerate = session->drag_assets->get(0)->get_sample_rate();
 
 
-               if(indexable->have_video())
-               {
+               if( indexable->have_video() ) {
                        edl->session->output_w = w;
                        edl->session->output_h = h;
                        edl->session->frame_rate = new_framerate;
-                       create_aspect_ratio(edl->session->aspect_w,
+                       create_aspect_ratio(
+                               edl->session->aspect_w,
                                edl->session->aspect_h,
-                               w,
-                               h);
+                               w, h);
 
-                       for(Track *current = edl->tracks->first;
-                               current;
-                               current = NEXT)
-                       {
-                               if(current->data_type == TRACK_VIDEO /* &&
-                                       current->record */ )
-                               {
+                       for( Track *current=edl->tracks->first; current; current=NEXT ) {
+                               if( current->data_type == TRACK_VIDEO /* &&
+                                       current->record */  ) {
                                        current->track_w = w;
                                        current->track_h = h;
                                }
                        }
 
 
-                       if(((edl->session->output_w % 4) ||
+                       if( ((edl->session->output_w % 4) ||
                                (edl->session->output_h % 4)) &&
-                               edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
-                       {
+                               edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) {
                                MainError::show_error(
                                        _("This project's dimensions are not multiples of 4 so\n"
                                        "it can't be rendered by OpenGL."));
                        }
 
-
 // Get aspect ratio
-                       if(defaults->get("AUTOASPECT", 0))
-                       {
-                               create_aspect_ratio(edl->session->aspect_w,
+                       if( defaults->get("AUTOASPECT", 0) ) {
+                               create_aspect_ratio(
+                                       edl->session->aspect_w,
                                        edl->session->aspect_h,
-                                       w,
-                                       h);
+                                       w, h);
                        }
                }
 
-               if(indexable->have_audio())
-               {
+               if( indexable->have_audio() ) {
                        edl->session->sample_rate = new_samplerate;
                        edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
                        edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
                }
 
-
                save_backup();
 
                undo->update_undo_after(_("asset to all"), LOAD_ALL);
                restart_brender();
-               gui->update(1,
-                       2,
-                       1,
-                       1,
-                       1,
-                       1,
-                       0);
+               gui->update(1, 2, 1, 1, 1, 1, 0);
                sync_parameters(CHANGE_ALL);
        }
 }
 
-
-
-
-
-
 void MWindow::asset_to_size()
 {
-       if(!session->drag_assets->size()) return;
+       if( !session->drag_assets->size() ) return;
        Indexable *indexable = session->drag_assets->get(0);
 
-       if(indexable->have_video())
-       {
+       if( indexable->have_video() ) {
                int w, h;
                undo->update_undo_before();
 
 // Get w and h
                w = indexable->get_w();
                h = indexable->get_h();
-
-
                edl->session->output_w = w;
                edl->session->output_h = h;
 
-               if(((edl->session->output_w % 4) ||
+               if( ((edl->session->output_w % 4) ||
                        (edl->session->output_h % 4)) &&
-                       edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
-               {
+                       edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) {
                        MainError::show_error(
                                _("This project's dimensions are not multiples of 4 so\n"
                                "it can't be rendered by OpenGL."));
                }
 
-
 // Get aspect ratio
-               if(defaults->get("AUTOASPECT", 0))
-               {
+               if( defaults->get("AUTOASPECT", 0) ) {
                        create_aspect_ratio(edl->session->aspect_w,
                                edl->session->aspect_h,
                                w,
@@ -329,9 +277,8 @@ void MWindow::asset_to_size()
 
 void MWindow::asset_to_rate()
 {
-       if(session->drag_assets->size() &&
-               session->drag_assets->get(0)->have_video())
-       {
+       if( session->drag_assets->size() &&
+               session->drag_assets->get(0)->have_video() ) {
                double new_framerate = session->drag_assets->get(0)->get_frame_rate();
                double old_framerate = edl->session->frame_rate;
                undo->update_undo_before();
@@ -343,19 +290,12 @@ void MWindow::asset_to_rate()
 
                undo->update_undo_after(_("asset to rate"), LOAD_ALL);
                restart_brender();
-               gui->update(1,
-                       2,
-                       1,
-                       1,
-                       1,
-                       1,
-                       0);
+               gui->update(1, 2, 1, 1, 1, 1, 0);
                sync_parameters(CHANGE_ALL);
        }
 }
 
 
-
 void MWindow::clear_entry()
 {
        undo->update_undo_before();
@@ -369,18 +309,14 @@ void MWindow::clear_entry()
        update_plugin_guis();
        gui->update(1, 2, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                          CHANGE_EDL,
-                          edl,
-                          1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 void MWindow::clear(int clear_handle)
 {
        double start = edl->local_session->get_selectionstart();
        double end = edl->local_session->get_selectionend();
-       if(clear_handle || !EQUIV(start, end))
-       {
+       if( clear_handle || !EQUIV(start, end) ) {
                edl->clear(start,
                        end,
                        edl->session->labels_follow_edits,
@@ -469,10 +405,7 @@ void MWindow::concatenate_tracks()
 
        restart_brender();
        gui->update(1, 1, 0, 0, 1, 0, 0);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-               CHANGE_EDL,
-               edl,
-               1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 
@@ -484,32 +417,14 @@ void MWindow::copy()
 
 int MWindow::copy(double start, double end)
 {
-       if(start == end) return 1;
+       if( start == end ) return 1;
 
-//printf("MWindow::copy 1\n");
        FileXML file;
-//printf("MWindow::copy 1\n");
-       edl->copy(start,
-               end,
-               0,
-               0,
-               0,
-               &file,
-               "",
-               1);
-//printf("MWindow::copy 1\n");
-
-// File is now terminated and rewound
-
-//printf("MWindow::copy 1\n");
+       edl->copy(start, end, 0, &file, "", 1);
        const char *file_string = file.string();
        long file_length = strlen(file_string);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               SECONDARY_SELECTION);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               BC_PRIMARY_SELECTION);
-//printf("MWindow::copy\n%s\n", file.string);
-//printf("MWindow::copy 2\n");
+       gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
+       gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
        save_backup();
        return 0;
 }
@@ -517,34 +432,26 @@ int MWindow::copy(double start, double end)
 int MWindow::copy_automation()
 {
        FileXML file;
-       edl->tracks->copy_automation(edl->local_session->get_selectionstart(),
-               edl->local_session->get_selectionend(),
-               &file,
-               0,
-               1);
+       double start = edl->local_session->get_selectionstart();
+       double end = edl->local_session->get_selectionend();
+       edl->tracks->copy_automation(start, end, &file, 0, 1);
        const char *file_string = file.string();
        long file_length = strlen(file_string);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               BC_PRIMARY_SELECTION);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               SECONDARY_SELECTION);
+       gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
+       gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
        return 0;
 }
 
 int MWindow::copy_default_keyframe()
 {
        FileXML file;
-       edl->tracks->copy_automation(edl->local_session->get_selectionstart(),
-               edl->local_session->get_selectionend(),
-               &file,
-               1,
-               0);
+       double start = edl->local_session->get_selectionstart();
+       double end = edl->local_session->get_selectionend();
+       edl->tracks->copy_automation(start, end, &file, 1, 0);
        const char *file_string = file.string();
        long file_length = strlen(file_string);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               BC_PRIMARY_SELECTION);
-       gui->get_clipboard()->to_clipboard(file_string, file_length,
-               SECONDARY_SELECTION);
+       gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
+       gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
        return 0;
 }
 
@@ -556,14 +463,12 @@ void MWindow::crop_video()
 
        undo->update_undo_before();
 // Clamp EDL crop region
-       if(edl->session->crop_x1 > edl->session->crop_x2)
-       {
+       if( edl->session->crop_x1 > edl->session->crop_x2 ) {
                edl->session->crop_x1 ^= edl->session->crop_x2;
                edl->session->crop_x2 ^= edl->session->crop_x1;
                edl->session->crop_x1 ^= edl->session->crop_x2;
        }
-       if(edl->session->crop_y1 > edl->session->crop_y2)
-       {
+       if( edl->session->crop_y1 > edl->session->crop_y2 ) {
                edl->session->crop_y1 ^= edl->session->crop_y2;
                edl->session->crop_y2 ^= edl->session->crop_y1;
                edl->session->crop_y1 ^= edl->session->crop_y2;
@@ -586,8 +491,7 @@ void MWindow::crop_video()
        edl->session->crop_y2 = edl->session->output_h;
 
 // Recalculate aspect ratio
-       if(defaults->get("AUTOASPECT", 0))
-       {
+       if( defaults->get("AUTOASPECT", 0) ) {
                create_aspect_ratio(edl->session->aspect_w,
                        edl->session->aspect_h,
                        edl->session->output_w,
@@ -597,40 +501,93 @@ void MWindow::crop_video()
        undo->update_undo_after(_("crop"), LOAD_ALL);
 
        restart_brender();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-               CHANGE_ALL,
-               edl,
-               1);
+       cwindow->refresh_frame(CHANGE_ALL);
        save_backup();
 }
 
 void MWindow::cut()
 {
-       undo->update_undo_before();
-
        double start = edl->local_session->get_selectionstart();
        double end = edl->local_session->get_selectionend();
+       if( EQUIV(start,end) )
+               blade(start);
+       else
+               cut(start, end);
+}
 
+void MWindow::blade(double position)
+{
+       undo->update_undo_before();
+       edl->blade(position);
+       edl->optimize();
+       save_backup();
+       undo->update_undo_after(_("blade"), LOAD_EDITS | LOAD_TIMEBAR);
+       restart_brender();
+       update_plugin_guis();
+       gui->update(1, 2, 1, 1, 1, 1, 0);
+       cwindow->update(1, 0, 0, 0, 1);
+       awindow->gui->async_update_assets();
+       cwindow->refresh_frame(CHANGE_EDL);
+}
+
+void MWindow::cut(double start, double end, double new_position)
+{
+       undo->update_undo_before();
        copy(start, end);
-       edl->clear(start,
-               end,
+       edl->clear(start, end,
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
 
-
        edl->optimize();
        save_backup();
-       undo->update_undo_after(_("cut"), LOAD_EDITS | LOAD_TIMEBAR);
-
+       undo->update_undo_after(_("split | cut"), LOAD_EDITS | LOAD_TIMEBAR);
+       if( new_position >= 0 ) {
+               edl->local_session->set_selectionstart(new_position);
+               edl->local_session->set_selectionend(new_position);
+       }
        restart_brender();
        update_plugin_guis();
        gui->update(1, 2, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                       CHANGE_EDL,
-                                                       edl,
-                                                       1);
+       awindow->gui->async_update_assets();
+       cwindow->refresh_frame(CHANGE_EDL);
+}
+
+void MWindow::cut_left_edit()
+{
+       double start_pos = edl->local_session->get_selectionstart(1);
+       double position = edl->prev_edit(start_pos);
+       if( position < start_pos )
+               cut(position, start_pos, position);
+}
+
+void MWindow::cut_right_edit()
+{
+       double end_pos = edl->local_session->get_selectionend(1);
+       double position = edl->next_edit(end_pos);
+       if( end_pos < position )
+               cut(end_pos, position, end_pos);
+}
+
+void MWindow::cut_left_label()
+{
+       double start_pos = edl->local_session->get_selectionstart(1);
+       Label *left_label = edl->labels->prev_label(start_pos);
+       if( !left_label ) return;
+       double position = left_label->position;
+       if( position < start_pos )
+               cut(position, start_pos, position);
+}
+
+void MWindow::cut_right_label()
+{
+       double end_pos = edl->local_session->get_selectionend(1);
+       Label *right_label = edl->labels->next_label(end_pos);
+       if( !right_label ) return;
+       double position = right_label->position;
+       if( end_pos < position )
+               cut(end_pos, position, end_pos);
 }
 
 int MWindow::cut_automation()
@@ -673,21 +630,10 @@ int MWindow::cut_default_keyframe()
        return 0;
 }
 
-void MWindow::delete_inpoint()
-{
-       edl->local_session->unset_inpoint();
-       save_backup();
-}
-
-void MWindow::delete_outpoint()
-{
-       edl->local_session->unset_outpoint();
-       save_backup();
-}
 
 void MWindow::delete_track()
 {
-       if (edl->tracks->last)
+       if( edl->tracks->last )
                delete_track(edl->tracks->last);
 }
 
@@ -700,11 +646,9 @@ void MWindow::delete_tracks()
 
        restart_brender();
        update_plugin_states();
+
        gui->update(1, 1, 1, 0, 1, 0, 0);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                          CHANGE_EDL,
-                          edl,
-                          1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 void MWindow::delete_track(Track *track)
@@ -715,24 +659,16 @@ void MWindow::delete_track(Track *track)
 
        restart_brender();
        update_plugin_states();
+
        gui->update(1, 1, 1, 0, 1, 0, 0);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                          CHANGE_EDL,
-                          edl,
-                          1);
+       cwindow->refresh_frame(CHANGE_EDL);
        save_backup();
 }
 
 
-
-
-
 // Insert data from clipboard
-void MWindow::insert(double position,
-       FileXML *file,
-       int edit_labels,
-       int edit_plugins,
-       int edit_autos,
+void MWindow::insert(double position, FileXML *file,
+       int edit_labels, int edit_plugins, int edit_autos,
        EDL *parent_edl)
 {
 // For clipboard pasting make the new edl use a separate session
@@ -749,9 +685,9 @@ void MWindow::insert(double position,
 
 
 
-       if(parent_edl) load_flags &= ~LOAD_SESSION;
-       if(!edl->session->autos_follow_edits) load_flags &= ~LOAD_AUTOMATION;
-       if(!edl->session->labels_follow_edits) load_flags &= ~LOAD_TIMEBAR;
+       if( parent_edl ) load_flags &= ~LOAD_SESSION;
+       if( !edl->session->autos_follow_edits ) load_flags &= ~LOAD_AUTOMATION;
+       if( !edl->session->labels_follow_edits ) load_flags &= ~LOAD_TIMEBAR;
 
        edl->load_xml(file, load_flags);
 
@@ -760,15 +696,9 @@ void MWindow::insert(double position,
 
 
 
-       paste_edls(&new_edls,
-               LOADMODE_PASTE,
-               0,
-               position,
-               edit_labels,
-               edit_plugins,
-               edit_autos,
-               0); // overwrite
-// if(vwindow->edl)
+       paste_edls(&new_edls, LOADMODE_PASTE, 0, position,
+               edit_labels, edit_plugins, edit_autos, 0); // overwrite
+// if( vwindow->edl )
 // printf("MWindow::insert 5 %f %f\n",
 // vwindow->edl->local_session->in_point,
 // vwindow->edl->local_session->out_point);
@@ -781,21 +711,15 @@ void MWindow::insert_effects_canvas(double start,
        double length)
 {
        Track *dest_track = session->track_highlighted;
-       if(!dest_track) return;
+       if( !dest_track ) return;
 
        undo->update_undo_before();
 
-       for(int i = 0; i < session->drag_pluginservers->total; i++)
-       {
+       for( int i=0; i<session->drag_pluginservers->total; ++i ) {
                PluginServer *plugin = session->drag_pluginservers->values[i];
-
-               insert_effect(plugin->title,
-                       0,
-                       dest_track,
+               insert_effect(plugin->title, 0, dest_track,
                        i == 0 ? session->pluginset_highlighted : 0,
-                       start,
-                       length,
-                       PLUGIN_STANDALONE);
+                       start, length, PLUGIN_STANDALONE);
        }
 
        save_backup();
@@ -807,46 +731,31 @@ void MWindow::insert_effects_canvas(double start,
 
 void MWindow::insert_effects_cwindow(Track *dest_track)
 {
-       if(!dest_track) return;
+       if( !dest_track ) return;
 
        undo->update_undo_before();
 
        double start = 0;
        double length = dest_track->get_length();
 
-       if(edl->local_session->get_selectionend() >
-               edl->local_session->get_selectionstart())
-       {
+       if( edl->local_session->get_selectionend() >
+               edl->local_session->get_selectionstart() ) {
                start = edl->local_session->get_selectionstart();
                length = edl->local_session->get_selectionend() -
                        edl->local_session->get_selectionstart();
        }
 
-       for(int i = 0; i < session->drag_pluginservers->total; i++)
-       {
+       for( int i=0; i<session->drag_pluginservers->total; ++i ) {
                PluginServer *plugin = session->drag_pluginservers->values[i];
-
-
-               insert_effect(plugin->title,
-                       0,
-                       dest_track,
-                       0,
-                       start,
-                       length,
-                       PLUGIN_STANDALONE);
+               insert_effect(plugin->title, 0, dest_track, 0,
+                       start, length, PLUGIN_STANDALONE);
        }
 
        save_backup();
        undo->update_undo_after(_("insert effect"), LOAD_EDITS | LOAD_PATCHES);
        restart_brender();
        sync_parameters(CHANGE_EDL);
-       gui->update(1,
-               1,
-               0,
-               0,
-               1,
-               0,
-               0);
+       gui->update(1, 1, 0, 0, 1, 0, 0);
 }
 
 void MWindow::insert_effect(char *title,
@@ -859,23 +768,14 @@ void MWindow::insert_effect(char *title,
        SharedLocation shared_location_local;
        shared_location_local.copy_from(shared_location);
        int first_track = 1;
-       for( ; current; current = NEXT)
-       {
-               if(current->data_type == data_type &&
-                       current->record)
-               {
-                       insert_effect(title,
-                               &shared_location_local,
-                               current,
-                               0,
-                               0,
-                               0,
-                               plugin_type);
-
-                       if(first_track)
-                       {
-                               if(plugin_type == PLUGIN_STANDALONE && single_standalone)
-                               {
+       for( ; current; current=NEXT ) {
+               if( current->data_type == data_type &&
+                       current->record ) {
+                       insert_effect(title, &shared_location_local,
+                               current, 0, 0, 0, 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;
@@ -897,38 +797,21 @@ void MWindow::insert_effect(char *title,
 {
        KeyFrame *default_keyframe = 0;
        PluginServer *server = 0;
-
-
-
-
-
-
 // Get default keyframe
-       if(plugin_type == PLUGIN_STANDALONE)
-       {
+       if( plugin_type == PLUGIN_STANDALONE ) {
                default_keyframe = new KeyFrame;
                server = new PluginServer(*scan_plugindb(title, track->data_type));
 
                server->open_plugin(0, preferences, edl, 0);
                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)
-       {
+       if( plugin_type == PLUGIN_STANDALONE ) {
                server->close_plugin();
                delete server;
                delete default_keyframe;
@@ -947,8 +830,6 @@ int MWindow::modify_edithandles()
                edl->session->autos_follow_edits);
 
        finish_modify_handles();
-
-
 //printf("MWindow::modify_handles 1\n");
        return 0;
 }
@@ -976,21 +857,21 @@ void MWindow::finish_modify_handles()
 {
        int edit_mode = edl->session->edit_handle_mode[session->drag_button];
 
-       if((session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
-               (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT))
-       {
+       if( (session->drag_handle == 1 && edit_mode != MOVE_NO_EDITS) ||
+               (session->drag_handle == 0 && edit_mode == MOVE_ONE_EDIT) ) {
+//printf("MWindow::finish_modify_handles %d\n", __LINE__);
                edl->local_session->set_selectionstart(session->drag_position);
                edl->local_session->set_selectionend(session->drag_position);
        }
        else
-       if(edit_mode != MOVE_NO_EDITS)
-       {
+       if( edit_mode != MOVE_NO_EDITS ) {
+//printf("MWindow::finish_modify_handles %d\n", __LINE__);
                edl->local_session->set_selectionstart(session->drag_start);
                edl->local_session->set_selectionend(session->drag_start);
        }
 
-       if(edl->local_session->get_selectionstart(1) < 0)
-       {
+// clamp the selection to 0
+       if( edl->local_session->get_selectionstart(1) < 0 ) {
                edl->local_session->set_selectionstart(0);
                edl->local_session->set_selectionend(0);
        }
@@ -1001,6 +882,8 @@ void MWindow::finish_modify_handles()
        sync_parameters(CHANGE_EDL);
        update_plugin_guis();
        gui->update(1, 2, 1, 1, 1, 1, 0);
+// label list can be modified
+       awindow->gui->async_update_assets();
        cwindow->update(1, 0, 0, 0, 1);
 }
 
@@ -1036,32 +919,22 @@ void MWindow::move_edits(ArrayList<Edit*> *edits,
        undo->update_undo_after(_("move edit"), LOAD_ALL);
 
        restart_brender();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-               CHANGE_EDL,
-               edl,
-               1);
+       cwindow->refresh_frame(CHANGE_EDL);
 
        update_plugin_guis();
-       gui->update(1,
-               1,      // 1 for incremental drawing.  2 for full refresh
-               1,
-               0,
-               0,
-               0,
-               0);
+       gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
+               1, 0, 0, 0, 0);
 }
 
 void MWindow::move_effect(Plugin *plugin, Track *track, int64_t position)
 {
        undo->update_undo_before();
-       edl->tracks->move_effect(plugin, track, position); 
+       edl->tracks->move_effect(plugin, track, position);
        save_backup();
        undo->update_undo_after(_("paste effect"), LOAD_ALL);
 
        restart_brender();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-               CHANGE_EDL, edl, 1);
-
+       cwindow->refresh_frame(CHANGE_EDL);
        update_plugin_guis();
        gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
                0, 0, 0, 0, 0);
@@ -1075,7 +948,7 @@ void MWindow::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t positio
        undo->update_undo_after(_("move effect"), LOAD_ALL);
 
        restart_brender();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
+       cwindow->refresh_frame(CHANGE_EDL);
        update_plugin_guis();
        gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
                0, 0, 0, 0, 0);
@@ -1090,13 +963,8 @@ void MWindow::move_plugins_up(PluginSet *plugin_set)
        save_backup();
        undo->update_undo_after(_("move effect up"), LOAD_ALL);
        restart_brender();
-       gui->update(1,
-               1,      // 1 for incremental drawing.  2 for full refresh
-               0,
-               0,
-               0,
-               0,
-               0);
+       gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
+               0, 0, 0, 0, 0);
        sync_parameters(CHANGE_EDL);
 }
 
@@ -1109,13 +977,8 @@ void MWindow::move_plugins_down(PluginSet *plugin_set)
        save_backup();
        undo->update_undo_after(_("move effect down"), LOAD_ALL);
        restart_brender();
-       gui->update(1,
-               1,      // 1 for incremental drawing.  2 for full refresh
-               0,
-               0,
-               0,
-               0,
-               0);
+       gui->update(1, 1,      // 1 for incremental drawing.  2 for full refresh
+               0, 0, 0, 0, 0);
        sync_parameters(CHANGE_EDL);
 }
 
@@ -1173,79 +1036,57 @@ void MWindow::mute_selection()
 {
        double start = edl->local_session->get_selectionstart();
        double end = edl->local_session->get_selectionend();
-       if(start != end)
-       {
+       if( start != end ) {
                undo->update_undo_before();
-               edl->clear(start,
-                       end,
-                       0,
+               edl->clear(start, end, 0,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits);
                edl->local_session->set_selectionend(end);
                edl->local_session->set_selectionstart(start);
-               edl->paste_silence(start,
-                       end,
-                       0,
+               edl->paste_silence(start, end, 0,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits);
+
                save_backup();
                undo->update_undo_after(_("mute"), LOAD_EDITS);
 
                restart_brender();
                update_plugin_guis();
                gui->update(1, 2, 1, 1, 1, 1, 0);
-               cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                               CHANGE_EDL,
-                                                               edl,
-                                                               1);
+               cwindow->refresh_frame(CHANGE_EDL);
        }
 }
 
 
-
-void MWindow::overwrite(EDL *source)
+void MWindow::overwrite(EDL *source, int all)
 {
        FileXML file;
 
-       double src_start = source->local_session->get_selectionstart();
-       double overwrite_len = source->local_session->get_selectionend() - src_start;
+       double src_start = all ? 0 :
+               source->local_session->get_selectionstart();
+       double overwrite_len = all ? source->tracks->total_length() :
+               source->local_session->get_selectionend() - src_start;
        double dst_start = edl->local_session->get_selectionstart();
        double dst_len = edl->local_session->get_selectionend() - dst_start;
 
        undo->update_undo_before();
-       if (!EQUIV(dst_len, 0) && (dst_len < overwrite_len))
-       {
+       if( !EQUIV(dst_len, 0) && (dst_len < overwrite_len) ) {
 // in/out points or selection present and shorter than overwrite range
 // shorten the copy range
                overwrite_len = dst_len;
        }
 
-       source->copy(src_start,
-               src_start + overwrite_len,
-               1,
-               0,
-               0,
-               &file,
-               "",
-               1);
+       source->copy(src_start, src_start + overwrite_len, 0, &file, "", 1);
 
 // HACK around paste_edl get_start/endselection on its own
 // so we need to clear only when not using both io points
 // FIXME: need to write simple overwrite_edl to be used for overwrite function
-       if (edl->local_session->get_inpoint() < 0 ||
-               edl->local_session->get_outpoint() < 0)
-               edl->clear(dst_start,
-                       dst_start + overwrite_len,
-                       0,
-                       0,
-                       0);
+       if( edl->local_session->get_inpoint() < 0 ||
+               edl->local_session->get_outpoint() < 0 )
+               edl->clear(dst_start, dst_start + overwrite_len, 0, 0, 0);
 
-       paste(dst_start,
-               dst_start + overwrite_len,
-               &file,
-               0,
-               0,
-               0);
+       paste(dst_start, dst_start + overwrite_len,
+               &file, 0, 0, 0);
 
        edl->local_session->set_selectionstart(dst_start + overwrite_len);
        edl->local_session->set_selectionend(dst_start + overwrite_len);
@@ -1270,12 +1111,9 @@ int MWindow::paste(double start,
        clear(0);
 
 // Want to insert with assets shared with the master EDL.
-       insert(start,
-                       file,
-                       edit_labels,
-                       edit_plugins,
-                       edit_autos,
-                       edl);
+       insert(start, file,
+               edit_labels, edit_plugins, edit_autos,
+               edl);
 
        return 0;
 }
@@ -1285,43 +1123,27 @@ void MWindow::paste()
 {
        double start = edl->local_session->get_selectionstart();
        //double end = edl->local_session->get_selectionend();
-       int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
-
-       if(len)
-       {
-               char *string = new char[len + 1];
+       int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
 
+       if( len ) {
+               char *string = new char[len];
                undo->update_undo_before();
-
-
-               gui->get_clipboard()->from_clipboard(string,
-                       len,
-                       BC_PRIMARY_SELECTION);
+               gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
                FileXML file;
                file.read_from_string(string);
-
-
-
-
                clear(0);
 
-               insert(start,
-                       &file,
+               insert(start, &file,
                        edl->session->labels_follow_edits,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits,
                        0);
 
                edl->optimize();
-
-
                delete [] string;
 
-
-
                save_backup();
 
-
                undo->update_undo_after(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
                restart_brender();
                update_plugin_guis();
@@ -1335,18 +1157,11 @@ void MWindow::paste()
 int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
 {
        int result = 0;
-
        undo->update_undo_before();
 
-
-
-       if(session->drag_assets->total)
-       {
+       if( session->drag_assets->total ) {
                load_assets(session->drag_assets,
-                       position,
-                       LOADMODE_PASTE,
-                       dest_track,
-                       0,
+                       position, LOADMODE_PASTE, dest_track, 0,
                        edl->session->labels_follow_edits,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits,
@@ -1354,13 +1169,9 @@ int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
                result = 1;
        }
 
-
-       if(session->drag_clips->total)
-       {
+       if( session->drag_clips->total ) {
                paste_edls(session->drag_clips,
-                       LOADMODE_PASTE,
-                       dest_track,
-                       position,
+                       LOADMODE_PASTE, dest_track, position,
                        edl->session->labels_follow_edits,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits,
@@ -1368,42 +1179,29 @@ int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
                result = 1;
        }
 
-
        save_backup();
 
        undo->update_undo_after(_("paste assets"), LOAD_EDITS);
        restart_brender();
-       gui->update(1,
-               2,
-               1,
-               0,
-               0,
-               1,
-               0);
+       gui->update(1, 2, 1, 0, 0, 1, 0);
        sync_parameters(CHANGE_EDL);
        return result;
 }
 
 void MWindow::load_assets(ArrayList<Indexable*> *new_assets,
-       double position,
-       int load_mode,
-       Track *first_track,
-       RecordLabels *labels,
-       int edit_labels,
-       int edit_plugins,
-       int edit_autos,
-       int overwrite)
+       double position, int load_mode, Track *first_track, RecordLabels *labels,
+       int edit_labels, int edit_plugins, int edit_autos, int overwrite)
 {
+       if( load_mode == LOADMODE_RESOURCESONLY )
+               load_mode = LOADMODE_ASSETSONLY;
 const int debug = 0;
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
-       if(position < 0) position = edl->local_session->get_selectionstart();
+if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
+       if( position < 0 ) position = edl->local_session->get_selectionstart();
 
        ArrayList<EDL*> new_edls;
-       for(int i = 0; i < new_assets->total; i++)
-       {
+       for( int i=0; i<new_assets->total; ++i ) {
                Indexable *indexable = new_assets->get(i);
-               if(indexable->is_asset)
-               {
+               if( indexable->is_asset ) {
                        remove_asset_from_caches((Asset*)indexable);
                }
                EDL *new_edl = new EDL;
@@ -1411,72 +1209,55 @@ if(debug) printf("MWindow::load_assets %d\n", __LINE__);
                new_edl->copy_session(edl);
                new_edls.append(new_edl);
 
-
-               if(indexable->is_asset)
-               {
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
-if(debug) ((Asset*)indexable)->dump();
-                       asset_to_edl(new_edl, (Asset*)indexable);
+               if( !indexable->is_asset ) {
+                       EDL *nested_edl = (EDL*)indexable;
+                       new_edl->to_nested(nested_edl);
+                       new_edl->local_session->set_clip_path(nested_edl);
+               }
+               else {
+                       Asset *asset = (Asset*)indexable;
+                       asset_to_edl(new_edl, asset);
                }
-               else
-                       edl_to_nested(new_edl, (EDL*)indexable);
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
-
 
-               if(labels)
-               {
-                       for(RecordLabel *label = labels->first; label; label = label->next)
-                       {
+               if( labels ) {
+                       for( RecordLabel *label=labels->first; label; label=label->next ) {
                                new_edl->labels->toggle_label(label->position, label->position);
                        }
                }
        }
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
-
-       paste_edls(&new_edls,
-               load_mode,
-               first_track,
-               position,
-               edit_labels,
-               edit_plugins,
-               edit_autos,
-               overwrite);
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
+if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
 
+       paste_edls(&new_edls, load_mode, first_track, position,
+               edit_labels, edit_plugins, edit_autos, overwrite);
+if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
 
        save_backup();
-       for(int i = 0; i < new_edls.size(); i++)
+       for( int i=0; i<new_edls.size(); ++i )
                new_edls.get(i)->Garbage::remove_user();
 
-if(debug) printf("MWindow::load_assets %d\n", __LINE__);
+if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
 }
 
 int MWindow::paste_automation()
 {
-       int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
+       int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
 
-       if(len)
-       {
+       if( len ) {
                undo->update_undo_before();
-               char *string = new char[len + 1];
-               gui->get_clipboard()->from_clipboard(string,
-                       len,
-                       BC_PRIMARY_SELECTION);
+               char *string = new char[len];
+               gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
                FileXML file;
                file.read_from_string(string);
 
-               edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
-                       edl->local_session->get_selectionend());
-               edl->tracks->paste_automation(edl->local_session->get_selectionstart(),
-                       &file,
-                       0,
-                       1,
+               double start = edl->local_session->get_selectionstart();
+               double end = edl->local_session->get_selectionend();
+               edl->tracks->clear_automation(start, end);
+               edl->tracks->paste_automation(start, &file, 0, 1,
                        edl->session->typeless_keyframes);
                save_backup();
                undo->update_undo_after(_("paste keyframes"), LOAD_AUTOMATION);
                delete [] string;
 
-
                restart_brender();
                update_plugin_guis();
                gui->draw_overlays(1);
@@ -1490,26 +1271,20 @@ int MWindow::paste_automation()
 
 int MWindow::paste_default_keyframe()
 {
-       int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION);
+       int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
 
-       if(len)
-       {
+       if( len ) {
                undo->update_undo_before();
-               char *string = new char[len + 1];
-               gui->get_clipboard()->from_clipboard(string,
-                       len,
-                       BC_PRIMARY_SELECTION);
+               char *string = new char[len];
+               gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
                FileXML file;
                file.read_from_string(string);
-               edl->tracks->paste_automation(edl->local_session->get_selectionstart(),
-                       &file,
-                       1,
-                       0,
+               double start = edl->local_session->get_selectionstart();
+               edl->tracks->paste_automation(start, &file, 1, 0,
                        edl->session->typeless_keyframes);
 //             edl->tracks->paste_default_keyframe(&file);
                undo->update_undo_after(_("paste default keyframe"), LOAD_AUTOMATION);
 
-
                restart_brender();
                update_plugin_guis();
                gui->draw_overlays(1);
@@ -1525,13 +1300,9 @@ int MWindow::paste_default_keyframe()
 
 
 // Insert edls with project deletion and index file generation.
-int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
-       int load_mode,
-       Track *first_track,
-       double current_position,
-       int edit_labels,
-       int edit_plugins,
-       int edit_autos,
+int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
+       Track *first_track, double current_position,
+       int edit_labels, int edit_plugins, int edit_autos,
        int overwrite)
 {
 
@@ -1539,41 +1310,29 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
        int need_new_tracks = 0;
 
 //PRINT_TRACE
-       if(!new_edls->total) return 0;
+       if( !new_edls->total ) return 0;
 
 //PRINT_TRACE
-//     double original_length = edl->tracks->total_playable_length();
+//     double original_length = edl->tracks->total_length();
 //     double original_preview_end = edl->local_session->preview_end;
 //PRINT_TRACE
 
 // Delete current project
-       if(load_mode == LOADMODE_REPLACE ||
-               load_mode == LOADMODE_REPLACE_CONCATENATE)
-       {
+       if( load_mode == LOADMODE_REPLACE ||
+           load_mode == LOADMODE_REPLACE_CONCATENATE ) {
                reset_caches();
-
                edl->save_defaults(defaults);
-
                hide_plugins();
-
                edl->Garbage::remove_user();
-
                edl = new EDL;
-
                edl->create_objects();
-
                edl->copy_session(new_edls->values[0]);
-
+               edl->copy_mixers(new_edls->values[0]);
                gui->mainmenu->update_toggles(0);
-
-
                gui->unlock_window();
-
                gwindow->gui->update_toggles(1);
-
                gui->lock_window("MWindow::paste_edls");
 
-
 // Insert labels for certain modes constitutively
                edit_labels = 1;
                edit_plugins = 1;
@@ -1587,68 +1346,54 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
 //PRINT_TRACE
 
 // Create new tracks in master EDL
-       if(load_mode == LOADMODE_REPLACE ||
-               load_mode == LOADMODE_REPLACE_CONCATENATE ||
-               load_mode == LOADMODE_NEW_TRACKS)
-       {
+       if( load_mode == LOADMODE_REPLACE ||
+           load_mode == LOADMODE_REPLACE_CONCATENATE ||
+           load_mode == LOADMODE_NEW_TRACKS ) {
 
                need_new_tracks = 1;
-               for(int i = 0; i < new_edls->total; i++)
-               {
+               for( int i=0; i<new_edls->total; ++i ) {
                        EDL *new_edl = new_edls->values[i];
-                       for(Track *current = new_edl->tracks->first;
-                               current;
-                               current = NEXT)
-                       {
-                               if(current->data_type == TRACK_VIDEO)
-                               {
+                       for( Track *current=new_edl->tracks->first; current; current=NEXT ) {
+                               switch( current->data_type ) {
+                               case TRACK_VIDEO:
                                        edl->tracks->add_video_track(0, 0);
-                                       if(current->draw) edl->tracks->last->draw = 1;
-                                       destination_tracks.append(edl->tracks->last);
-                               }
-                               else
-                               if(current->data_type == TRACK_AUDIO)
-                               {
+                                       if( current->draw ) edl->tracks->last->draw = 1;
+                                       break;
+                               case TRACK_AUDIO:
                                        edl->tracks->add_audio_track(0, 0);
-                                       destination_tracks.append(edl->tracks->last);
-                               }
-                               else
-                               if(current->data_type == TRACK_SUBTITLE)
-                               {
+                                       break;
+                               case TRACK_SUBTITLE:
                                        edl->tracks->add_subttl_track(0, 0);
-                                       destination_tracks.append(edl->tracks->last);
+                                       break;
+                               default:
+                                       continue;
                                }
-                               edl->session->highlighted_track = edl->tracks->total() - 1;
+                               destination_tracks.append(edl->tracks->last);
                        }
 
 // Base track count on first EDL only for concatenation
-                       if(load_mode == LOADMODE_REPLACE_CONCATENATE) break;
+                       if( load_mode == LOADMODE_REPLACE_CONCATENATE ) break;
                }
-
+               edl->session->highlighted_track = edl->tracks->total() - 1;
        }
        else
 // Recycle existing tracks of master EDL
-       if(load_mode == LOADMODE_CONCATENATE ||
-               load_mode == LOADMODE_PASTE ||
-               load_mode == LOADMODE_NESTED)
-       {
+       if( load_mode == LOADMODE_CONCATENATE ||
+           load_mode == LOADMODE_PASTE ||
+           load_mode == LOADMODE_NESTED ) {
 //PRINT_TRACE
 
 // The point of this is to shift forward labels after the selection so they can
 // then be shifted back to their original locations without recursively
 // shifting back every paste.
-               if((load_mode == LOADMODE_PASTE ||
-                       load_mode == LOADMODE_NESTED) &&
-                       edl->session->labels_follow_edits)
+               if( (load_mode == LOADMODE_PASTE || load_mode == LOADMODE_NESTED) &&
+                   edl->session->labels_follow_edits )
                        edl->labels->clear(edl->local_session->get_selectionstart(),
-                                               edl->local_session->get_selectionend(),
-                                               1);
+                                          edl->local_session->get_selectionend(), 1);
 
                Track *current = first_track ? first_track : edl->tracks->first;
-               for( ; current; current = NEXT)
-               {
-                       if(current->record)
-                       {
+               for( ; current; current=NEXT ) {
+                       if( current->record ) {
                                destination_tracks.append(current);
                        }
                }
@@ -1656,20 +1401,11 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
 
        }
 //PRINT_TRACE
-
-
-
-
        int destination_track = 0;
        double *paste_position = new double[destination_tracks.total];
 
-
-
-
-
 // Iterate through the edls
-       for(int i = 0; i < new_edls->total; i++)
-       {
+       for( int i=0; i<new_edls->total; ++i ) {
 
                EDL *new_edl = new_edls->values[i];
                double edl_length = new_edl->local_session->clipboard_length ?
@@ -1679,9 +1415,6 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
 // new_edl->local_session->clipboard_length,
 // new_edl->tracks->total_length());
 // new_edl->dump();
-
-
-
 //PRINT_TRACE
 
 // Convert EDL to master rates
@@ -1692,71 +1425,54 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
                        edl->session->frame_rate,
                        TRACK_VIDEO);
 //PRINT_TRACE
-
-
-
-
 // Add assets and prepare index files
-               for(Asset *new_asset = new_edl->assets->first;
-                       new_asset;
-                       new_asset = new_asset->next)
-               {
+               for( Asset *new_asset=new_edl->assets->first;
+                    new_asset; new_asset=new_asset->next ) {
                        mainindexes->add_next_asset(0, new_asset);
                }
 // Capture index file status from mainindex test
                edl->update_assets(new_edl);
 //PRINT_TRACE
-
-
-
 // Get starting point of insertion.  Need this to paste labels.
-               switch(load_mode)
-               {
-                       case LOADMODE_REPLACE:
-                       case LOADMODE_NEW_TRACKS:
-                               current_position = 0;
-                               break;
-
-                       case LOADMODE_CONCATENATE:
-                       case LOADMODE_REPLACE_CONCATENATE:
-                               destination_track = 0;
-                               if(destination_tracks.total)
-                                       current_position = destination_tracks.values[0]->get_length();
-                               else
-                                       current_position = 0;
-                               break;
-
-                       case LOADMODE_PASTE:
-                       case LOADMODE_NESTED:
-                               destination_track = 0;
-                               if(i == 0)
-                               {
-                                       for(int j = 0; j < destination_tracks.total; j++)
-                                       {
-                                               paste_position[j] = (current_position >= 0) ?
-                                                       current_position :
-                                                       edl->local_session->get_selectionstart();
-                                       }
+               switch( load_mode ) {
+               case LOADMODE_REPLACE:
+               case LOADMODE_NEW_TRACKS:
+                       current_position = 0;
+                       break;
+
+               case LOADMODE_CONCATENATE:
+               case LOADMODE_REPLACE_CONCATENATE:
+                       destination_track = 0;
+                       if( destination_tracks.total )
+                               current_position = destination_tracks.values[0]->get_length();
+                       else
+                               current_position = 0;
+                       break;
+
+               case LOADMODE_PASTE:
+               case LOADMODE_NESTED:
+                       destination_track = 0;
+                       if( i == 0 ) {
+                               for( int j=0; j<destination_tracks.total; ++j ) {
+                                       paste_position[j] = (current_position >= 0) ?
+                                               current_position :
+                                               edl->local_session->get_selectionstart();
                                }
-                               break;
+                       }
+                       break;
 
-                       case LOADMODE_RESOURCESONLY:
-                               edl->add_clip(new_edl);
-                               break;
+               case LOADMODE_RESOURCESONLY:
+                       edl->add_clip(new_edl);
+                       break;
                }
-
-
-
 //PRINT_TRACE
-
-
 // Insert edl
-               if(load_mode != LOADMODE_RESOURCESONLY)
-               {
+               if( load_mode != LOADMODE_RESOURCESONLY &&
+                   load_mode != LOADMODE_ASSETSONLY ) {
 // Insert labels
 //printf("MWindow::paste_edls %f %f\n", current_position, edl_length);
-                       if(load_mode == LOADMODE_PASTE ||
-                               load_mode == LOADMODE_NESTED)
+                       if( load_mode == LOADMODE_PASTE ||
+                           load_mode == LOADMODE_NESTED )
                                edl->labels->insert_labels(new_edl->labels,
                                        destination_tracks.total ? paste_position[0] : 0.0,
                                        edl_length,
@@ -1768,24 +1484,20 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
                                        edit_labels);
 //PRINT_TRACE
 
-                       for(Track *new_track = new_edl->tracks->first;
-                               new_track;
-                               new_track = new_track->next)
-                       {
+                       for( Track *new_track=new_edl->tracks->first;
+                            new_track; new_track=new_track->next ) {
 // Get destination track of same type as new_track
-                               for(int k = 0;
-                                       k < destination_tracks.total &&
-                                       destination_tracks.values[destination_track]->data_type != new_track->data_type;
-                                       k++, destination_track++)
-                               {
-                                       if(destination_track >= destination_tracks.total - 1)
+                               for( int k = 0;
+                                    k < destination_tracks.total &&
+                                    destination_tracks.values[destination_track]->data_type != new_track->data_type;
+                                    ++k, ++destination_track ) {
+                                       if( destination_track >= destination_tracks.total - 1 )
                                                destination_track = 0;
                                }
 
 // Insert data into destination track
-                               if(destination_track < destination_tracks.total &&
-                                       destination_tracks.values[destination_track]->data_type == new_track->data_type)
-                               {
+                               if( destination_track < destination_tracks.total &&
+                                   destination_tracks.values[destination_track]->data_type == new_track->data_type ) {
                                        Track *track = destination_tracks.values[destination_track];
 
 // Replace default keyframes if first EDL and new tracks were created.
@@ -1797,49 +1509,41 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
 
 //printf("MWindow::paste_edls 1 %d\n", replace_default);
 // Insert new track at current position
-                                       switch(load_mode)
-                                       {
-                                               case LOADMODE_REPLACE_CONCATENATE:
-                                               case LOADMODE_CONCATENATE:
-                                                       current_position = track->get_length();
-                                                       break;
-
-                                               case LOADMODE_PASTE:
-                                               case LOADMODE_NESTED:
-                                                       current_position = paste_position[destination_track];
-                                                       paste_position[destination_track] += new_track->get_length();
-                                                       break;
+                                       switch( load_mode ) {
+                                       case LOADMODE_REPLACE_CONCATENATE:
+                                       case LOADMODE_CONCATENATE:
+                                               current_position = track->get_length();
+                                               break;
+
+                                       case LOADMODE_PASTE:
+                                       case LOADMODE_NESTED:
+                                               current_position = paste_position[destination_track];
+                                               paste_position[destination_track] += new_track->get_length();
+                                               break;
                                        }
-                                       if (overwrite)
+                                       if( overwrite ) {
                                                track->clear(current_position,
-                                                               current_position + new_track->get_length(),
-                                                               1, // edit edits
-                                                               edit_labels,
-                                                               edit_plugins,
-                                                               edit_autos,
-                                                               1, // convert units
-                                                               0); // trim edits
-
-
+                                                       current_position + new_track->get_length(),
+                                                       1, // edit edits
+                                                       edit_labels, edit_plugins, edit_autos,
+                                                       1, // convert units
+                                                       0); // trim edits
+                                       }
 //PRINT_TRACE
-                                       track->insert_track(new_track,
-                                               current_position,
-                                               replace_default,
-                                               edit_plugins,
-                                               edit_autos,
-                                               edl_length);
+                                       track->insert_track(new_track, current_position, replace_default,
+                                               edit_plugins, edit_autos, edl_length);
 //PRINT_TRACE
                                }
 
 // Get next destination track
                                destination_track++;
-                               if(destination_track >= destination_tracks.total)
+                               if( destination_track >= destination_tracks.total )
                                        destination_track = 0;
                        }
                }
 
-               if(load_mode == LOADMODE_PASTE ||
-                       load_mode == LOADMODE_NESTED)
+               if( load_mode == LOADMODE_PASTE ||
+                   load_mode == LOADMODE_NESTED )
                        current_position += edl_length;
        }
 
@@ -1848,25 +1552,24 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
 // strange issue, for index not being shown
 // Assume any paste operation from the same EDL won't contain any clips.
 // If it did it would duplicate every clip here.
-       for(int i = 0; i < new_edls->total; i++)
-       {
-               EDL *new_edl = new_edls->values[i];
+       for( int i=0; i<new_edls->total; ++i ) {
+               EDL *new_edl = new_edls->get(i);
 
-               for(int j = 0; j < new_edl->clips.total; j++)
-               {
-                       edl->add_clip(new_edl->clips.values[j]);
+               for( int j=0; j<new_edl->clips.size(); ++j ) {
+                       edl->add_clip(new_edl->clips[j]);
+               }
+               for( int j=0; j<new_edl->nested_edls.size(); ++j ) {
+                       edl->nested_edls.get_copy(new_edl->nested_edls[j]);
                }
 
-               if(new_edl->total_vwindow_edls())
-               {
-//                     if(edl->vwindow_edl)
+               if( new_edl->total_vwindow_edls() ) {
+//                     if( edl->vwindow_edl )
 //                             edl->vwindow_edl->Garbage::remove_user();
 //                     edl->vwindow_edl = new EDL(edl);
 //                     edl->vwindow_edl->create_objects();
 //                     edl->vwindow_edl->copy_all(new_edl->vwindow_edl);
 
-                       for(int j = 0; j < new_edl->total_vwindow_edls(); j++)
-                       {
+                       for( int j=0; j<new_edl->total_vwindow_edls(); ++j ) {
                                EDL *vwindow_edl = new EDL(edl);
                                vwindow_edl->create_objects();
                                vwindow_edl->copy_all(new_edl->get_vwindow_edl(j));
@@ -1875,27 +1578,21 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls,
                }
        }
 
-
-       if(paste_position) delete [] paste_position;
-
+       if( paste_position ) delete [] paste_position;
 
 // This is already done in load_filenames and everything else that uses paste_edls
 //     update_project(load_mode);
 
 // Fix preview range
-//     if(EQUIV(original_length, original_preview_end))
+//     if( EQUIV(original_length, original_preview_end) )
 //     {
-//             edl->local_session->preview_end = edl->tracks->total_playable_length();
+//             edl->local_session->preview_end = edl->tracks->total_length();
 //     }
 
-
 // Start examining next batch of index files
        mainindexes->start_build();
 
-
 // Don't save a backup after loading since the loaded file is on disk already.
-
-
 //PRINT_TRACE
        return 0;
 }
@@ -1905,8 +1602,7 @@ void MWindow::paste_silence()
        double start = edl->local_session->get_selectionstart();
        double end = edl->local_session->get_selectionend();
        undo->update_undo_before();
-       edl->paste_silence(start,
-               end,
+       edl->paste_silence(start, end,
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
@@ -1918,10 +1614,7 @@ void MWindow::paste_silence()
        restart_brender();
        gui->update(1, 2, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                       CHANGE_EDL,
-                                                       edl,
-                                                       1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 void MWindow::detach_transition(Transition *transition)
@@ -1933,14 +1626,8 @@ void MWindow::detach_transition(Transition *transition)
        save_backup();
        undo->update_undo_after(_("detach transition"), LOAD_ALL);
 
-       if(is_video) restart_brender();
-       gui->update(0,
-               1,
-               0,
-               0,
-               0,
-               0,
-               0);
+       if( is_video ) restart_brender();
+       gui->update(0, 1, 0, 0, 0, 0, 0);
        sync_parameters(CHANGE_EDL);
 }
 
@@ -1967,7 +1654,7 @@ void MWindow::paste_transition()
        PluginServer *server = session->drag_pluginservers->values[0];
 
        undo->update_undo_before();
-       if(server->audio)
+       if( server->audio )
                strcpy(edl->session->default_atransition, server->title);
        else
                strcpy(edl->session->default_vtransition, server->title);
@@ -1976,7 +1663,7 @@ void MWindow::paste_transition()
        save_backup();
        undo->update_undo_after(_("transition"), LOAD_EDITS);
 
-       if(server->video) restart_brender();
+       if( server->video ) restart_brender();
        sync_parameters(CHANGE_ALL);
 }
 
@@ -2013,8 +1700,7 @@ void MWindow::paste_audio_transition()
 {
        PluginServer *server = scan_plugindb(edl->session->default_atransition,
                TRACK_AUDIO);
-       if(!server)
-       {
+       if( !server ) {
                char string[BCTEXTLEN];
                sprintf(string, _("No default transition %s found."), edl->session->default_atransition);
                gui->show_message(string);
@@ -2034,8 +1720,7 @@ void MWindow::paste_video_transition()
 {
        PluginServer *server = scan_plugindb(edl->session->default_vtransition,
                TRACK_VIDEO);
-       if(!server)
-       {
+       if( !server ) {
                char string[BCTEXTLEN];
                sprintf(string, _("No default transition %s found."), edl->session->default_vtransition);
                gui->show_message(string);
@@ -2172,71 +1857,48 @@ void MWindow::set_transition_length(double length)
 
 void MWindow::redo_entry(BC_WindowBase *calling_window_gui)
 {
-
        calling_window_gui->unlock_window();
-
-       cwindow->playback_engine->que->send_command(STOP,
-               CHANGE_NONE,
-               0,
-               0);
-       cwindow->playback_engine->interrupt_playback(0);
-
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       vwindows.get(i)->playback_engine->que->send_command(STOP,
-                               CHANGE_NONE,
-                               0,
-                               0);
-                       vwindows.get(i)->playback_engine->interrupt_playback(0);
-               }
-       }
-
-       cwindow->gui->lock_window("MWindow::redo_entry");
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       if (calling_window_gui != vwindows.get(i)->gui)
-                       {
+       stop_playback(0);
+       if( undo->redo_load_flags() & LOAD_SESSION )
+               close_mixers();
+
+       cwindow->gui->lock_window("MWindow::redo_entry 1");
+       for( int i=0; i<vwindows.size(); ++i ) {
+               if( vwindows.get(i)->is_running() ) {
+                       if( calling_window_gui != vwindows.get(i)->gui ) {
                                vwindows.get(i)->gui->lock_window("MWindow::redo_entry 2");
                        }
                }
        }
-       gui->lock_window();
+       gui->lock_window("MWindow::redo_entry 3");
 
        undo->redo();
 
        save_backup();
+       restart_brender();
        update_plugin_states();
        update_plugin_guis();
-       restart_brender();
+
        gui->update(1, 2, 1, 1, 1, 1, 1);
+       gui->unlock_window();
        cwindow->update(1, 1, 1, 1, 1);
+       cwindow->gui->unlock_window();
 
-       if (calling_window_gui != cwindow->gui)
-               cwindow->gui->unlock_window();
-       if (calling_window_gui != gui)
-               gui->unlock_window();
-
-
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       if (calling_window_gui != vwindows.get(i)->gui)
-                       {
+       for( int i=0; i < vwindows.size(); ++i ) {
+               if( vwindows.get(i)->is_running() ) {
+                       if( calling_window_gui != vwindows.get(i)->gui ) {
                                vwindows.get(i)->gui->unlock_window();
                        }
                }
        }
 
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                          CHANGE_ALL,
-                          edl,
-                          1);
+       if( calling_window_gui != gui )
+               gui->unlock_window();
+
+       awindow->gui->async_update_assets();
 
+       cwindow->refresh_frame(CHANGE_ALL);
+       calling_window_gui->lock_window("MWindow::redo_entry 4");
 }
 
 
@@ -2264,23 +1926,19 @@ void MWindow::set_inpoint(int is_mwindow)
        save_backup();
        undo->update_undo_after(_("in point"), LOAD_TIMEBAR);
 
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->lock_window("MWindow::set_inpoint 1");
        }
        gui->update_timebar(1);
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->unlock_window();
        }
 
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->lock_window("MWindow::set_inpoint 2");
        }
        cwindow->gui->timebar->update(1);
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->unlock_window();
        }
 }
@@ -2292,63 +1950,69 @@ void MWindow::set_outpoint(int is_mwindow)
        save_backup();
        undo->update_undo_after(_("out point"), LOAD_TIMEBAR);
 
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->lock_window("MWindow::set_outpoint 1");
        }
        gui->update_timebar(1);
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->unlock_window();
        }
 
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->lock_window("MWindow::set_outpoint 2");
        }
        cwindow->gui->timebar->update(1);
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->unlock_window();
        }
 }
 
-void MWindow::splice(EDL *source)
+void MWindow::unset_inoutpoint(int is_mwindow)
 {
-       FileXML file;
-
        undo->update_undo_before();
-       source->copy(source->local_session->get_selectionstart(),
-               source->local_session->get_selectionend(),
-               1,
-               0,
-               0,
-               &file,
-               "",
-               1);
+       edl->unset_inoutpoint();
+       save_backup();
+       undo->update_undo_after(_("clear in/out"), LOAD_TIMEBAR);
 
+       if( !is_mwindow ) {
+               gui->lock_window("MWindow::unset_inoutpoint 1");
+       }
+       gui->update_timebar(1);
+       if( !is_mwindow ) {
+               gui->unlock_window();
+       }
+
+       if( is_mwindow ) {
+               cwindow->gui->lock_window("MWindow::unset_inoutpoint 2");
+       }
+       cwindow->gui->timebar->update(1);
+       if( is_mwindow ) {
+               cwindow->gui->unlock_window();
+       }
+}
 
+void MWindow::splice(EDL *source, int all)
+{
+       FileXML file;
 
+       undo->update_undo_before();
+       double source_start = all ? 0 :
+               source->local_session->get_selectionstart();
+       double source_end = all ? source->tracks->total_length() :
+               source->local_session->get_selectionend();
+       source->copy(source_start, source_end, 1, &file, "", 1);
 //file.dump();
        double start = edl->local_session->get_selectionstart();
        //double end = edl->local_session->get_selectionend();
-       double source_start = source->local_session->get_selectionstart();
-       double source_end = source->local_session->get_selectionend();
 
-       paste(start,
-               start,
-               &file,
+       paste(start, start, &file,
                edl->session->labels_follow_edits,
                edl->session->plugins_follow_edits,
                edl->session->autos_follow_edits);
 
 // Position at end of clip
-       edl->local_session->set_selectionstart(start +
-               source_end -
-               source_start);
-       edl->local_session->set_selectionend(start +
-               source_end -
-               source_start);
+       edl->local_session->set_selectionstart(start + source_end - source_start);
+       edl->local_session->set_selectionend(start + source_end - source_start);
 
        save_backup();
        undo->update_undo_after(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
@@ -2358,55 +2022,90 @@ void MWindow::splice(EDL *source)
        sync_parameters(CHANGE_EDL);
 }
 
-void MWindow::to_clip()
+void MWindow::save_clip(EDL *new_edl, const char *txt)
+{
+       new_edl->local_session->set_selectionstart(0);
+       new_edl->local_session->set_selectionend(0);
+       sprintf(new_edl->local_session->clip_title, _("Clip %d"),
+               session->clip_number++);
+       char duration[BCTEXTLEN];
+       Units::totext(duration, new_edl->tracks->total_length(),
+               new_edl->session->time_format,
+               new_edl->session->sample_rate,
+               new_edl->session->frame_rate,
+               new_edl->session->frames_per_foot);
+
+       Track *track = new_edl->tracks->first;
+       const char *path = edl->path;
+       for( ; (!path || !*path) && track; track=track->next ) {
+               if( !track->record ) continue;
+               Edit *edit = track->edits->first;
+               if( !edit ) continue;
+               Indexable *indexable = edit->get_source();
+               if( !indexable ) continue;
+               path = indexable->path;
+       }
+
+        time_t now;  time(&now);
+        struct tm dtm;   localtime_r(&now, &dtm);
+       char *cp = new_edl->local_session->clip_notes;
+       int n, sz = sizeof(new_edl->local_session->clip_notes)-1;
+       if( txt && *txt ) {
+               n = snprintf(cp, sz, "%s", txt);
+               cp += n;  sz -= n;
+       }
+       n = snprintf(cp, sz, 
+               "%02d/%02d/%02d %02d:%02d:%02d,  +%s\n",
+               dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday, 
+               dtm.tm_hour, dtm.tm_min, dtm.tm_sec, duration);
+       cp += n;  sz -= n;
+       if( path && *path ) {
+               FileSystem fs;
+               char title[BCTEXTLEN];
+               fs.extract_name(title, path);
+               n = snprintf(cp, sz, "%s", title);
+               cp += n;  sz -= n;
+       }
+       cp[n] = 0;
+       sprintf(new_edl->local_session->clip_icon,
+               "clip_%02d%02d%02d-%02d%02d%02d.png",
+               dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
+               dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
+       edl->update_assets(new_edl);
+       int cur_x, cur_y;
+       gui->get_abs_cursor(cur_x, cur_y, 0);
+       gui->unlock_window();
+
+       awindow->clip_edit->create_clip(new_edl, cur_x, cur_y);
+       new_edl->remove_user();
+
+       gui->lock_window("MWindow::save_clip");
+       save_backup();
+}
+
+void MWindow::to_clip(EDL *edl, const char *txt, int all)
 {
        FileXML file;
        double start, end;
 
        gui->lock_window("MWindow::to_clip 1");
-       start = edl->local_session->get_selectionstart();
-       end = edl->local_session->get_selectionend();
+       start = all ? 0 :
+               edl->local_session->get_selectionstart();
+       end = all ? edl->tracks->total_length() :
+               edl->local_session->get_selectionend();
 
-       if(EQUIV(end, start))
-       {
+       if( EQUIV(end, start) ) {
                start = 0;
                end = edl->tracks->total_length();
        }
 
 // Don't copy all since we don't want the clips twice.
-       edl->copy(start,
-               end,
-               0,
-               0,
-               0,
-               &file,
-               "",
-               1);
-
+       edl->copy(start, end, 0, &file, "", 1);
 
        EDL *new_edl = new EDL(edl);
        new_edl->create_objects();
        new_edl->load_xml(&file, LOAD_ALL);
-       sprintf(new_edl->local_session->clip_title, _("Clip %d"), session->clip_number++);
-       char string[BCTEXTLEN];
-       Units::totext(string,
-                       end - start,
-                       edl->session->time_format,
-                       edl->session->sample_rate,
-                       edl->session->frame_rate,
-                       edl->session->frames_per_foot);
-
-       sprintf(new_edl->local_session->clip_notes, _("%s\nCreated from main window"), string);
-
-       new_edl->local_session->set_selectionstart(0);
-       new_edl->local_session->set_selectionend(0);
-
-       gui->unlock_window();
-
-       awindow->clip_edit->create_clip(new_edl);
-
-       gui->lock_window("MWindow::to_clip 2");
-       save_backup();
+       save_clip(new_edl, txt);
        gui->unlock_window();
 }
 
@@ -2415,13 +2114,11 @@ int MWindow::toggle_label(int is_mwindow)
        double position1, position2;
        undo->update_undo_before();
 
-       if(cwindow->playback_engine->is_playing_back)
-       {
+       if( cwindow->playback_engine->is_playing_back ) {
                position1 = position2 =
                        cwindow->playback_engine->get_tracking_position();
        }
-       else
-       {
+       else {
                position1 = edl->local_session->get_selectionstart(1);
                position2 = edl->local_session->get_selectionend(1);
        }
@@ -2434,28 +2131,26 @@ int MWindow::toggle_label(int is_mwindow)
        edl->labels->toggle_label(position1, position2);
        save_backup();
 
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->lock_window("MWindow::toggle_label 1");
        }
        gui->update_timebar(0);
        gui->activate_timeline();
        gui->flush();
-       if(!is_mwindow)
-       {
+       if( !is_mwindow ) {
                gui->unlock_window();
        }
 
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->lock_window("MWindow::toggle_label 2");
        }
        cwindow->gui->timebar->update(1);
-       if(is_mwindow)
-       {
+       if( is_mwindow ) {
                cwindow->gui->unlock_window();
        }
 
+       awindow->gui->async_update_assets();
+
        undo->update_undo_after(_("label"), LOAD_TIMEBAR);
        return 0;
 }
@@ -2476,45 +2171,23 @@ void MWindow::trim_selection()
        update_plugin_guis();
        gui->update(1, 2, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
+       awindow->gui->async_update_assets();
        restart_brender();
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                                                       CHANGE_EDL,
-                                                       edl,
-                                                       1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }
 
 
-
 void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
 {
        calling_window_gui->unlock_window();
-
-       cwindow->playback_engine->que->send_command(STOP,
-               CHANGE_NONE,
-               0,
-               0);
-       cwindow->playback_engine->interrupt_playback(0);
-
-//printf("MWindow::undo_entry %d %d\n", __LINE__, vwindows.size());
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       vwindows.get(i)->playback_engine->que->send_command(STOP,
-                               CHANGE_NONE,
-                               0,
-                               0);
-                       vwindows.get(i)->playback_engine->interrupt_playback(0);
-               }
-       }
+       stop_playback(0);
+       if( undo->undo_load_flags() & LOAD_SESSION )
+               close_mixers();
 
        cwindow->gui->lock_window("MWindow::undo_entry 1");
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       if (calling_window_gui != vwindows.get(i)->gui)
-                       {
+       for( int i=0; i<vwindows.size(); ++i ) {
+               if( vwindows.get(i)->is_running() ) {
+                       if( calling_window_gui != vwindows.get(i)->gui ) {
                                vwindows.get(i)->gui->lock_window("MWindow::undo_entry 4");
                        }
                }
@@ -2528,42 +2201,29 @@ void MWindow::undo_entry(BC_WindowBase *calling_window_gui)
        update_plugin_states();
        update_plugin_guis();
 
-
-
        gui->update(1, 2, 1, 1, 1, 1, 1);
-
        gui->unlock_window();
-
        cwindow->update(1, 1, 1, 1, 1);
-
        cwindow->gui->unlock_window();
 
-       for(int i = 0; i < vwindows.size(); i++)
-       {
-               if(vwindows.get(i)->is_running())
-               {
-                       if (calling_window_gui != vwindows.get(i)->gui)
-                       {
+       for( int i=0; i<vwindows.size(); ++i ) {
+               if( vwindows.get(i)->is_running() ) {
+                       if( calling_window_gui != vwindows.get(i)->gui ) {
                                vwindows.get(i)->gui->unlock_window();
                        }
                }
        }
 
-       if (calling_window_gui != gui)
+       if( calling_window_gui != gui )
                gui->unlock_window();
 
-
        awindow->gui->async_update_assets();
 
-       cwindow->playback_engine->que->send_command(CURRENT_FRAME,
-                          CHANGE_ALL,
-                          edl,
-                          1);
+       cwindow->refresh_frame(CHANGE_ALL);
        calling_window_gui->lock_window("MWindow::undo_entry 4");
 }
 
 
-
 void MWindow::new_folder(const char *new_folder)
 {
        undo->update_undo_before();
@@ -2585,7 +2245,6 @@ void MWindow::select_point(double position)
 // Que the CWindow
        cwindow->update(1, 0, 0, 0, 1);
 
-
        update_plugin_guis();
        gui->update_patchbay();
        gui->hide_cursor(0);
@@ -2615,67 +2274,144 @@ void MWindow::remap_audio(int pattern)
 {
        int current_channel = 0;
        int current_track = 0;
-       for(Track *current = edl->tracks->first; current; current = NEXT)
-       {
-               if(current->data_type == TRACK_AUDIO &&
-                       current->record)
-               {
+       for( Track *current=edl->tracks->first; current; current=NEXT ) {
+               if( current->data_type == TRACK_AUDIO &&
+                       current->record ) {
                        Autos *pan_autos = current->automation->autos[AUTOMATION_PAN];
                        PanAuto *pan_auto = (PanAuto*)pan_autos->get_auto_for_editing(-1);
 
-                       for(int i = 0; i < MAXCHANNELS; i++)
-                       {
+                       for( int i=0; i < MAXCHANNELS; ++i ) {
                                pan_auto->values[i] = 0.0;
                        }
 
-                       if(pattern == MWindow::AUDIO_1_TO_1)
-                       {
+                       if( pattern == MWindow::AUDIO_1_TO_1 ) {
                                pan_auto->values[current_channel] = 1.0;
                        }
                        else
-                       if(pattern == MWindow::AUDIO_5_1_TO_2)
-                       {
-                               switch(current_track)
-                               {
-                                       case 0:
-                                               pan_auto->values[0] = 0.5;
-                                               pan_auto->values[1] = 0.5;
-                                               break;
-                                       case 1:
-                                               pan_auto->values[0] = 1;
-                                               break;
-                                       case 2:
-                                               pan_auto->values[1] = 1;
-                                               break;
-                                       case 3:
-                                               pan_auto->values[0] = 1;
-                                               break;
-                                       case 4:
-                                               pan_auto->values[1] = 1;
-                                               break;
-                                       case 5:
-                                               pan_auto->values[0] = 0.5;
-                                               pan_auto->values[1] = 0.5;
-                                               break;
+                       if( pattern == MWindow::AUDIO_5_1_TO_2 ) {
+                               switch( current_track ) {
+                               case 0:
+                               case 4:
+                                       pan_auto->values[0] = 1;
+                                       break;
+                               case 1:
+                               case 5:
+                                       pan_auto->values[1] = 1;
+                                       break;
+                               case 2:
+                               case 3:
+                                       pan_auto->values[0] = 0.5;
+                                       pan_auto->values[1] = 0.5;
+                                       break;
                                }
                        }
 
                        BC_Pan::calculate_stick_position(edl->session->audio_channels,
-                               edl->session->achannel_positions,
-                               pan_auto->values,
-                               MAX_PAN,
-                               PAN_RADIUS,
-                               pan_auto->handle_x,
-                               pan_auto->handle_y);
+                               edl->session->achannel_positions, pan_auto->values,
+                               MAX_PAN, PAN_RADIUS, pan_auto->handle_x, pan_auto->handle_y);
 
                        current_channel++;
                        current_track++;
-                       if(current_channel >= edl->session->audio_channels)
+                       if( current_channel >= edl->session->audio_channels )
                                current_channel = 0;
                }
        }
 }
 
+void MWindow::set_proxy(int use_scaler, int new_scale, int auto_scale,
+               ArrayList<Indexable*> *orig_assets,
+               ArrayList<Indexable*> *proxy_assets)
+{
+       int orig_use_scaler = edl->session->proxy_use_scaler;
+       int orig_scale = edl->session->proxy_scale;
+// rescale to full size asset in read_frame
+       edl->session->proxy_use_scaler = use_scaler;
+       edl->session->proxy_scale = new_scale;
+       edl->session->proxy_auto_scale = auto_scale;
+
+       if( use_scaler ) {
+               for( int i=0; i<proxy_assets->size(); ++i ) {
+                       Asset *proxy_asset = (Asset *)proxy_assets->get(i);
+                       proxy_asset->width = orig_assets->get(i)->get_w();
+                       proxy_asset->height = orig_assets->get(i)->get_h();
+               }
+               new_scale = 1;
+       }
+
+       if( !orig_use_scaler && new_scale != orig_scale ) {
+// project size
+               float orig_w = (float)edl->session->output_w * orig_scale;
+               float orig_h = (float)edl->session->output_h * orig_scale;
+               edl->session->output_w = Units::round(orig_w / new_scale);
+               edl->session->output_h = Units::round(orig_h / new_scale);
+
+// track sizes
+               for( Track *track=edl->tracks->first; track; track=track->next ) {
+                       if( track->data_type != TRACK_VIDEO ) continue;
+                       orig_w = (float)track->track_w * orig_scale;
+                       orig_h = (float)track->track_h * orig_scale;
+                       track->track_w = Units::round(orig_w / new_scale);
+                       track->track_h = Units::round(orig_h / new_scale);
+                       ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->
+                               set_proxy(orig_scale, new_scale);
+                       ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_X])->
+                               set_proxy(orig_scale, new_scale);
+                       ((FloatAutos*)track->automation->autos[AUTOMATION_CAMERA_Y])->
+                               set_proxy(orig_scale, new_scale);
+                       ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_X])->
+                               set_proxy(orig_scale, new_scale);
+                       ((FloatAutos*)track->automation->autos[AUTOMATION_PROJECTOR_Y])->
+                               set_proxy(orig_scale, new_scale);
+               }
+       }
+
+// change original assets to proxy assets
+       int awindow_folder = use_scaler || new_scale != 1 ? AW_PROXY_FOLDER : AW_MEDIA_FOLDER;
+       for( int i=0,n=proxy_assets->size(); i<n; ++i ) {
+               Asset *proxy_asset = edl->assets->update((Asset *)proxy_assets->get(i));
+               proxy_asset->awindow_folder = awindow_folder;
+// replace track contents
+               for( Track *track=edl->tracks->first; track; track=track->next ) {
+                       if( track->data_type != TRACK_VIDEO ) continue;
+                       for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                               if( !edit->asset ) continue;
+                               if( !strcmp(edit->asset->path, orig_assets->get(i)->path) ) {
+                                       edit->asset = proxy_asset;
+                               }
+                       }
+               }
+       }
+}
+
+void MWindow::add_proxy(int use_scaler,
+               ArrayList<Indexable*> *orig_assets,
+               ArrayList<Indexable*> *proxy_assets)
+{
+       if( use_scaler ) {
+               for( int i=0,n=proxy_assets->size(); i<n; ++i ) {
+                       Asset *proxy_asset = (Asset *)proxy_assets->get(i);
+                       proxy_asset->width = orig_assets->get(i)->get_w();
+                       proxy_asset->height = orig_assets->get(i)->get_h();
+               }
+       }
+
+// change original assets to proxy assets
+       for( int i=0,n=proxy_assets->size(); i<n; ++i ) {
+               Asset *proxy_asset = edl->assets->update((Asset *)proxy_assets->get(i));
+               proxy_asset->awindow_folder = AW_PROXY_FOLDER;
+// replace track contents
+               for( Track *track=edl->tracks->first; track; track=track->next ) {
+                       if( track->data_type != TRACK_VIDEO ) continue;
+                       for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                               if( !edit->asset ) continue;
+                               if( !strcmp(edit->asset->path, orig_assets->get(i)->path) ) {
+                                       edit->asset = proxy_asset;
+                               }
+                       }
+               }
+       }
+}
+
 void MWindow::cut_commercials()
 {
        undo->update_undo_before();
@@ -2688,8 +2424,7 @@ void MWindow::cut_commercials()
        update_plugin_guis();
        gui->update(1, 2, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
-       cwindow->playback_engine->que->
-               send_command(CURRENT_FRAME, CHANGE_EDL, edl, 1);
+       cwindow->refresh_frame(CHANGE_EDL);
 }