X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindow.C;h=7d871c9652126768e7e3d1612aaaaaa23fcde9ec;hp=6150f954131af90569483dc305304075ff4c09d8;hb=7eded24eb31529ad7652dea64e34b0a6210e5be1;hpb=a94468d6de897136e77c70662177f4b8b4454b6b diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 6150f954..7d871c96 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -28,6 +28,7 @@ #include "awindow.h" #include "batchrender.h" #include "bcdisplayinfo.h" +#include "bcprogressbox.h" #include "bcsignals.h" #include "bctimer.h" #include "bctrace.h" @@ -41,6 +42,7 @@ #include "clipedls.h" #include "bccmodels.h" #include "commercials.h" +#include "confirmsave.h" #include "cplayback.h" #include "ctimebar.h" #include "cwindowgui.h" @@ -97,6 +99,7 @@ #include "removefile.h" #include "render.h" #include "resourcethread.h" +#include "savefile.inc" #include "samplescroll.h" #include "sha1.h" #include "sighandler.h" @@ -141,6 +144,7 @@ #include #include #include +#include #include #include @@ -173,6 +177,7 @@ extern "C" } +extern long cin_timezone; ArrayList* MWindow::plugindb = 0; Commercials* MWindow::commercials = 0; @@ -210,7 +215,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; @@ -231,6 +235,7 @@ MWindow::MWindow() screens = 1; in_destructor = 0; speed_edl = 0; + proxy_beep = 0; } @@ -245,6 +250,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; @@ -319,7 +325,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 @@ -423,8 +428,8 @@ const char *MWindow::default_std() } } -//__timezone: Seconds west of UTC. 240sec/deg - double tz_deg = -__timezone / 240.; +// cin_timezone: Seconds west of UTC. 240sec/deg + double tz_deg = -cin_timezone / 240.; // from Honolulu = -10, to New York = -5, 15deg/hr lat -150..-75 return tz_deg >= -10*15 && tz_deg <= -5*15 ? "NTSC" : "PAL"; } @@ -471,6 +476,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(); } @@ -520,12 +526,11 @@ void MWindow::get_plugin_path(char *path, const char *plug_dir, const char *fs_p delete [] base_path; } -int MWindow::load_plugin_index(MWindow *mwindow, const char *index_path, const char *plugin_dir) +int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir) { -// load index - FILE *fp = fopen(index_path, "r"); if( !fp ) return -1; - +// load index + fseek(fp, 0, SEEK_SET); int ret = 0; char index_line[BCTEXTLEN]; int index_version = -1, len = strlen(plugin_dir); @@ -561,6 +566,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); @@ -570,7 +578,6 @@ int MWindow::load_plugin_index(MWindow *mwindow, const char *index_path, const c ret = 1; continue; } } - fclose(fp); if( !ret ) ret = check_plugin_index(plugins, plugin_dir, "."); @@ -617,20 +624,36 @@ int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences) create_defaults_path(index_path, PLUGIN_FILE); char *plugin_dir = FileSystem::basepath(preferences->plugin_dir); strcpy(plugin_path, plugin_dir); delete [] plugin_dir; - if( !load_plugin_index(mwindow, index_path, plugin_path) ) return 1; - printf("init plugin index: %s\n", plugin_path); - FILE *fp = fopen(index_path,"w"); + FILE *fp = fopen(index_path,"a+"); if( !fp ) { fprintf(stderr,_("MWindow::init_plugins: " - "can't create plugin index: %s\n"), index_path); - return 1; + "can't open plugin index: %s\n"), index_path); + return -1; + } + int fd = fileno(fp), ret = -1; + if( !flock(fd, LOCK_EX) ) { + fseek(fp, 0, SEEK_SET); + ret = load_plugin_index(mwindow, fp, plugin_path); + } + if( ret > 0 ) { + ftruncate(fd, 0); + fseek(fp, 0, SEEK_SET); + printf("init plugin index: %s\n", plugin_path); + fprintf(fp, "%d\n", PLUGIN_FILE_VERSION); + 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); + fseek(fp, 0, SEEK_SET); + ret = load_plugin_index(mwindow, fp, plugin_path); + } + if( ret ) { + fprintf(stderr,_("MWindow::init_plugins: " + "can't %s plugin index: %s\n"), + ret>0 ? _("create") : _("lock"), index_path); } - fprintf(fp, "%d\n", PLUGIN_FILE_VERSION); - fprintf(fp, "%s\n", plugin_path); - init_plugin_index(mwindow, preferences, fp, plugin_path); - init_ffmpeg_index(mwindow, preferences, fp); fclose(fp); - return load_plugin_index(mwindow, index_path, plugin_path); + return ret; } int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences) @@ -654,9 +677,30 @@ int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences) for( char *bp=plugin_path; *bp!=0; ++bp ) *cp++ = *bp=='/' ? '_' : *bp; *cp = 0; - if( !load_plugin_index(mwindow, index_path, plugin_path) ) continue; - if( init_ladspa_index(mwindow, preferences, index_path, plugin_path) ) continue; - load_plugin_index(mwindow, index_path, plugin_path); + FILE *fp = fopen(index_path,"a+"); + if( !fp ) { + fprintf(stderr,_("MWindow::init_ladspa_plugins: " + "can't open ladspa plugin index: %s\n"), index_path); + continue; + } + int fd = fileno(fp), ret = -1; + if( !flock(fd, LOCK_EX) ) { + fseek(fp, 0, SEEK_SET); + ret = load_plugin_index(mwindow, fp, plugin_path); + } + if( ret > 0 ) { + ftruncate(fd, 0); + fseek(fp, 0, SEEK_SET); + init_ladspa_index(mwindow, preferences, fp, plugin_path); + fseek(fp, 0, SEEK_SET); + ret = load_plugin_index(mwindow, fp, plugin_path); + } + if( ret ) { + fprintf(stderr,_("MWindow::init_ladspa_plugins: " + "can't %s ladspa plugin index: %s\n"), + ret>0 ? _("create") : _("lock"), index_path); + } + fclose(fp); } return 1; } @@ -675,25 +719,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) { @@ -746,17 +771,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(); + 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 ) { snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt", - cfg_path); + dat_path); fp = fopen(msg_path, "r"); } if( !fp ) return; @@ -897,10 +922,25 @@ int MWindow::plugin_exists(char *plugin_path) return !plugindb ? 0 : plugin_exists(plugin_path, *plugindb); } +void MWindow::remove_plugin_index() +{ + char index_path[BCTEXTLEN]; + MWindow::create_defaults_path(index_path, PLUGIN_FILE); + ::remove(index_path); +} + void MWindow::init_preferences() { preferences = new Preferences; preferences->load_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 @@ -1156,7 +1196,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 ) @@ -1268,22 +1307,24 @@ void MWindow::stop_mixers() } } -void MWindow::close_mixers() +void MWindow::close_mixers(int destroy) { + ArrayList closed; 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); zgui->unlock_window(); + closed.append(zwindow); } zwindows_lock->unlock(); - for( int i=0; iidx < 0 ) continue; - zwindow->close_window(); + for( int i=0; ijoin(); } } @@ -1328,11 +1369,13 @@ void MWindow::create_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); } @@ -1514,9 +1557,7 @@ void MWindow::init_indexes() void MWindow::init_gui() { gui = new MWindowGUI(this); - gui->lock_window("MWindow::init_gui"); gui->create_objects(); - gui->unlock_window(); gui->load_defaults(defaults); } @@ -1629,37 +1670,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; @@ -1667,7 +1720,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; @@ -1720,6 +1772,7 @@ int MWindow::put_commercial() undo_commercial(); result = 1; } +#endif return result; } @@ -1746,6 +1799,12 @@ 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) @@ -1782,7 +1841,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); char string[BCTEXTLEN]; new_edl->create_objects(); - new_edl->copy_session(edl); + new_edl->copy_session(edl, -1); new_file->set_program(edl->session->program_no); sprintf(string, _("Loading %s"), new_asset->path); @@ -1947,7 +2006,8 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); result = 1; break; } - if( strcmp(cin_version, CINELERRA_VERSION) ) { + if( strcmp(cin_version, CINELERRA_VERSION) && + strcmp(cin_version, "5.1") ) { char string[BCTEXTLEN]; snprintf(string, sizeof(string), _("Warning: XML from cinelerra version %s\n" @@ -2113,10 +2173,12 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); load_mode == LOADMODE_REPLACE_CONCATENATE ) ) { select_asset(0, 0); edl->session->proxy_scale = 1; + edl->session->proxy_disabled_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->preview_end = -1; edl->local_session->loop_playback = 0; edl->local_session->set_selectionstart(0); edl->local_session->set_selectionend(0); @@ -2144,8 +2206,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 @@ -2192,7 +2260,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; @@ -2220,6 +2288,173 @@ 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; +} + +int MWindow::enable_proxy() +{ + int ret = 0; + if( edl->session->proxy_scale == 1 && + edl->session->proxy_disabled_scale != 1 ) { + int new_scale = edl->session->proxy_disabled_scale; + int new_use_scaler = edl->session->proxy_use_scaler; + edl->session->proxy_disabled_scale = 1; + Asset *asset = new Asset; + asset->format = FILE_FFMPEG; + asset->load_defaults(defaults, "PROXY_", 1, 1, 0, 0, 0); + ret = to_proxy(asset, new_scale, new_use_scaler); + asset->remove_user(); + if( ret > 0 ) + beep(2000., 1.5, 0.5); + } + return 1; +} + +int MWindow::disable_proxy() +{ + if( edl->session->proxy_scale != 1 && + edl->session->proxy_disabled_scale == 1 ) { + int new_scale = 1; + int new_use_scaler = edl->session->proxy_use_scaler; + edl->session->proxy_disabled_scale = edl->session->proxy_scale; + Asset *asset = new Asset; + asset->format = FILE_FFMPEG; + asset->load_defaults(defaults, "PROXY_", 1, 1, 0, 0, 0); + to_proxy(asset, new_scale, new_use_scaler); + asset->remove_user(); + } + return 1; +} + +int MWindow::to_proxy(Asset *asset, int new_scale, int new_use_scaler) +{ + ArrayList orig_idxbls; + ArrayList proxy_assets; + + edl->Garbage::add_user(); + save_backup(); + undo->update_undo_before(_("proxy"), this); + ProxyRender proxy_render(this, asset); + +// revert project to original size from current size +// remove all session proxy assets at the at the current proxy_scale + int proxy_scale = edl->session->proxy_scale; + + if( proxy_scale > 1 ) { + Asset *orig_asset = edl->assets->first; + for( ; orig_asset; orig_asset=orig_asset->next ) { + char new_path[BCTEXTLEN]; + proxy_render.to_proxy_path(new_path, orig_asset, proxy_scale); +// test if proxy asset was already added to proxy_assets + int got_it = 0; + for( int i = 0; !got_it && ipath, new_path); + if( got_it ) continue; + Asset *proxy_asset = edl->assets->get_asset(new_path); + if( !proxy_asset ) continue; +// add pointer to existing EDL asset if it exists +// EDL won't delete it unless it's the same pointer. + proxy_assets.append(proxy_asset); + proxy_asset->add_user(); + orig_idxbls.append(orig_asset); + orig_asset->add_user(); + } + for( int i=0,n=edl->nested_edls.size(); inested_edls[i]; + char new_path[BCTEXTLEN]; + if( !ProxyRender::from_proxy_path(new_path, orig_nested, proxy_scale) ) + continue; + proxy_render.to_proxy_path(new_path, orig_nested, proxy_scale); +// test if proxy asset was already added to proxy_assets + int got_it = 0; + for( int i = 0; !got_it && ipath, new_path); + if( got_it ) continue; + Asset *proxy_nested = edl->assets->get_asset(new_path); + if( !proxy_nested ) continue; +// add pointer to existing EDL asset if it exists +// EDL won't delete it unless it's the same pointer. + proxy_assets.append(proxy_nested); + proxy_nested->add_user(); + orig_idxbls.append(orig_nested); + orig_nested->add_user(); + } + +// convert from the proxy assets to the original assets + edl->set_proxy(1, 0, &proxy_assets, &orig_idxbls); + +// remove the references + for( int i=0; iwidth = proxy->actual_width; + proxy->height = proxy->actual_height; + proxy->remove_user(); + edl->assets->remove_pointer(proxy); + proxy->remove_user(); + } + proxy_assets.remove_all(); + for( int i = 0; i < orig_idxbls.size(); i++ ) + orig_idxbls[i]->remove_user(); + orig_idxbls.remove_all(); + } + + ArrayList confirm_paths; // test for new files + confirm_paths.set_array_delete(); + +// convert to new size if not original size + if( new_scale != 1 ) { + FileSystem fs; + Asset *orig = edl->assets->first; + for( ; orig; orig=orig->next ) { + Asset *proxy = proxy_render.add_original(orig, new_scale); + if( !proxy ) continue; + int exists = fs.get_size(proxy->path) > 0 ? 1 : 0; + int got_it = exists && // if proxy exists, and is newer than orig + fs.get_date(proxy->path) > fs.get_date(orig->path) ? 1 : 0; + if( !got_it ) { + if( exists ) // prompt user to overwrite + confirm_paths.append(cstrdup(proxy->path)); + proxy_render.add_needed(orig, proxy); + } + } + for( int i=0,n=edl->nested_edls.size(); inested_edls[i]; + Asset *proxy = proxy_render.add_original(orig_nested, new_scale); + if( !proxy ) continue; + int exists = fs.get_size(proxy->path) > 0 ? 1 : 0; + int got_it = exists && // if proxy exists, and is newer than orig_nested + fs.get_date(proxy->path) > fs.get_date(orig_nested->path) ? 1 : 0; + if( !got_it ) { + if( exists ) // prompt user to overwrite + confirm_paths.append(cstrdup(proxy->path)); + proxy_render.add_needed(orig_nested, proxy); + } + } + } + + int result = 0; +// test for existing files + if( confirm_paths.size() ) { + result = ConfirmSave::test_files(this, &confirm_paths); + confirm_paths.remove_all_objects(); + } + + if( !result ) + result = proxy_render.create_needed_proxies(new_scale); + + if( !result ) // resize project + edl->set_proxy(new_scale, new_use_scaler, + &proxy_render.orig_idxbls, &proxy_render.orig_proxies); + + undo->update_undo_after(_("proxy"), LOAD_ALL); + edl->Garbage::remove_user(); + restart_brender(); + + gui->lock_window("MWindow::to_proxy"); + update_project(LOADMODE_REPLACE); + gui->unlock_window(); + + return !result ? proxy_render.needed_proxies.size() : -1; } void MWindow::test_plugins(EDL *new_edl, char *path) @@ -2319,14 +2554,14 @@ void MWindow::create_objects(int want_gui, check_language(); init_preferences(); if(splash_window) - splash_window->operation->update(_("Initializing Plugins")); + splash_window->update_status(_("Initializing Plugins")); init_plugins(this, preferences); if(debug) PRINT_TRACE init_ladspa_plugins(this, preferences); if(debug) PRINT_TRACE init_plugin_tips(*plugindb, cin_lang); if(splash_window) - splash_window->operation->update(_("Initializing GUI")); + splash_window->update_status(_("Initializing GUI")); if(debug) PRINT_TRACE init_theme(); @@ -2334,16 +2569,13 @@ void MWindow::create_objects(int want_gui, init_error(); if(splash_window) - splash_window->operation->update(_("Initializing Fonts")); + splash_window->update_status(_("Initializing Fonts")); char string[BCTEXTLEN]; strcpy(string, preferences->plugin_dir); strcat(string, "/" FONT_SEARCHPATH); 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 @@ -2649,12 +2881,6 @@ void MWindow::toggle_loop_playback() sync_parameters(CHANGE_PARAMS); } -//void MWindow::set_titles(int value) -//{ -// edl->session->show_titles = value; -// trackmovement(edl->local_session->track_start); -//} - void MWindow::set_screens(int value) { screens = value; @@ -2724,6 +2950,19 @@ void MWindow::toggle_editing_mode() set_editing_mode(EDITING_ARROW, 0, 1); } +void MWindow::toggle_camera_xyz() +{ + gwindow->gui->lock_window("MWindow::toggle_camera_xyz"); + gwindow->gui->toggle_camera_xyz(); + gwindow->gui->unlock_window(); +} + +void MWindow::toggle_projector_xyz() +{ + gwindow->gui->lock_window("MWindow::toggle_projector_xyz"); + gwindow->gui->toggle_projector_xyz(); + gwindow->gui->unlock_window(); +} void MWindow::set_labels_follow_edits(int value) { @@ -3234,9 +3473,10 @@ void MWindow::update_project(int load_mode) if(debug) PRINT_TRACE - if(load_mode == LOADMODE_REPLACE || - load_mode == LOADMODE_REPLACE_CONCATENATE) - { + if( load_mode == LOADMODE_REPLACE || + load_mode == LOADMODE_REPLACE_CONCATENATE ) { + delete gui->keyvalue_popup; + gui->keyvalue_popup = 0; gui->load_panes(); } @@ -3276,7 +3516,7 @@ void MWindow::update_project(int load_mode) } if(debug) PRINT_TRACE select_zwindow(0); - close_mixers(); + close_mixers(0); for( int i=0; imixers.size(); ++i ) { Mixer *mixer = edl->mixers[i]; @@ -3400,6 +3640,8 @@ void MWindow::load_backup() void MWindow::save_undo_data() { + undo->update_undo_before(); + undo->update_undo_after(_("perpetual session"), LOAD_ALL); char perpetual_path[BCTEXTLEN]; snprintf(perpetual_path, sizeof(perpetual_path), "%s/%s", File::get_config_path(), PERPETUAL_FILE); @@ -3420,6 +3662,187 @@ void MWindow::load_undo_data() fclose(fp); } + +int MWindow::copy_target(const char *path, const char *target) +{ + int ifd = ::open(path, O_RDONLY); + if( ifd < 0 ) { + eprintf("Cannot open asset: %s", path); + return 1; + } + int ret = 0; + int ofd = ::open(target, O_CREAT+O_TRUNC+O_WRONLY, 0777); + if( ofd >= 0 ) { + struct stat st; + int64_t total_bytes = !fstat(ifd, &st) ? st.st_size : 0; + char progress_title[BCTEXTLEN]; + sprintf(progress_title, _("Copying: %s\n"), target); + BC_ProgressBox progress(-1, -1, progress_title, total_bytes); + + int64_t count = 0, len = -1; + int bfrsz = 0x100000; + uint8_t *bfr = new uint8_t[bfrsz]; + while( (len=::read(ifd, bfr, bfrsz)) > 0 ) { + if( len != ::write(ofd, bfr, len) ) { + eprintf("Error writing: %s", target); + break; + } + if( progress.is_cancelled() ) { + ret = 1; + break; + } + progress.update(count += len, 1); + } + delete [] bfr; + ::close(ofd); + + progress.stop_progress(); + if( len < 0 ) { + eprintf("Error reading: %s", path); + ret = 1; + } + } + else + eprintf("Cannot create asset target: %s", target); + ::close(ifd); + return ret; +} + +int MWindow::link_target(const char *real_path, const char *link_path, int relative) +{ + char target[BCTEXTLEN]; + if( relative ) { + const char *bp = real_path, *cp = bp; + const char *lp = link_path, *np = lp; + char *tp = target, *ep = tp+sizeof(target)-1, lch; + while( *lp && *bp && (lch=*lp++) == *bp++ ) { + if( lch == '/' ) { np = lp; cp = bp; } + } + while( tpcreate_objects(); + save_edl->copy_all(edl); + + char progress_title[BCTEXTLEN]; + sprintf(progress_title, _("Saving to %s:\n"), dir); + int total_assets = save_edl->assets->total(); + MainProgressBar *progress = mainprogress->start_progress(progress_title, total_assets); + int ret = 0; + Asset *current = save_edl->assets->first; + for( int i=0; !ret && current; ++i, current=NEXT ) { + char *path = current->path; + if( ::stat(path, &st) ) { + eprintf("Asset not found: %s", path); + continue; + } + char *real_path = realpath(path, 0); + const char *cp = strrchr(path, '/'), *bp = !cp ? path : cp+1; + char link_path[BCTEXTLEN]; + snprintf(link_path, sizeof(link_path), "%s/%s", dir_path, bp); + int skip = 0; + if( strcmp(real_path, link_path) ) { + if( !::lstat(link_path, &st) ) { + if( overwrite ) + ::remove(link_path); + else + skip = 1; + } + } + else { + eprintf("copy/link to self, skippped: %s", path); + skip = 1; + } + if( !skip ) { + if( save_mode == SAVE_PROJECT_COPY ) { + if( copy_target(real_path, link_path) ) + ret = 1; + } + else { + link_target(real_path, link_path, + save_mode == SAVE_PROJECT_RELLINK ? 1 : 0); + } + } + free(real_path); + strcpy(path, link_path); + + if( progress->is_cancelled() ) break; + progress->update(i); + } + + progress->stop_progress(); + delete progress; + + char *cp = strrchr(dir_path,'/'); + char *bp = cp ? cp+1 : dir_path; + char filename[BCTEXTLEN]; + snprintf(filename, sizeof(filename), "%s/%s.xml", dir_path, bp); + save_edl->set_path(filename); + FileXML file; + save_edl->save_xml(&file, filename); + file.terminate_string(); + + if( !file.write_to_file(filename) ) { + char string[BCTEXTLEN]; + sprintf(string, _("\"%s\" %dC written"), filename, (int)strlen(file.string())); + gui->lock_window("SaveProject::run 2"); + gui->show_message(string); + gui->unlock_window(); + gui->mainmenu->add_load(filename); + } + else + eprintf(_("Couldn't open %s."), filename); + + save_edl->remove_user(); + + if( reload ) { + gui->lock_window("MWindow::save_project"); + ArrayList filenames; + filenames.append(filename); + load_filenames(&filenames, LOADMODE_REPLACE); + gui->unlock_window(); + } +} + + static inline int gcd(int m, int n) { int r;