X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindow.C;h=992e9f342823dff1d3cec31537a08a3269725982;hp=9bab2c61df5bee55bcb4c4c58f973d6939bbcb56;hb=d54e2016ca0bea24cd4371058d0f75aeebdb044f;hpb=ce9d2233f4653ae54ee7bdfa4a7313326a9d8240 diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 9bab2c61..992e9f34 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -38,6 +38,7 @@ #include "channeldb.h" #include "channelinfo.h" #include "clip.h" +#include "clipedls.h" #include "bccmodels.h" #include "commercials.h" #include "cplayback.h" @@ -80,7 +81,6 @@ #include "mutex.h" #include "mwindowgui.h" #include "mwindow.h" -#include "nestededls.h" #include "new.h" #include "panautos.h" #include "patchbay.h" @@ -210,7 +210,6 @@ MWindow::MWindow() strcpy(cin_lang,"en"); channeldb_buz = new ChannelDB; channeldb_v4l2jpeg = new ChannelDB; - //file_server = 0; plugin_guis = 0; dead_plugins = 0; keyframe_threads = 0; @@ -230,6 +229,8 @@ MWindow::MWindow() restart_status = 0; screens = 1; in_destructor = 0; + speed_edl = 0; + proxy_beep = 0; } @@ -244,6 +245,7 @@ MWindow::~MWindow() #ifdef HAVE_DVB gui->channel_info->stop(); #endif + delete proxy_beep; delete create_bd; create_bd = 0; delete create_dvd; create_dvd = 0; delete batch_render; batch_render = 0; @@ -251,7 +253,7 @@ MWindow::~MWindow() commit_commercial(); if( commercials && !commercials->remove_user() ) commercials = 0; close_mixers(); - + if( speed_edl ) { speed_edl->remove_user(); speed_edl = 0; } // Save defaults for open plugins plugin_gui_lock->lock("MWindow::~MWindow"); for(int i = 0; i < plugin_guis->size(); i++) { @@ -318,7 +320,6 @@ MWindow::~MWindow() delete gwindow; gwindow = 0; delete cwindow; cwindow = 0; delete gui; gui = 0; - //delete file_server; file_server = 0; // reusable delete mainindexes; mainindexes = 0; delete mainprogress; mainprogress = 0; delete audio_cache; audio_cache = 0; // delete the cache after the assets @@ -470,6 +471,7 @@ void MWindow::init_defaults(BC_Hash* &defaults, char *config_path) else create_defaults_path(path, CONFIG_FILE); + delete defaults; defaults = new BC_Hash(path); defaults->load(); } @@ -560,6 +562,9 @@ int MWindow::load_plugin_index(MWindow *mwindow, const char *index_path, const c case PLUGIN_TYPE_FFMPEG: { server = new_ffmpeg_server(mwindow, path); break; } + case PLUGIN_TYPE_LV2: { + server = new_lv2_server(mwindow, path); + break; } } if( !server ) continue; plugins.append(server); @@ -628,6 +633,7 @@ int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences) fprintf(fp, "%s\n", plugin_path); init_plugin_index(mwindow, preferences, fp, plugin_path); init_ffmpeg_index(mwindow, preferences, fp); + init_lv2_index(mwindow, preferences, fp); fclose(fp); return load_plugin_index(mwindow, index_path, plugin_path); } @@ -674,25 +680,6 @@ void MWindow::init_plugin_index(MWindow *mwindow, Preferences *preferences, scan_plugin_index(mwindow, preferences, fp, plugin_dir, ".", idx); } -int MWindow::init_ladspa_index(MWindow *mwindow, Preferences *preferences, - const char *index_path, const char *plugin_dir) -{ - char plugin_path[BCTEXTLEN], *path = FileSystem::basepath(plugin_dir); - strcpy(plugin_path, path); delete [] path; - printf("init ladspa index: %s\n", plugin_dir); - FILE *fp = fopen(index_path,"w"); - if( !fp ) { - fprintf(stderr,_("MWindow::init_ladspa_index: " - "can't create plugin index: %s\n"), index_path); - return 1; - } - fprintf(fp, "%d\n", PLUGIN_FILE_VERSION); - fprintf(fp, "%s\n", plugin_dir); - init_plugin_index(mwindow, preferences, fp, plugin_path); - fclose(fp); - return 0; -} - void MWindow::scan_plugin_index(MWindow *mwindow, Preferences *preferences, FILE *fp, const char *plug_dir, const char *plug_path, int &idx) { @@ -745,18 +732,17 @@ void MWindow::add_plugins(ArrayList &plugins) void MWindow::init_plugin_tips(ArrayList &plugins, const char *lang) { - const char *cfg_path = File::get_cindat_path(); - char msg_path[BCTEXTLEN]; int txt = 0; + const char *dat_path = File::get_cindat_path(); + char msg_path[BCTEXTLEN]; FILE *fp = 0; if( BC_Resources::language[0] ) { snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.%s", - cfg_path, lang); + dat_path, lang); fp = fopen(msg_path, "r"); } if( !fp ) { - txt = 1; snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt", - cfg_path); + dat_path); fp = fopen(msg_path, "r"); } if( !fp ) return; @@ -775,9 +761,8 @@ void MWindow::init_plugin_tips(ArrayList &plugins, const char *la if( done ) { if( tp > text && *--tp == '\n' ) *tp = 0; if( title[0] ) { - tp = !txt ? title : _(title); int idx = plugins.size(); - while( --idx>=0 && strcmp(plugins[idx]->title, tp) ); + while( --idx>=0 && strcmp(plugins[idx]->title, title) ); if( idx >= 0 ) { delete [] plugins[idx]->tip; plugins[idx]->tip = cstrdup(text); @@ -872,6 +857,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 &plugins) { for( int i=0; iload_defaults(defaults); + const char *lv2_path = getenv("LV2_PATH"); + if( lv2_path && strcmp(lv2_path, preferences->lv2_path) ) { + strncpy(preferences->lv2_path, lv2_path, sizeof(preferences->lv2_path)); + remove_plugin_index(); + } + else if( !lv2_path && preferences->lv2_path[0] ) { + File::setenv_path("LV2_PATH",preferences->lv2_path, 0); + } session = new MainSession(this); session->load_defaults(defaults); // set x11_host, screens, window_config @@ -1034,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); @@ -1143,7 +1157,6 @@ void MWindow::del_mixer(ZWindow *zwindow) { zwindows_lock->lock("MWindow::del_mixer 0"); edl->mixers.del_mixer(zwindow->idx); - zwindow->idx = -1; if( session->selected_zwindow >= 0 ) { int i = zwindows.number_of(zwindow); if( i >= 0 && i < session->selected_zwindow ) @@ -1203,7 +1216,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; vidxchange_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() +void MWindow::refresh_mixers(int dir) { - queue_mixers(edl,CURRENT_FRAME,0,0,1,0); + int command = dir >= 0 ? CURRENT_FRAME : LAST_FRAME; + queue_mixers(edl,command,0,0,1,0,0); } void MWindow::stop_mixers() @@ -1250,16 +1264,17 @@ void MWindow::stop_mixers() for( int vidx=0; vidxidx < 0 ) continue; - zwindow->issue_command(STOP, 0, 0, 0, 0); + zwindow->issue_command(STOP, 0, 0, 0, 0, 0); } } -void MWindow::close_mixers() +void MWindow::close_mixers(int destroy) { zwindows_lock->lock("MWindow::close_mixers"); - for( int i=0; i=0; ) { ZWindow *zwindow = zwindows[i]; if( zwindow->idx < 0 ) continue; + zwindow->destroy = destroy; ZWindowGUI *zgui = zwindow->zgui; zgui->lock_window("MWindow::select_zwindow 0"); zgui->set_done(0); @@ -1273,6 +1288,70 @@ void MWindow::close_mixers() } } +ZWindow *MWindow::create_mixer(Indexable *indexable) +{ + ArrayList new_assets; + new_assets.append(indexable); + Track *track = edl->tracks->last; + load_assets(&new_assets, 0, 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; + } + if( indexable->is_asset ) { + char *path = indexable->path; + char *tp = strrchr(path, '/'); + if( !tp ) tp = path; else ++tp; + zwindow->set_title(tp); + } + else { + char *title = ((EDL*)indexable)->local_session->clip_title; + zwindow->set_title(title); + } + return zwindow; +} + +void MWindow::create_mixers() +{ + if( !session->drag_assets->size() && + !session->drag_clips->size() ) return; + undo->update_undo_before(); + + select_zwindow(0); + ArrayListnew_mixers; + + for( int i=0; idrag_assets->size(); ++i ) { + Indexable *indexable = session->drag_assets->get(i); + if( !indexable->have_video() ) continue; + ZWindow *zwindow = create_mixer(indexable); + new_mixers.append(zwindow); + } + for( int i=0; idrag_clips->size(); ++i ) { + Indexable *indexable = (Indexable*)session->drag_clips->get(i); + if( !indexable->have_video() ) continue; + ZWindow *zwindow = create_mixer(indexable); + new_mixers.append(zwindow); + } + + tile_mixers(); + for( int i=0; istart(); + + 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; imixers.size(); ++i ) { @@ -1492,19 +1571,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) @@ -1546,7 +1620,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); @@ -1556,37 +1632,49 @@ void MWindow::set_brender_active(int v, int update) int MWindow::has_commercials() { +#ifdef HAVE_COMMERCIAL return theme->use_commercials; +#else + return 0; +#endif } void MWindow::init_commercials() { +#ifdef HAVE_COMMERCIAL if( !commercials ) { commercials = new Commercials(this); commercial_active = 0; } else commercials->add_user(); +#endif } void MWindow::commit_commercial() { +#ifdef HAVE_COMMERCIAL if( !commercial_active ) return; commercial_active = 0; if( !commercials ) return; commercials->commitDb(); +#endif } void MWindow::undo_commercial() { +#ifdef HAVE_COMMERCIAL if( !commercial_active ) return; commercial_active = 0; if( !commercials ) return; commercials->undoDb(); +#endif } int MWindow::put_commercial() { + int result = 0; +#ifdef HAVE_COMMERCIAL double start = edl->local_session->get_selectionstart(); double end = edl->local_session->get_selectionend(); if( start >= end ) return 0; @@ -1594,7 +1682,6 @@ int MWindow::put_commercial() const char *errmsg = 0; int count = 0; Tracks *tracks = edl->tracks; - int result = 0; //check it for(Track *track=tracks->first; track && !errmsg; track=track->next) { if( track->data_type != TRACK_VIDEO ) continue; @@ -1647,6 +1734,7 @@ int MWindow::put_commercial() undo_commercial(); result = 1; } +#endif return result; } @@ -1668,6 +1756,17 @@ void MWindow::stop_playback(int wait) } } +void MWindow::stop_transport() +{ + gui->stop_transport(gui->get_window_lock() ? "MWindow::stop_transport" : 0); +} + +void MWindow::beep(double freq, double secs, double gain) +{ + if( !proxy_beep ) proxy_beep = new ProxyBeep(this); + proxy_beep->tone(freq, secs, gain); +} + int MWindow::load_filenames(ArrayList *filenames, int load_mode, int update_filename) @@ -1880,10 +1979,10 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); // 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); //printf("MWindow::load_filenames %p %s\n", nested_edl, nested_edl->project_path); - edl_to_nested(new_edl, nested_edl); + new_edl->create_nested(nested_edl); + new_edl->set_path(filenames->get(i)); nested_edl->Garbage::remove_user(); } else { @@ -1967,40 +2066,33 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); // Add new assets to EDL and schedule assets for index building. int got_indexes = 0; - for(int i = 0; i < new_edls.size(); i++) - { + for( int i=0; inested_edls->size(); j++) - { - mainindexes->add_next_asset(0, - new_edl->nested_edls->get(j)); + for( int j=0; jnested_edls.size(); ++j ) { + mainindexes->add_next_asset(0, new_edl->nested_edls[j]); + edl->nested_edls.update_index(new_edl->nested_edls[j]); got_indexes = 1; - edl->nested_edls->update_index(new_edl->nested_edls->get(j)); } } if(debug) printf("MWindow::load_filenames %d\n", __LINE__); - for(int i = 0; i < new_assets.size(); i++) - { + for( int i=0; iasset->path, - new_asset->path)) - { + if( !strcmp(new_file->asset->path, new_asset->path) ) { got_it = 1; break; } } mainindexes->add_next_asset(got_it ? new_file : 0, new_asset); - got_indexes = 1; edl->assets->update(new_asset); + got_indexes = 1; } if(debug) printf("MWindow::load_filenames %d\n", __LINE__); @@ -2044,6 +2136,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); edl->session->proxy_scale = 1; edl->session->proxy_use_scaler = 0; edl->session->proxy_auto_scale = 0; + edl->session->proxy_beep = 0; edl->local_session->preview_start = 0; edl->local_session->preview_end = 0; edl->local_session->loop_playback = 0; @@ -2073,8 +2166,14 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); } } gui->unlock_window(); // to update progress bar - render_proxy(orig_idxbls); + int ret = render_proxy(orig_idxbls); gui->lock_window("MWindow::load_filenames"); + if( ret >= 0 && edl->session->proxy_beep ) { + if( ret > 0 ) + beep(2000., 1.5, 0.5); + else + beep(4000., 0.25, 0.5); + } } // need to update undo before project, since mwindow is unlocked & a new load @@ -2121,7 +2220,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); return 0; } -void MWindow::render_proxy(ArrayList &new_idxbls) +int MWindow::render_proxy(ArrayList &new_idxbls) { Asset *format_asset = new Asset; format_asset->format = FILE_FFMPEG; @@ -2149,112 +2248,81 @@ void MWindow::render_proxy(ArrayList &new_idxbls) &proxy_render.orig_idxbls, &proxy_render.orig_proxies); } format_asset->remove_user(); + return !result ? proxy_render.needed_proxies.size() : -1; } 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; kplugin_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); } } } } -void MWindow::init_shm() +void MWindow::init_shm(const char *pfn, int64_t min) { + int64_t result = 0; // Fix shared memory - FILE *fd = fopen("/proc/sys/kernel/shmmax", "w"); - if(fd) { - fprintf(fd, "0x7fffffff"); + FILE *fd = fopen(pfn, "r"); + if( fd ) { + fscanf(fd, "%jd", &result); fclose(fd); + if( result >= min ) return; } - fd = 0; - fd = fopen("/proc/sys/kernel/shmmax", "r"); - if(!fd) { - MainError::show_error("MWindow::init_shm: couldn't open /proc/sys/kernel/shmmax for reading.\n"); + fd = fopen(pfn, "w"); + if( !fd ) return; + fprintf(fd, "0x%jx", min); + fclose(fd); + + fd = fopen(pfn, "r"); + if( !fd ) { + eprintf(_("MWindow::init_shm: couldn't open %s for reading.\n"), pfn); return; } - int64_t result = 0; fscanf(fd, "%jd", &result); fclose(fd); - fd = 0; - if(result < 0x7fffffff) { - eprintf(_("MWindow::init_shm: /proc/sys/kernel/shmmax is %p.\n" + if( result < min ) { + eprintf(_("MWindow::init_shm: %s is %p.\n" "you probably need to be root, or:\n" - "as root, run: echo 0x7fffffff > /proc/sys/kernel/shmmax\n" + "as root, run: echo 0x%jx > %s\n" "before trying to start cinelerra.\n" - "It should be at least 0x7fffffff for Cinelerra.\n"), (void *)result); + "It should be at least 0x%jx for Cinelerra.\n"), + pfn, (void *)result, min, pfn, min); } } @@ -2302,9 +2370,6 @@ void MWindow::create_objects(int want_gui, BC_Resources::init_fontconfig(string); if(debug) PRINT_TRACE -// Initialize before too much else is running -// Preferences & theme are required for building MPEG table of contents - // Default project created here init_edl(); if(debug) PRINT_TRACE @@ -2439,7 +2504,8 @@ void MWindow::create_objects(int want_gui, &MWindowGUI::keyboard_listener); hide_splash(); - init_shm(); + init_shm("/proc/sys/kernel/shmmax", 0x7fffffff); + init_shm("/proc/sys/kernel/shmmni", 0x4000); if(debug) PRINT_TRACE BC_WindowBase::get_resources()->vframe_shm = 1; @@ -3183,38 +3249,6 @@ if(debug) printf("MWindow::asset_to_edl %d\n", __LINE__); return 0; } -int MWindow::edl_to_nested(EDL *new_edl, - EDL *nested_edl) -{ - -// Keep frame rate, sample rate, and output size unchanged. -// These parameters would revert the project if VWindow displayed an asset -// of different size than the project. - - - -// Nest all video & audio outputs - new_edl->session->video_tracks = 1; - new_edl->session->audio_tracks = nested_edl->session->audio_channels; - new_edl->create_default_tracks(); - - - - new_edl->insert_asset(0, - nested_edl, - 0, - 0, - 0); - - char string[BCTEXTLEN]; - FileSystem fs; - fs.extract_name(string, nested_edl->path); -//printf("MWindow::edl_to_nested %p %s\n", nested_edl, nested_edl->path); - - strcpy(new_edl->local_session->clip_title, string); - - return 0; -} // Reset everything after a load. void MWindow::update_project(int load_mode) @@ -3222,7 +3256,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 @@ -3236,6 +3269,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); @@ -3262,9 +3296,13 @@ void MWindow::update_project(int load_mode) if( !vwindow->is_running() ) continue; vwindow->close_window(); } + for( int i=0; ivwindow_edls.size(); ++i ) { + VWindow *vwindow = get_viewer(1, -1); + vwindow->change_source(i); + } if(debug) PRINT_TRACE select_zwindow(0); - close_mixers(); + close_mixers(0); for( int i=0; imixers.size(); ++i ) { Mixer *mixer = edl->mixers[i]; @@ -3343,10 +3381,13 @@ void MWindow::save_backup() FileXML file; edl->optimize(); edl->set_path(session->filename); - char backup_path[BCTEXTLEN]; + char backup_path[BCTEXTLEN], backup_path1[BCTEXTLEN]; snprintf(backup_path, sizeof(backup_path), "%s/%s", File::get_config_path(), BACKUP_FILE); - edl->save_xml(&file, backup_path, 0, 0); + snprintf(backup_path1, sizeof(backup_path1), "%s/%s", + File::get_config_path(), BACKUP_FILE1); + rename(backup_path, backup_path1); + edl->save_xml(&file, backup_path); file.terminate_string(); FileSystem fs; fs.complete_path(backup_path); @@ -3382,6 +3423,29 @@ void MWindow::load_backup() save_backup(); } + +void MWindow::save_undo_data() +{ + char perpetual_path[BCTEXTLEN]; + snprintf(perpetual_path, sizeof(perpetual_path), "%s/%s", + File::get_config_path(), PERPETUAL_FILE); + FILE *fp = fopen(perpetual_path,"w"); + if( !fp ) return; + undo->save(fp); + fclose(fp); +} + +void MWindow::load_undo_data() +{ + char perpetual_path[BCTEXTLEN]; + snprintf(perpetual_path, sizeof(perpetual_path), "%s/%s", + File::get_config_path(), PERPETUAL_FILE); + FILE *fp = fopen(perpetual_path,"r"); + if( !fp ) return; + undo->load(fp); + fclose(fp); +} + static inline int gcd(int m, int n) { int r; @@ -3966,29 +4030,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 ) {