repeat play, in/out <> shortcuts, append to proj wording, cleanup
[goodguy/history.git] / cinelerra-5.1 / cinelerra / mwindow.C
index 426421c3bcc2571de9badb2c74ec1e27a1d340f4..53b5a1937b5bfca4ff1b8bc3b07264e509f26771 100644 (file)
@@ -872,6 +872,20 @@ PluginServer* MWindow::scan_plugindb(char *title,
        return 0;
 }
 
+// repair session files with xlated plugin titles
+void MWindow::fix_plugin_title(char *title)
+{
+       for(int i = 0; i < plugindb->total; i++) {
+               PluginServer *server = plugindb->get(i);
+               if( !server->title ) continue;
+               const char *server_title = server->title;
+               if( !bstrcasecmp(title, _(server_title)) ) {
+                       strcpy(title, server_title);
+                       return;
+               }
+       }
+}
+
 int MWindow::plugin_exists(const char *plugin_path, ArrayList<PluginServer*> &plugins)
 {
        for( int i=0; i<plugins.size(); ++i )
@@ -904,6 +918,7 @@ void MWindow::init_preferences()
        BC_WindowBase::get_resources()->popupmenu_btnup = preferences->popupmenu_btnup;
        BC_WindowBase::get_resources()->textbox_focus_policy = preferences->textbox_focus_policy;
        BC_WindowBase::get_resources()->grab_input_focus = preferences->grab_input_focus;
+       YUV::yuv.yuv_set_colors(preferences->yuv_color_space, preferences->yuv_color_range);
 }
 
 void MWindow::clean_indexes()
@@ -1033,7 +1048,7 @@ void MWindow::init_theme()
                fprintf(stderr, _("MWindow::init_theme: prefered theme %s not found.\n"),
                         preferences->theme);
 
-       const char *default_theme = _(DEFAULT_THEME);
+       const char *default_theme = DEFAULT_THEME;
        if( !theme_plugin && strcasecmp(preferences->theme, default_theme) ) {
                fprintf(stderr, _("MWindow::init_theme: trying default theme %s\n"),
                        default_theme);
@@ -1202,7 +1217,7 @@ void MWindow::update_mixer_tracks()
 }
 
 void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking,
-               int use_inout, int update_refresh, int toggle_audio)
+               int use_inout, int update_refresh, int toggle_audio, int loop_play)
 {
        zwindows_lock->lock("MWindow::queue_mixers");
        for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
@@ -1234,14 +1249,14 @@ void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking,
                }
                zwindow->change_source(mixer_edl);
                zwindow->issue_command(command,
-                       wait_tracking, use_inout, update_refresh, toggle_audio);
+                       wait_tracking, use_inout, update_refresh, toggle_audio, loop_play);
        }
        zwindows_lock->unlock();
 }
 
 void MWindow::refresh_mixers()
 {
-       queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
+       queue_mixers(edl,CURRENT_FRAME,0,0,1,0,0);
 }
 
 void MWindow::stop_mixers()
@@ -1249,7 +1264,7 @@ void MWindow::stop_mixers()
        for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
                ZWindow *zwindow = zwindows[vidx];
                if( zwindow->idx < 0 ) continue;
-               zwindow->issue_command(STOP, 0, 0, 0, 0);
+               zwindow->issue_command(STOP, 0, 0, 0, 0, 0);
        }
 }
 
@@ -1272,6 +1287,61 @@ void MWindow::close_mixers()
        }
 }
 
+void MWindow::create_mixers()
+{
+       if( !session->drag_assets->size() ) return;
+       undo->update_undo_before();
+
+       select_zwindow(0);
+       ArrayList<ZWindow *>new_mixers;
+
+       for( int i=0; i<session->drag_assets->total; ++i ) {
+               Indexable *indexable = session->drag_assets->values[i];
+               ArrayList<Indexable*> new_assets;
+               new_assets.append(indexable);
+               Track *track = edl->tracks->last;
+               load_assets(&new_assets, -1, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
+               track = !track ? edl->tracks->first : track->next;
+               Mixer *mixer = 0;
+               ZWindow *zwindow = get_mixer(mixer);
+               while( track ) {
+                       track->play = track->record = 0;
+                       if( track->data_type == TRACK_VIDEO ) {
+                               sprintf(track->title, _("Mixer %d"), zwindow->idx);
+                       }
+                       mixer->mixer_ids.append(track->get_mixer_id());
+                       track = track->next;
+               }
+               char *path = indexable->path;
+               char *tp = strrchr(path, '/');
+               if( !tp ) tp = path; else ++tp;
+               zwindow->set_title(tp);
+               new_mixers.append(zwindow);
+       }
+
+       tile_mixers();
+       for( int i=0; i<new_mixers.size(); ++i )
+               new_mixers[i]->start();
+
+       refresh_mixers();
+       save_backup();
+       undo->update_undo_after(_("create mixers"), LOAD_ALL);
+       restart_brender();
+       gui->update(1, 2, 1, 1, 1, 1, 0);
+       sync_parameters(CHANGE_ALL);
+}
+
+void MWindow::open_mixers()
+{
+       for( int i=0; i<edl->mixers.size(); ++i ) {
+               Mixer *mixer = edl->mixers[i];
+               ZWindow *zwindow = get_mixer(mixer);
+               zwindow->set_title(mixer->title);
+               zwindow->start();
+       }
+        refresh_mixers();
+}
+
 int MWindow::select_zwindow(ZWindow *zwindow)
 {
        int ret = 0, n = zwindows.number_of(zwindow);
@@ -1350,7 +1420,6 @@ void MWindow::tile_mixers()
        }
 }
 
-
 void MWindow::init_cache()
 {
        audio_cache = new CICache(preferences);
@@ -1481,19 +1550,14 @@ void MWindow::restart_brender()
 //printf("MWindow::restart_brender 1\n");
        if( !brender_active || !preferences->use_brender ) return;
        if( !brender ) return;
-       int locked  = gui->get_window_lock();
-       if( locked ) gui->unlock_window();
        brender->restart(edl);
-       if( locked ) gui->lock_window("MWindow::restart_brender");
 }
 
 void MWindow::stop_brender()
 {
        if( !brender ) return;
-       int locked  = gui->get_window_lock();
-       if( locked ) gui->unlock_window();
+// cannot be holding mwindow->gui display lock
        brender->stop();
-       if( locked ) gui->lock_window("MWindow::stop_brender");
 }
 
 int MWindow::brender_available(int position)
@@ -1535,7 +1599,9 @@ void MWindow::set_brender_active(int v, int update)
        }
        else {
                edl->session->brender_start = edl->session->brender_end = 0;
+               gui->unlock_window();
                stop_brender();
+               gui->lock_window("MWindow::set_brender_active");
        }
        if( update ) {
                gui->update_timebar(0);
@@ -1657,6 +1723,11 @@ void MWindow::stop_playback(int wait)
        }
 }
 
+void MWindow::stop_transport()
+{
+       gui->stop_transport(gui->get_window_lock() ? "MWindow::stop_transport" : 0);
+}
+
 int MWindow::load_filenames(ArrayList<char*> *filenames,
        int load_mode,
        int update_filename)
@@ -1684,8 +1755,8 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 // Define new_edls and new_assets to load
        int result = 0, ftype = -1;
-       for(int i = 0; i < filenames->size(); i++)
-       {
+
+       for( int i=0; i<filenames->size(); ++i ) {
 // Get type of file
                File *new_file = new File;
                Asset *new_asset = new Asset(filenames->get(i));
@@ -1704,234 +1775,210 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
                result = 1;
-               switch(ftype)
-               {
+               switch( ftype ) {
 // Convert media file to EDL
-                       case FILE_OK:
+               case FILE_OK:
 // Warn about odd image dimensions
-                               if(new_asset->video_data &&
-                                       ((new_asset->width % 2) ||
-                                       (new_asset->height % 2)))
-                               {
-                                       char string[BCTEXTLEN];
-                                       sprintf(string, _("%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly."),
-                                               new_asset->path,
-                                               new_asset->width,
-                                               new_asset->height);
-                                       MainError::show_error(string);
-                               }
-
-                               if(new_asset->program >= 0 &&
-                                       edl->session->program_no != new_asset->program)
-                               {
-                                       char string[BCTEXTLEN];
-                                       sprintf(string, _("%s's index was built for program number %d\n"
-                                               "Playback preference is %d.\n  Using program %d."),
-                                               new_asset->path, new_asset->program,
-                                               edl->session->program_no, new_asset->program);
-                                       MainError::show_error(string);
-                               }
+                       if( new_asset->video_data &&
+                           ((new_asset->width % 2) || (new_asset->height % 2)) ) {
+                               char string[BCTEXTLEN];
+                               sprintf(string, _("%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly."),
+                                       new_asset->path, new_asset->width, new_asset->height);
+                               MainError::show_error(string);
+                       }
 
+                       if( new_asset->program >= 0 &&
+                           edl->session->program_no != new_asset->program ) {
+                               char string[BCTEXTLEN];
+                               sprintf(string, _("%s's index was built for program number %d\n"
+                                       "Playback preference is %d.\n  Using program %d."),
+                                       new_asset->path, new_asset->program,
+                                       edl->session->program_no, new_asset->program);
+                               MainError::show_error(string);
+                       }
 
-                               if(load_mode != LOADMODE_RESOURCESONLY)
-                               {
-                                       RecordLabels *labels = edl->session->label_cells ?
-                                               new RecordLabels(new_file) : 0;
-                                       asset_to_edl(new_edl, new_asset, labels);
-                                       new_edls.append(new_edl);
-                                       new_asset->Garbage::remove_user();
-                                       delete labels;
-                                       new_asset = 0;
-                               }
-                               else
-                               {
-                                       new_assets.append(new_asset);
-                                       new_asset = 0;
-                               }
+                       if( load_mode != LOADMODE_RESOURCESONLY ) {
+                               RecordLabels *labels = edl->session->label_cells ?
+                                       new RecordLabels(new_file) : 0;
+                               asset_to_edl(new_edl, new_asset, labels);
+                               new_edls.append(new_edl);
+                               new_edl->add_user();
+                               delete labels;
+                       }
+                       else {
+                               new_assets.append(new_asset);
+                               new_asset->add_user();
+                       }
 
 // Set filename to nothing for assets since save EDL would overwrite them.
-                               if(load_mode == LOADMODE_REPLACE ||
-                                       load_mode == LOADMODE_REPLACE_CONCATENATE)
-                               {
-                                       set_filename("");
+                       if( load_mode == LOADMODE_REPLACE ||
+                           load_mode == LOADMODE_REPLACE_CONCATENATE ) {
+                               set_filename("");
 // Reset timeline position
-                                       for(int i = 0; i < TOTAL_PANES; i++)
-                                       {
-                                               new_edl->local_session->view_start[i] = 0;
-                                               new_edl->local_session->track_start[i] = 0;
-                                       }
+                               for( int i=0; i<TOTAL_PANES; ++i ) {
+                                       new_edl->local_session->view_start[i] = 0;
+                                       new_edl->local_session->track_start[i] = 0;
                                }
+                       }
 
-                               result = 0;
-                               break;
+                       result = 0;
+                       break;
 
 // File not found
-                       case FILE_NOT_FOUND:
-                               sprintf(string, _("Failed to open %s"), new_asset->path);
-                               gui->show_message(string, theme->message_error);
-                               gui->update_default_message();
-                               break;
+               case FILE_NOT_FOUND:
+                       sprintf(string, _("Failed to open %s"), new_asset->path);
+                       gui->show_message(string, theme->message_error);
+                       gui->update_default_message();
+                       break;
 
 // Unknown format
-                       case FILE_UNRECOGNIZED_CODEC:
-                       {
+               case FILE_UNRECOGNIZED_CODEC: {
 // Test index file
-                               {       IndexFile indexfile(this, new_asset);
-                                       if( !(result = indexfile.open_index()) )
-                                               indexfile.close_index();
-                               }
+                       { IndexFile indexfile(this, new_asset);
+                       if( !(result = indexfile.open_index()) )
+                               indexfile.close_index(); }
 
 // Test existing EDLs
-                               for(int j = 0; result && j <= new_edls.total; j++) {
-                                       Asset *old_asset = j < new_edls.total ?
-                                               new_edls[j]->assets->get_asset(new_asset->path) :
-                                               edl->assets->get_asset(new_asset->path);
-                                       if( old_asset ) {
-                                               new_asset->copy_from(old_asset,1);
-                                               result = 0;
-                                       }
+                       for( int j=0; result && j<new_edls.total; ++j ) {
+                               Asset *old_asset = new_edls[j]->assets->get_asset(new_asset->path);
+                               if( old_asset ) {
+                                       new_asset->copy_from(old_asset,1);
+                                       result = 0;
                                }
+                       }
+                       if( result ) {
+                               Asset *old_asset = edl->assets->get_asset(new_asset->path);
+                               if( old_asset ) {
+                                       new_asset->copy_from(old_asset,1);
+                                       result = 0;
+                               }
+                       }
 
 // Prompt user
-                               if(result)
-                               {
-                                       char string[BCTEXTLEN];
-                                       FileSystem fs;
-                                       fs.extract_name(string, new_asset->path);
-
-                                       strcat(string, _("'s format couldn't be determined."));
-                                       new_asset->audio_data = 1;
-                                       new_asset->format = FILE_PCM;
-                                       new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
-                                       new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
-                                       new_asset->bits = defaults->get("AUDIO_BITS", 16);
-                                       new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
-                                       new_asset->signed_ = defaults->get("SIGNED_", 1);
-                                       new_asset->header = defaults->get("HEADER", 0);
-
-                                       FileFormat fwindow(this);
-                                       fwindow.create_objects(new_asset, string);
-                                       result = fwindow.run_window();
-
-
-                                       defaults->update("AUDIO_CHANNELS", new_asset->channels);
-                                       defaults->update("SAMPLE_RATE", new_asset->sample_rate);
-                                       defaults->update("AUDIO_BITS", new_asset->bits);
-                                       defaults->update("BYTE_ORDER", new_asset->byte_order);
-                                       defaults->update("SIGNED_", new_asset->signed_);
-                                       defaults->update("HEADER", new_asset->header);
-                                       save_defaults();
-                               }
+                       if( result ) {
+                               char string[BCTEXTLEN];
+                               FileSystem fs;
+                               fs.extract_name(string, new_asset->path);
+
+                               strcat(string, _("'s format couldn't be determined."));
+                               new_asset->audio_data = 1;
+                               new_asset->format = FILE_PCM;
+                               new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
+                               new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
+                               new_asset->bits = defaults->get("AUDIO_BITS", 16);
+                               new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
+                               new_asset->signed_ = defaults->get("SIGNED_", 1);
+                               new_asset->header = defaults->get("HEADER", 0);
+
+                               FileFormat fwindow(this);
+                               fwindow.create_objects(new_asset, string);
+                               result = fwindow.run_window();
+
+                               defaults->update("AUDIO_CHANNELS", new_asset->channels);
+                               defaults->update("SAMPLE_RATE", new_asset->sample_rate);
+                               defaults->update("AUDIO_BITS", new_asset->bits);
+                               defaults->update("BYTE_ORDER", new_asset->byte_order);
+                               defaults->update("SIGNED_", new_asset->signed_);
+                               defaults->update("HEADER", new_asset->header);
+                               save_defaults();
+                       }
 
 // Append to list
-                               if(!result)
-                               {
+                       if( !result ) {
 // Recalculate length
-                                       delete new_file;
-                                       new_file = new File;
-                                       result = new_file->open_file(preferences, new_asset, 1, 0);
+                               delete new_file;
+                               new_file = new File;
+                               result = new_file->open_file(preferences, new_asset, 1, 0);
 
-                                       if(load_mode != LOADMODE_RESOURCESONLY)
-                                       {
-                                               RecordLabels *labels = edl->session->label_cells ?
-                                                       new RecordLabels(new_file) : 0;
-                                               asset_to_edl(new_edl, new_asset, labels);
-                                               new_edls.append(new_edl);
-                                               new_asset->Garbage::remove_user();
-                                               delete labels;
-                                               new_asset = 0;
-                                       }
-                                       else
-                                       {
-                                               new_assets.append(new_asset);
-                                               new_asset = 0;
-                                       }
+                               if( load_mode != LOADMODE_RESOURCESONLY ) {
+                                       RecordLabels *labels = edl->session->label_cells ?
+                                               new RecordLabels(new_file) : 0;
+                                       asset_to_edl(new_edl, new_asset, labels);
+                                       new_edls.append(new_edl);
+                                       new_edl->add_user();
+                                       delete labels;
                                }
-                               else
-                               {
-                                       result = 1;
+                               else {
+                                       new_assets.append(new_asset);
+                                       new_asset->add_user();
                                }
-                               break;
                        }
+                       else {
+                               result = 1;
+                       }
+                       break; }
 
-                       case FILE_IS_XML:
-                       {
-                               FileXML xml_file;
+               case FILE_IS_XML: {
+                       FileXML xml_file;
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-                               xml_file.read_from_file(filenames->get(i));
+                       xml_file.read_from_file(filenames->get(i));
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-                               const char *cin_version = 0;
-                               while( !xml_file.read_tag() ) {
-                                       if( xml_file.tag.title_is("EDL") ) {
-                                               cin_version = xml_file.tag.get_property("VERSION");
-                                               break;
-                                       }
-                               }
-                               xml_file.rewind();
-                               if( !cin_version ) {
-                                       eprintf(_("XML file %s\n not from cinelerra."),filenames->get(i));
-                                       char string[BCTEXTLEN];
-                                       sprintf(string,_("Unknown %s"), filenames->get(i));
-                                       gui->show_message(string);
-                                       result = 1;
+                       const char *cin_version = 0;
+                       while( !xml_file.read_tag() ) {
+                               if( xml_file.tag.title_is("EDL") ) {
+                                       cin_version = xml_file.tag.get_property("VERSION");
                                        break;
                                }
-                               if( strcmp(cin_version, CINELERRA_VERSION) ) {
-                                       char string[BCTEXTLEN];
-                                       snprintf(string, sizeof(string),
-                                                _("Warning: XML from cinelerra version %s\n"
-                                               "Session data may be incompatible."), cin_version);
-                                       show_warning(&preferences->warn_version, string);
-                               }
-                               if(load_mode == LOADMODE_NESTED)
-                               {
+                       }
+                       xml_file.rewind();
+                       if( !cin_version ) {
+                               eprintf(_("XML file %s\n not from cinelerra."),filenames->get(i));
+                               char string[BCTEXTLEN];
+                               sprintf(string,_("Unknown %s"), filenames->get(i));
+                               gui->show_message(string);
+                               result = 1;
+                               break;
+                       }
+                       if( strcmp(cin_version, CINELERRA_VERSION) ) {
+                               char string[BCTEXTLEN];
+                               snprintf(string, sizeof(string),
+                                        _("Warning: XML from cinelerra version %s\n"
+                                       "Session data may be incompatible."), cin_version);
+                               show_warning(&preferences->warn_version, string);
+                       }
+                       if( load_mode == LOADMODE_NESTED ) {
 // Load temporary EDL for nesting.
-                                       EDL *nested_edl = new EDL;
-                                       nested_edl->create_objects();
-                                       nested_edl->set_path(filenames->get(i));
-                                       nested_edl->load_xml(&xml_file, LOAD_ALL);
+                               EDL *nested_edl = new EDL;
+                               nested_edl->create_objects();
+                               nested_edl->set_path(filenames->get(i));
+                               nested_edl->load_xml(&xml_file, LOAD_ALL);
 //printf("MWindow::load_filenames %p %s\n", nested_edl, nested_edl->project_path);
-                                       edl_to_nested(new_edl, nested_edl);
-                                       nested_edl->Garbage::remove_user();
-                               }
-                               else
-                               {
+                               edl_to_nested(new_edl, nested_edl);
+                               nested_edl->Garbage::remove_user();
+                       }
+                       else {
 // Load EDL for pasting
-                                       new_edl->load_xml(&xml_file, LOAD_ALL);
+                               new_edl->load_xml(&xml_file, LOAD_ALL);
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-                                       test_plugins(new_edl, filenames->get(i));
+                               test_plugins(new_edl, filenames->get(i));
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
-                                       if(load_mode == LOADMODE_REPLACE ||
-                                               load_mode == LOADMODE_REPLACE_CONCATENATE)
-                                       {
-                                               strcpy(session->filename, filenames->get(i));
-                                               strcpy(new_edl->local_session->clip_title,
-                                                       filenames->get(i));
-                                               if(update_filename)
-                                                       set_filename(new_edl->local_session->clip_title);
-                                       }
-                                       else
-                                       if( load_mode == LOADMODE_RESOURCESONLY ) {
-                                               strcpy(new_edl->local_session->clip_title,
-                                                       filenames->get(i));
-                                               struct stat st;
-                                               time_t t = !stat(filenames->get(i),&st) ?
-                                                       st.st_mtime : time(&t);
-                                               ctime_r(&t, new_edl->local_session->clip_notes);
-                                       }
+                               if( load_mode == LOADMODE_REPLACE ||
+                                   load_mode == LOADMODE_REPLACE_CONCATENATE ) {
+                                       strcpy(session->filename, filenames->get(i));
+                                       strcpy(new_edl->local_session->clip_title,
+                                               filenames->get(i));
+                                       if(update_filename)
+                                               set_filename(new_edl->local_session->clip_title);
+                               }
+                               else if( load_mode == LOADMODE_RESOURCESONLY ) {
+                                       strcpy(new_edl->local_session->clip_title,
+                                               filenames->get(i));
+                                       struct stat st;
+                                       time_t t = !stat(filenames->get(i),&st) ?
+                                               st.st_mtime : time(&t);
+                                       ctime_r(&t, new_edl->local_session->clip_notes);
                                }
-
-                               new_edls.append(new_edl);
-                               result = 0;
-                               break;
                        }
+
+                       new_edls.append(new_edl);
+                       new_edl->add_user();
+                       result = 0;
+                       break; }
                }
 
-// edls are in new_edls
-               if( result && new_edl ) new_edl->Garbage::remove_user();
-// assets are copied
-               if( new_asset ) new_asset->Garbage::remove_user();
+               new_edl->Garbage::remove_user();
+               new_asset->Garbage::remove_user();
 
 // Store for testing index
                new_files.append(new_file);
@@ -2058,7 +2105,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                edl->session->proxy_use_scaler = 0;
                edl->session->proxy_auto_scale = 0;
                edl->local_session->preview_start = 0;
-               edl->local_session->preview_end = edl->tracks->total_length();
+               edl->local_session->preview_end = 0;
                edl->local_session->loop_playback = 0;
                edl->local_session->set_selectionstart(0);
                edl->local_session->set_selectionend(0);
@@ -2168,74 +2215,37 @@ void MWindow::test_plugins(EDL *new_edl, char *path)
 {
        char string[BCTEXTLEN];
 
-// Do a check weather plugins exist
-       for(Track *track = new_edl->tracks->first; track; track = track->next)
-       {
-               for(int k = 0; k < track->plugin_set.total; k++)
-               {
+// Do a check whether plugins exist
+       for( Track *track=new_edl->tracks->first; track; track=track->next ) {
+               for( int k=0; k<track->plugin_set.total; ++k ) {
                        PluginSet *plugin_set = track->plugin_set[k];
-                       for(Plugin *plugin = (Plugin*)plugin_set->first;
-                               plugin;
-                               plugin = (Plugin*)plugin->next)
-                       {
-                               if(plugin->plugin_type == PLUGIN_STANDALONE)
-                               {
+                       for( Plugin *plugin = (Plugin*)plugin_set->first;
+                                       plugin; plugin = (Plugin*)plugin->next ) {
+                               if( plugin->plugin_type != PLUGIN_STANDALONE ) continue;
 // ok we need to find it in plugindb
-                                       int plugin_found = 0;
-
-                                       for(int j = 0; j < plugindb->size(); j++)
-                                       {
-                                               PluginServer *server = plugindb->get(j);
-                                               if(server->title &&
-                                                       !strcasecmp(server->title, plugin->title) &&
-                                                       ((track->data_type == TRACK_AUDIO && server->audio) ||
-                                                       (track->data_type == TRACK_VIDEO && server->video)) &&
-                                                       (!server->transition))
-                                                       plugin_found = 1;
-                                       }
-
-                                       if (!plugin_found)
-                                       {
-                                               sprintf(string,
+                               PluginServer *server =
+                                       scan_plugindb(plugin->title, track->data_type);
+                               if( !server || server->transition ) {
+                                       sprintf(string,
        _("The %s '%s' in file '%s' is not part of your installation of Cinelerra.\n"
          "The project won't be rendered as it was meant and Cinelerra might crash.\n"),
-                                                       "effect", plugin->title,
-                                                       path);
-                                               MainError::show_error(string);
-                                       }
+                                               "effect", _(plugin->title), path);
+                                       MainError::show_error(string);
                                }
                        }
                }
 
-               for(Edit *edit = (Edit*)track->edits->first;
-                       edit;
-                       edit = (Edit*)edit->next)
-               {
-                       if (edit->transition)
-                       {
+               for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
+                       if( !edit->transition ) continue;
 // ok we need to find transition in plugindb
-
-                               int transition_found = 0;
-                               for(int j = 0; j < plugindb->size(); j++)
-                               {
-                                       PluginServer *server = plugindb->get(j);
-                                       if(server->title &&
-                                               !strcasecmp(server->title, edit->transition->title) &&
-                                               ((track->data_type == TRACK_AUDIO && server->audio) ||
-                                               (track->data_type == TRACK_VIDEO && server->video)) &&
-                                               (server->transition))
-                                               transition_found = 1;
-                               }
-
-                               if (!transition_found)
-                               {
-                                       sprintf(string,
+                       PluginServer *server =
+                               scan_plugindb(edit->transition->title, track->data_type);
+                       if( !server || !server->transition ) {
+                               sprintf(string,
        _("The %s '%s' in file '%s' is not part of your installation of Cinelerra.\n"
          "The project won't be rendered as it was meant and Cinelerra might crash.\n"),
-                                               "transition", edit->transition->title,
-                                               path);
-                                       MainError::show_error(string);
-                               }
+                                       "transition", _(edit->transition->title), path);
+                               MainError::show_error(string);
                        }
                }
        }
@@ -3235,7 +3245,6 @@ void MWindow::update_project(int load_mode)
        const int debug = 0;
 
        if(debug) PRINT_TRACE
-       init_brender();
        edl->tracks->update_y_pixels(theme);
 
        if(debug) PRINT_TRACE
@@ -3249,6 +3258,7 @@ void MWindow::update_project(int load_mode)
        gui->update(1, 1, 1, 1, 1, 1, 1);
        if(debug) PRINT_TRACE
        gui->unlock_window();
+       init_brender();
 
        cwindow->gui->lock_window("MWindow::update_project 1");
        cwindow->update(0, 0, 1, 1, 1);
@@ -3275,6 +3285,10 @@ void MWindow::update_project(int load_mode)
                        if( !vwindow->is_running() ) continue;
                        vwindow->close_window();
                }
+               for( int i=0; i<edl->vwindow_edls.size(); ++i ) {
+                       VWindow *vwindow = get_viewer(1, -1);
+                       vwindow->change_source(i);
+               }
                if(debug) PRINT_TRACE
                select_zwindow(0);
                close_mixers();
@@ -3341,6 +3355,7 @@ void MWindow::rebuild_indices()
                                asset->reset_audio();
                        }
                        asset->reset_video();
+                       remove_asset_from_caches(asset);
 //                     File file; // re-probe the asset
 //                     file.open_file(preferences, asset, 1, 0);
                }
@@ -3978,29 +3993,9 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
                if( channels < 1 ) channels = 1;
                if( channels > 6 ) channels = 6;
                session->audio_tracks = session->audio_channels = channels;
-               switch( channels ) {
-               case 6:
-                       session->achannel_positions[0] = 90;
-                       session->achannel_positions[1] = 150;
-                       session->achannel_positions[2] = 30;
-                       session->achannel_positions[3] = 210;
-                       session->achannel_positions[4] = 330;
-                       session->achannel_positions[5] = 270;
-                       break;
-               case 2:
-                       session->achannel_positions[0] = 180;
-                       session->achannel_positions[1] = 0;
-                       break;
-               case 1:
-                       session->achannel_positions[1] = 90;
-                       break;
-               default: {
-                       if( !channels ) break;
-                       double t = 0, dt = 360./channels;
-                       for( int i=channels; --i>=0; t+=dt )
-                               session->achannel_positions[i] = int(t+0.5);
-                       break; }
-               }
+
+               int *achannel_positions = preferences->channel_positions[session->audio_channels-1];
+               memcpy(&session->achannel_positions, achannel_positions, sizeof(session->achannel_positions));
                remap_audio(MWindow::AUDIO_1_TO_1);
 
                if( delete_tracks ) {