3 #include "awindowgui.h"
5 #include "batchrender.h"
6 #include "bcdisplayinfo.h"
11 #include "channeldb.h"
13 #include "colormodels.h"
14 #include "cplayback.h"
16 #include "cwindowgui.h"
19 #include "editpanel.h"
21 #include "edlsession.h"
23 #include "fileformat.h"
25 #include "filesystem.h"
28 #include "gwindowgui.h"
29 #include "indexfile.h"
30 #include "interlacemodes.h"
32 #include "levelwindowgui.h"
33 #include "levelwindow.h"
34 #include "loadfile.inc"
35 #include "localsession.h"
36 #include "maincursor.h"
37 #include "mainerror.h"
38 #include "mainindexes.h"
40 #include "mainprogress.h"
41 #include "mainsession.h"
45 #include "mwindowgui.h"
49 #include "playback3d.h"
50 #include "playbackengine.h"
52 #include "pluginserver.h"
53 #include "pluginset.h"
54 #include "preferences.h"
56 #include "recordlabel.h"
58 #include "samplescroll.h"
59 #include "sighandler.h"
60 #include "splashgui.h"
61 #include "statusbar.h"
63 #include "threadloader.h"
65 #include "tipwindow.h"
66 #include "trackcanvas.h"
69 #include "trackscroll.h"
71 #include "transition.h"
72 #include "transportque.h"
74 #include "videodevice.inc"
75 #include "videowindow.h"
76 #include "vplayback.h"
77 #include "vwindowgui.h"
80 #include "exportedl.h"
92 // Hack for libdv to remove glib dependancy
95 // g_log (const char *log_domain,
97 // const char *format,
103 // g_logv (const char *log_domain,
105 // const char *format,
112 // Hack for XFree86 4.1.0
114 int atexit(void (*function)(void))
128 plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
129 brender_lock = new Mutex("MWindow::brender_lock");
132 channeldb_buz = new ChannelDB;
133 channeldb_v4l2jpeg = new ChannelDB;
138 brender_lock->lock("MWindow::~MWindow");
139 if(brender) delete brender;
141 brender_lock->unlock();
152 // Give up and go to a movie
157 delete audio_cache; // delete the cache after the assets
158 delete video_cache; // delete the cache after the assets
164 // delete renderlist;
169 plugin_guis->remove_all_objects();
171 delete plugin_gui_lock;
174 void MWindow::init_error()
179 void MWindow::create_defaults_path(char *string)
181 // set the .bcast path
184 sprintf(string, "%s", BCASTDIR);
185 fs.complete_path(string);
186 if(!fs.is_dir(string))
188 fs.create_dir(string);
192 strcat(string, "Cinelerra_rc");
195 void MWindow::init_defaults(BC_Hash* &defaults, char *config_path)
197 char path[BCTEXTLEN];
198 // Use user supplied path
201 strcpy(path, config_path);
205 create_defaults_path(path);
208 defaults = new BC_Hash(path);
212 void MWindow::init_plugin_path(Preferences *preferences,
213 ArrayList<PluginServer*>* &plugindb,
215 SplashGUI *splash_window,
219 PluginServer *newplugin;
223 for(int i = 0; i < fs->dir_list.total; i++)
225 char path[BCTEXTLEN];
226 strcpy(path, fs->dir_list.values[i]->path);
228 // File is a directory
235 // Try to query the plugin
236 fs->complete_path(path);
237 //printf("MWindow::init_plugin_path %s\n", path);
238 PluginServer *new_plugin = new PluginServer(path);
239 int result = new_plugin->open_plugin(1, preferences, 0, 0, -1);
243 plugindb->append(new_plugin);
244 new_plugin->close_plugin();
246 splash_window->operation->update(_(new_plugin->title));
249 if(result == PLUGINSERVER_IS_LAD)
252 // Open LAD subplugins
256 new_plugin = new PluginServer(path);
257 result = new_plugin->open_plugin(1,
265 plugindb->append(new_plugin);
266 new_plugin->close_plugin();
268 splash_window->operation->update(_(new_plugin->title));
277 // Plugin failed to open
282 if(splash_window) splash_window->progress->update((*counter)++);
287 void MWindow::init_plugins(Preferences *preferences,
288 ArrayList<PluginServer*>* &plugindb,
289 SplashGUI *splash_window)
291 plugindb = new ArrayList<PluginServer*>;
295 FileSystem cinelerra_fs;
296 ArrayList<FileSystem*> lad_fs;
300 cinelerra_fs.set_filter("[*.plugin][*.so]");
301 result = cinelerra_fs.update(preferences->global_plugin_dir);
306 _("MWindow::init_plugins: couldn't open %s directory\n"),
307 preferences->global_plugin_dir);
310 // Parse LAD environment variable
311 char *env = getenv("LADSPA_PATH");
314 char string[BCTEXTLEN];
318 char *ptr = strchr(ptr1, ':');
326 end = env + strlen(env);
331 int len = end - ptr1;
332 memcpy(string, ptr1, len);
336 FileSystem *fs = new FileSystem;
338 fs->set_filter("*.so");
339 result = fs->update(string);
344 _("MWindow::init_plugins: couldn't open %s directory\n"),
356 int total = cinelerra_fs.total_files();
358 for(int i = 0; i < lad_fs.total; i++)
359 total += lad_fs.values[i]->total_files();
360 if(splash_window) splash_window->progress->update_length(total);
365 init_plugin_path(preferences,
371 // Call automatically generated routine to get plugins
375 for(int i = 0; i < lad_fs.total; i++)
376 init_plugin_path(preferences,
382 lad_fs.remove_all_objects();
385 void MWindow::delete_plugins()
387 for(int i = 0; i < plugindb->total; i++)
389 delete plugindb->values[i];
394 void MWindow::create_plugindb(int do_audio,
399 ArrayList<PluginServer*> &plugindb)
402 for(int i = 0; i < this->plugindb->total; i++)
404 PluginServer *current = this->plugindb->values[i];
406 if(current->audio == do_audio &&
407 current->video == do_video &&
408 (current->realtime == is_realtime || is_realtime < 0) &&
409 current->transition == is_transition &&
410 current->theme == is_theme)
411 plugindb.append(current);
414 // Alphabetize list by title
420 for(int i = 0; i < plugindb.total - 1; i++)
422 PluginServer *value1 = plugindb.values[i];
423 PluginServer *value2 = plugindb.values[i + 1];
424 if(strcmp(_(value1->title), _(value2->title)) > 0)
427 plugindb.values[i] = value2;
428 plugindb.values[i + 1] = value1;
434 PluginServer* MWindow::scan_plugindb(char *title,
439 printf("MWindow::scan_plugindb data_type < 0\n");
443 for(int i = 0; i < plugindb->total; i++)
445 PluginServer *server = plugindb->values[i];
446 if(!strcasecmp(server->title, title) &&
447 ((data_type == TRACK_AUDIO && server->audio) ||
448 (data_type == TRACK_VIDEO && server->video)))
449 return plugindb->values[i];
454 void MWindow::init_preferences()
456 preferences = new Preferences;
457 preferences->load_defaults(defaults);
458 session = new MainSession(this);
459 session->load_defaults(defaults);
462 void MWindow::clean_indexes()
467 int oldest_item = -1;
469 char string[BCTEXTLEN];
470 char string2[BCTEXTLEN];
472 // Delete extra indexes
473 fs.set_filter("*.idx");
474 fs.complete_path(preferences->index_directory);
475 fs.update(preferences->index_directory);
476 //printf("MWindow::clean_indexes 1 %d\n", fs.dir_list.total);
478 // Eliminate directories
483 for(int i = 0; i < fs.dir_list.total && !result; i++)
485 fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
486 if(fs.is_dir(string))
488 delete fs.dir_list.values[i];
489 fs.dir_list.remove_number(i);
494 total_excess = fs.dir_list.total - preferences->index_count;
496 //printf("MWindow::clean_indexes 2 %d\n", fs.dir_list.total);
497 while(total_excess > 0)
500 for(int i = 0; i < fs.dir_list.total; i++)
502 fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
504 if(i == 0 || fs.get_date(string) <= oldest)
506 oldest = fs.get_date(string);
514 fs.join_names(string,
515 preferences->index_directory,
516 fs.dir_list.values[oldest_item]->name);
517 //printf("MWindow::clean_indexes 1 %s\n", string);
519 perror("delete_indexes");
520 delete fs.dir_list.values[oldest_item];
521 fs.dir_list.remove_number(oldest_item);
523 // Remove table of contents if it exists
524 strcpy(string2, string);
525 char *ptr = strrchr(string2, '.');
528 //printf("MWindow::clean_indexes 2 %s\n", string2);
529 sprintf(ptr, ".toc");
538 void MWindow::init_awindow()
540 awindow = new AWindow(this);
541 awindow->create_objects();
544 void MWindow::init_gwindow()
546 gwindow = new GWindow(this);
547 gwindow->create_objects();
550 void MWindow::init_tipwindow()
552 twindow = new TipWindow(this);
556 void MWindow::init_theme()
560 // Replace blond theme with SUV since it doesn't work
561 if(!strcasecmp(preferences->theme, "Blond"))
562 strcpy(preferences->theme, DEFAULT_THEME);
564 for(int i = 0; i < plugindb->total; i++)
566 if(plugindb->values[i]->theme &&
567 !strcasecmp(preferences->theme, plugindb->values[i]->title))
569 PluginServer plugin = *plugindb->values[i];
570 plugin.open_plugin(0, preferences, 0, 0, -1);
571 theme = plugin.new_theme();
572 theme->mwindow = this;
573 strcpy(theme->path, plugin.path);
574 plugin.close_plugin();
580 fprintf(stderr, _("MWindow::init_theme: theme %s not found.\n"), preferences->theme);
584 // Load images which may have been forgotten
585 theme->Theme::initialize();
588 // Create menus with user colors
589 theme->build_menus();
595 void MWindow::init_3d()
597 playback_3d = new Playback3D(this);
598 playback_3d->create_objects();
601 void MWindow::init_edl()
604 edl->create_objects();
605 edl->load_defaults(defaults);
606 edl->create_default_tracks();
607 edl->tracks->update_y_pixels(theme);
610 void MWindow::init_compositor()
612 cwindow = new CWindow(this);
613 cwindow->create_objects();
616 void MWindow::init_levelwindow()
618 lwindow = new LevelWindow(this);
619 lwindow->create_objects();
622 void MWindow::init_viewer()
624 vwindow = new VWindow(this);
625 vwindow->load_defaults();
626 vwindow->create_objects();
629 void MWindow::init_cache()
631 audio_cache = new CICache(preferences, plugindb);
632 video_cache = new CICache(preferences, plugindb);
635 void MWindow::init_channeldb()
637 channeldb_buz->load("channeldb_buz");
638 channeldb_v4l2jpeg->load("channeldb_v4l2jpeg");
641 void MWindow::init_menus()
643 char string[BCTEXTLEN];
646 cmodel_to_text(string, BC_RGB888);
647 colormodels.append(new ColormodelItem(string, BC_RGB888));
648 cmodel_to_text(string, BC_RGBA8888);
649 colormodels.append(new ColormodelItem(string, BC_RGBA8888));
650 // cmodel_to_text(string, BC_RGB161616);
651 // colormodels.append(new ColormodelItem(string, BC_RGB161616));
652 // cmodel_to_text(string, BC_RGBA16161616);
653 // colormodels.append(new ColormodelItem(string, BC_RGBA16161616));
654 cmodel_to_text(string, BC_RGB_FLOAT);
655 colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT));
656 cmodel_to_text(string, BC_RGBA_FLOAT);
657 colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT));
658 cmodel_to_text(string, BC_YUV888);
659 colormodels.append(new ColormodelItem(string, BC_YUV888));
660 cmodel_to_text(string, BC_YUVA8888);
661 colormodels.append(new ColormodelItem(string, BC_YUVA8888));
662 // cmodel_to_text(string, BC_YUV161616);
663 // colormodels.append(new ColormodelItem(string, BC_YUV161616));
664 // cmodel_to_text(string, BC_YUVA16161616);
665 // colormodels.append(new ColormodelItem(string, BC_YUVA16161616));
667 #define ILACEPROJECTMODELISTADD(x) ilacemode_to_text(string, x); \
668 interlace_project_modes.append(new InterlacemodeItem(string, x));
670 #define ILACEASSETMODELISTADD(x) ilacemode_to_text(string, x); \
671 interlace_asset_modes.append(new InterlacemodeItem(string, x));
673 #define ILACEFIXMETHODLISTADD(x) ilacefixmethod_to_text(string, x); \
674 interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
677 ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
679 ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
680 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
682 ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
683 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
685 ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
686 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
688 // Interlacing Fixing Methods
689 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
690 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
691 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
694 void MWindow::init_indexes()
696 mainindexes = new MainIndexes(this);
697 mainindexes->start_loop();
700 void MWindow::init_gui()
702 gui = new MWindowGUI(this);
703 gui->create_objects();
704 gui->load_defaults(defaults);
707 void MWindow::init_signals()
709 sighandler = new SigHandler;
710 sighandler->initialize();
714 void MWindow::init_render()
716 render = new Render(this);
717 // renderlist = new Render(this);
718 batch_render = new BatchRenderThread(this);
721 void MWindow::init_exportedl()
723 exportedl = new ExportEDL(this);
726 void MWindow::init_brender()
728 if(preferences->use_brender && !brender)
730 brender_lock->lock("MWindow::init_brender 1");
731 brender = new BRender(this);
732 brender->initialize();
733 session->brender_end = 0;
734 brender_lock->unlock();
737 if(!preferences->use_brender && brender)
739 brender_lock->lock("MWindow::init_brender 2");
742 session->brender_end = 0;
743 brender_lock->unlock();
745 if(brender) brender->restart(edl);
748 void MWindow::restart_brender()
750 //printf("MWindow::restart_brender 1\n");
751 if(brender) brender->restart(edl);
754 void MWindow::stop_brender()
756 if(brender) brender->stop();
759 int MWindow::brender_available(int position)
762 brender_lock->lock("MWindow::brender_available 1");
765 if(brender->map_valid)
767 brender->map_lock->lock("MWindow::brender_available 2");
768 if(position < brender->map_size &&
771 //printf("MWindow::brender_available 1 %d %d\n", position, brender->map[position]);
772 if(brender->map[position] == BRender::RENDERED)
775 brender->map_lock->unlock();
778 brender_lock->unlock();
782 void MWindow::set_brender_start()
784 edl->session->brender_start = edl->local_session->get_selectionstart();
786 gui->canvas->draw_overlays();
787 gui->canvas->flash();
792 int MWindow::load_filenames(ArrayList<char*> *filenames,
800 ArrayList<EDL*> new_edls;
801 ArrayList<Asset*> new_assets;
802 ArrayList<File*> new_files;
805 gui->start_hourglass();
807 // Need to stop playback since tracking depends on the EDL not getting
809 cwindow->playback_engine->que->send_command(STOP,
813 vwindow->playback_engine->que->send_command(STOP,
817 cwindow->playback_engine->interrupt_playback(0);
818 vwindow->playback_engine->interrupt_playback(0);
822 // Define new_edls and new_assets to load
824 for(int i = 0; i < filenames->total; i++)
827 File *new_file = new File;
828 Asset *new_asset = new Asset(filenames->values[i]);
829 EDL *new_edl = new EDL;
830 char string[BCTEXTLEN];
832 // Set reel name and number for the asset
833 // If the user wants to overwrite the last used reel number for the clip,
834 // we have to rebuild the index for the file
838 char source_filename[BCTEXTLEN];
839 char index_filename[BCTEXTLEN];
841 strcpy(new_asset->reel_name, reel_name);
842 new_asset->reel_number = reel_number;
844 IndexFile::get_index_filename(source_filename,
845 preferences->index_directory,
848 remove(index_filename);
849 new_asset->index_status = INDEX_NOTTESTED;
852 new_edl->create_objects();
853 new_edl->copy_session(edl);
855 sprintf(string, "Loading %s", new_asset->path);
856 gui->show_message(string);
858 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
863 // Convert media file to EDL
865 // Warn about odd image dimensions
866 if(new_asset->video_data &&
867 ((new_asset->width % 2) ||
868 (new_asset->height % 2)))
870 char string[BCTEXTLEN];
871 sprintf(string, "%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly.",
875 MainError::show_error(string);
879 if(load_mode != LOAD_RESOURCESONLY)
882 asset_to_edl(new_edl, new_asset);
884 new_edls.append(new_edl);
886 Garbage::delete_object(new_asset);
892 new_assets.append(new_asset);
895 // Set filename to nothing for assets since save EDL would overwrite them.
896 if(load_mode == LOAD_REPLACE ||
897 load_mode == LOAD_REPLACE_CONCATENATE)
900 // Reset timeline position
901 new_edl->local_session->view_start = 0;
902 new_edl->local_session->track_start = 0;
910 sprintf(string, _("Failed to open %s"), new_asset->path);
911 gui->show_message(string, theme->message_error);
916 case FILE_UNRECOGNIZED_CODEC:
919 IndexFile indexfile(this);
920 result = indexfile.open_index(this, new_asset);
923 indexfile.close_index();
926 // Test existing EDLs
929 for(int j = 0; j < new_edls.total + 1; j++)
932 if(j == new_edls.total)
934 if(old_asset = edl->assets->get_asset(new_asset->path))
936 *new_asset = *old_asset;
942 if(old_asset = new_edls.values[j]->assets->get_asset(new_asset->path))
944 *new_asset = *old_asset;
954 char string[BCTEXTLEN];
956 fs.extract_name(string, new_asset->path);
958 strcat(string, _("'s format couldn't be determined."));
959 new_asset->audio_data = 1;
960 new_asset->format = FILE_PCM;
961 new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
962 new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
963 new_asset->bits = defaults->get("AUDIO_BITS", 16);
964 new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
965 new_asset->signed_ = defaults->get("SIGNED_", 1);
966 new_asset->header = defaults->get("HEADER", 0);
968 FileFormat fwindow(this);
969 fwindow.create_objects(new_asset, string);
970 result = fwindow.run_window();
972 defaults->update("AUDIO_CHANNELS", new_asset->channels);
973 defaults->update("SAMPLE_RATE", new_asset->sample_rate);
974 defaults->update("AUDIO_BITS", new_asset->bits);
975 defaults->update("BYTE_ORDER", new_asset->byte_order);
976 defaults->update("SIGNED_", new_asset->signed_);
977 defaults->update("HEADER", new_asset->header);
984 // Recalculate length
987 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
989 if(load_mode != LOAD_RESOURCESONLY)
991 asset_to_edl(new_edl, new_asset);
992 new_edls.append(new_edl);
993 Garbage::delete_object(new_asset);
998 new_assets.append(new_asset);
1011 xml_file.read_from_file(filenames->values[i]);
1012 // Load EDL for pasting
1013 new_edl->load_xml(plugindb, &xml_file, LOAD_ALL);
1014 test_plugins(new_edl, filenames->values[i]);
1016 // We don't want a valid reel name/number for projects
1017 strcpy(new_asset->reel_name, "");
1020 if(load_mode == LOAD_REPLACE ||
1021 load_mode == LOAD_REPLACE_CONCATENATE)
1023 strcpy(session->filename, filenames->values[i]);
1024 strcpy(new_edl->local_session->clip_title, filenames->values[i]);
1026 set_filename(new_edl->local_session->clip_title);
1029 new_edls.append(new_edl);
1039 Garbage::delete_object(new_asset);
1045 // Store for testing index
1046 new_files.append(new_file);
1052 if(!result) gui->statusbar->default_message();
1062 // Don't back up here.
1065 // For pasting, clear the active region
1066 if(load_mode == LOAD_PASTE)
1068 double start = edl->local_session->get_selectionstart();
1069 double end = edl->local_session->get_selectionend();
1070 if(!EQUIV(start, end))
1073 edl->session->labels_follow_edits,
1074 edl->session->plugins_follow_edits);
1077 paste_edls(&new_edls,
1081 edl->session->labels_follow_edits,
1082 edl->session->plugins_follow_edits);
1090 // Add new assets to EDL and schedule assets for index building.
1091 // Used for loading resources only.
1092 if(new_assets.total)
1094 for(int i = 0; i < new_assets.total; i++)
1096 Asset *new_asset = new_assets.values[i];
1098 File *index_file = 0;
1100 for(int j = 0; j < new_files.total; j++)
1102 new_file = new_files.values[j];
1103 if(!strcmp(new_file->asset->path,
1111 mainindexes->add_next_asset(got_it ? new_file : 0,
1113 edl->assets->update(new_asset);
1118 // Start examining next batch of index files
1119 mainindexes->start_build();
1123 update_project(load_mode);
1128 new_edls.remove_all_objects();
1130 for(int i = 0; i < new_assets.total; i++)
1131 Garbage::delete_object(new_assets.values[i]);
1133 new_assets.remove_all();
1135 new_files.remove_all_objects();
1138 undo->update_undo(_("load"), LOAD_ALL, 0);
1142 gui->stop_hourglass();
1151 void MWindow::test_plugins(EDL *new_edl, char *path)
1153 char string[BCTEXTLEN];
1154 // Do a check weather plugins exist
1155 for(Track *track = new_edl->tracks->first; track; track = track->next)
1157 for(int k = 0; k < track->plugin_set.total; k++)
1159 PluginSet *plugin_set = track->plugin_set.values[k];
1160 for(Plugin *plugin = (Plugin*)plugin_set->first;
1162 plugin = (Plugin*)plugin->next)
1164 if(plugin->plugin_type == PLUGIN_STANDALONE)
1166 // ok we need to find it in plugindb
1167 int plugin_found = 0;
1168 for(int j = 0; j < plugindb->total; j++)
1170 PluginServer *server = plugindb->values[j];
1171 if(!strcasecmp(server->title, plugin->title) &&
1172 ((track->data_type == TRACK_AUDIO && server->audio) ||
1173 (track->data_type == TRACK_VIDEO && server->video)) &&
1174 (!server->transition))
1180 "The effect '%s' in file '%s' is not part of your installation of Cinelerra.\n"
1181 "The project won't be rendered as it was meant and Cinelerra might crash.\n",
1184 MainError::show_error(string);
1189 for(Edit *edit = (Edit*)track->edits->first;
1191 edit = (Edit*)edit->next)
1193 if (edit->transition)
1195 // ok we need to find transition in plugindb
1196 int transition_found = 0;
1197 for(int j = 0; j < plugindb->total; j++)
1199 PluginServer *server = plugindb->values[j];
1200 if(!strcasecmp(server->title, edit->transition->title) &&
1201 ((track->data_type == TRACK_AUDIO && server->audio) ||
1202 (track->data_type == TRACK_VIDEO && server->video)) &&
1203 (server->transition))
1204 transition_found = 1;
1206 if (!transition_found)
1209 "The transition '%s' in file '%s' is not part of your installation of Cinelerra.\n"
1210 "The project won't be rendered as it was meant and Cinelerra might crash.\n",
1211 edit->transition->title,
1213 MainError::show_error(string);
1224 void MWindow::create_objects(int want_gui,
1228 char string[BCTEXTLEN];
1237 // For some reason, init_signals must come after show_splash or the signals won't
1245 init_defaults(defaults, config_path);
1249 init_plugins(preferences, plugindb, splash_window);
1250 if(splash_window) splash_window->operation->update(_("Initializing GUI"));
1253 // Default project created here
1279 mainprogress = new MainProgress(this, gui);
1280 undo = new MainUndo(this);
1282 plugin_guis = new ArrayList<PluginServer*>;
1285 if(session->show_vwindow) vwindow->gui->show_window();
1286 if(session->show_cwindow) cwindow->gui->show_window();
1287 if(session->show_awindow) awindow->gui->show_window();
1288 if(session->show_lwindow) lwindow->gui->show_window();
1289 if(session->show_gwindow) gwindow->gui->show_window();
1293 gui->mainmenu->load_defaults(defaults);
1295 gui->mainmenu->update_toggles(0);
1297 gui->patchbay->update();
1299 gui->canvas->draw();
1301 gui->cursor->draw(1);
1304 gui->raise_window();
1306 if(preferences->use_tipwindow)
1316 void MWindow::show_splash()
1318 #include "data/heroine_logo12_png.h"
1319 VFrame *frame = new VFrame(heroine_logo12_png);
1320 BC_DisplayInfo display_info;
1321 splash_window = new SplashGUI(frame,
1322 display_info.get_root_w() / 2 - frame->get_w() / 2,
1323 display_info.get_root_h() / 2 - frame->get_h() / 2);
1324 splash_window->create_objects();
1327 void MWindow::hide_splash()
1330 delete splash_window;
1335 void MWindow::start()
1344 playback_3d->start();
1352 void MWindow::show_vwindow()
1354 session->show_vwindow = 1;
1355 vwindow->gui->lock_window("MWindow::show_vwindow");
1356 vwindow->gui->show_window();
1357 vwindow->gui->raise_window();
1358 vwindow->gui->flush();
1359 vwindow->gui->unlock_window();
1360 gui->mainmenu->show_vwindow->set_checked(1);
1363 void MWindow::show_awindow()
1365 session->show_awindow = 1;
1366 awindow->gui->lock_window("MWindow::show_awindow");
1367 awindow->gui->show_window();
1368 awindow->gui->raise_window();
1369 awindow->gui->flush();
1370 awindow->gui->unlock_window();
1371 gui->mainmenu->show_awindow->set_checked(1);
1374 void MWindow::show_cwindow()
1376 session->show_cwindow = 1;
1377 cwindow->show_window();
1378 gui->mainmenu->show_cwindow->set_checked(1);
1381 void MWindow::show_gwindow()
1383 session->show_gwindow = 1;
1385 gwindow->gui->lock_window("MWindow::show_gwindow");
1386 gwindow->gui->show_window();
1387 gwindow->gui->raise_window();
1388 gwindow->gui->flush();
1389 gwindow->gui->unlock_window();
1391 gui->mainmenu->show_gwindow->set_checked(1);
1394 void MWindow::show_lwindow()
1396 session->show_lwindow = 1;
1397 lwindow->gui->lock_window("MWindow::show_lwindow");
1398 lwindow->gui->show_window();
1399 lwindow->gui->raise_window();
1400 lwindow->gui->flush();
1401 lwindow->gui->unlock_window();
1402 gui->mainmenu->show_lwindow->set_checked(1);
1405 void MWindow::tile_windows()
1407 session->default_window_positions();
1408 gui->default_positions();
1411 void MWindow::toggle_loop_playback()
1413 edl->local_session->loop_playback = !edl->local_session->loop_playback;
1414 set_loop_boundaries();
1417 gui->canvas->draw_overlays();
1418 gui->canvas->flash();
1419 sync_parameters(CHANGE_PARAMS);
1422 void MWindow::set_titles(int value)
1424 edl->session->show_titles = value;
1425 trackmovement(edl->local_session->track_start);
1428 void MWindow::set_auto_keyframes(int value)
1430 gui->lock_window("MWindow::set_auto_keyframes");
1431 edl->session->auto_keyframes = value;
1432 gui->mbuttons->edit_panel->keyframe->update(value);
1434 gui->unlock_window();
1435 cwindow->gui->lock_window("MWindow::set_auto_keyframes");
1436 cwindow->gui->edit_panel->keyframe->update(value);
1437 cwindow->gui->flush();
1438 cwindow->gui->unlock_window();
1441 int MWindow::set_editing_mode(int new_editing_mode)
1443 gui->lock_window("MWindow::set_editing_mode");
1444 edl->session->editing_mode = new_editing_mode;
1445 gui->mbuttons->edit_panel->editing_mode = edl->session->editing_mode;
1446 gui->mbuttons->edit_panel->update();
1447 gui->canvas->update_cursor();
1448 gui->unlock_window();
1449 cwindow->gui->lock_window("MWindow::set_editing_mode");
1450 cwindow->gui->edit_panel->update();
1451 cwindow->gui->edit_panel->editing_mode = edl->session->editing_mode;
1452 cwindow->gui->unlock_window();
1457 void MWindow::sync_parameters(int change_type)
1460 // Sync engines which are playing back
1461 if(cwindow->playback_engine->is_playing_back)
1463 if(change_type == CHANGE_PARAMS)
1465 // TODO: block keyframes until synchronization is done
1466 cwindow->playback_engine->sync_parameters(edl);
1471 int command = cwindow->playback_engine->command->command;
1472 cwindow->playback_engine->que->send_command(STOP,
1476 // Waiting for tracking to finish would make the restart position more
1477 // accurate but it can't lock the window to stop tracking for some reason.
1478 // Not waiting for tracking gives a faster response but restart position is
1479 // only as accurate as the last tracking update.
1480 cwindow->playback_engine->interrupt_playback(0);
1481 cwindow->playback_engine->que->send_command(command,
1490 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1497 void MWindow::age_caches()
1499 int64_t prev_memory_usage;
1500 int64_t memory_usage;
1504 memory_usage = audio_cache->get_memory_usage(1) +
1505 video_cache->get_memory_usage(1);
1507 if(memory_usage > preferences->cache_size)
1510 int oldest1 = audio_cache->get_oldest();
1511 int oldest2 = video_cache->get_oldest();
1512 if(oldest2 < oldest1) target = 2;
1515 case 1: audio_cache->delete_oldest(); break;
1516 case 2: video_cache->delete_oldest(); break;
1519 prev_memory_usage = memory_usage;
1520 memory_usage = audio_cache->get_memory_usage(1) +
1521 video_cache->get_memory_usage(1);
1523 prev_memory_usage != memory_usage &&
1524 memory_usage > preferences->cache_size);
1527 void MWindow::show_plugin(Plugin *plugin)
1530 //printf("MWindow::show_plugin 1\n");
1531 plugin_gui_lock->lock("MWindow::show_plugin");
1532 for(int i = 0; i < plugin_guis->total; i++)
1534 // Pointer comparison
1535 if(plugin_guis->values[i]->plugin == plugin)
1537 plugin_guis->values[i]->raise_window();
1543 //printf("MWindow::show_plugin 1\n");
1548 printf("MWindow::show_plugin track not defined.\n");
1550 PluginServer *server = scan_plugindb(plugin->title,
1551 plugin->track->data_type);
1553 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
1554 if(server && server->uses_gui)
1556 PluginServer *gui = plugin_guis->append(new PluginServer(*server));
1557 // Needs mwindow to do GUI
1558 gui->set_mwindow(this);
1559 gui->open_plugin(0, preferences, edl, plugin, -1);
1564 plugin_gui_lock->unlock();
1565 //printf("MWindow::show_plugin 2\n");
1568 void MWindow::hide_plugin(Plugin *plugin, int lock)
1571 gui->lock_window("MWindow::hide_plugin");
1572 gui->update(0, 1, 0, 0, 0, 0, 0);
1573 gui->unlock_window();
1575 if(lock) plugin_gui_lock->lock("MWindow::hide_plugin");
1576 for(int i = 0; i < plugin_guis->total; i++)
1578 if(plugin_guis->values[i]->plugin == plugin)
1580 PluginServer *ptr = plugin_guis->values[i];
1581 plugin_guis->remove(ptr);
1582 if(lock) plugin_gui_lock->unlock();
1583 // Last command executed in client side close
1588 if(lock) plugin_gui_lock->unlock();
1592 void MWindow::hide_plugins()
1594 plugin_gui_lock->lock("MWindow::hide_plugins");
1595 plugin_guis->remove_all_objects();
1596 plugin_gui_lock->unlock();
1599 void MWindow::update_plugin_guis()
1601 plugin_gui_lock->lock("MWindow::update_plugin_guis");
1603 for(int i = 0; i < plugin_guis->total; i++)
1605 plugin_guis->values[i]->update_gui();
1607 plugin_gui_lock->unlock();
1610 int MWindow::plugin_gui_open(Plugin *plugin)
1613 plugin_gui_lock->lock("MWindow::plugin_gui_open");
1614 for(int i = 0; i < plugin_guis->total; i++)
1616 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1622 plugin_gui_lock->unlock();
1626 void MWindow::render_plugin_gui(void *data, Plugin *plugin)
1628 plugin_gui_lock->lock("MWindow::render_plugin_gui");
1629 for(int i = 0; i < plugin_guis->total; i++)
1631 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1633 plugin_guis->values[i]->render_gui(data);
1637 plugin_gui_lock->unlock();
1640 void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin)
1642 plugin_gui_lock->lock("MWindow::render_plugin_gui");
1643 for(int i = 0; i < plugin_guis->total; i++)
1645 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1647 plugin_guis->values[i]->render_gui(data, size);
1651 plugin_gui_lock->unlock();
1655 void MWindow::update_plugin_states()
1657 plugin_gui_lock->lock("MWindow::update_plugin_states");
1658 for(int i = 0; i < plugin_guis->total; i++)
1662 Plugin *src_plugin = plugin_guis->values[i]->plugin;
1663 PluginServer *src_plugingui = plugin_guis->values[i];
1665 // Search for plugin in EDL. Only the master EDL shows plugin GUIs.
1666 for(Track *track = edl->tracks->first;
1668 track = track->next)
1671 j < track->plugin_set.total && !result;
1674 PluginSet *plugin_set = track->plugin_set.values[j];
1675 for(Plugin *plugin = (Plugin*)plugin_set->first;
1677 plugin = (Plugin*)plugin->next)
1679 if(plugin == src_plugin &&
1680 !strcmp(plugin->title, src_plugingui->title)) result = 1;
1686 // Doesn't exist anymore
1689 hide_plugin(src_plugin, 0);
1693 plugin_gui_lock->unlock();
1697 void MWindow::update_plugin_titles()
1699 for(int i = 0; i < plugin_guis->total; i++)
1701 plugin_guis->values[i]->update_title();
1705 int MWindow::asset_to_edl(EDL *new_edl,
1707 RecordLabels *labels)
1709 //printf("MWindow::asset_to_edl 1\n");
1710 // new_edl->load_defaults(defaults);
1712 // Keep frame rate, sample rate, and output size unchanged.
1713 // These parameters would revert the project if VWindow displayed an asset
1714 // of different size than the project.
1715 if(new_asset->video_data)
1717 new_edl->session->video_tracks = new_asset->layers;
1718 // new_edl->session->frame_rate = new_asset->frame_rate;
1719 // new_edl->session->output_w = new_asset->width;
1720 // new_edl->session->output_h = new_asset->height;
1723 new_edl->session->video_tracks = 0;
1730 if(new_asset->audio_data)
1732 new_edl->session->audio_tracks = new_asset->channels;
1733 // new_edl->session->sample_rate = new_asset->sample_rate;
1736 new_edl->session->audio_tracks = 0;
1737 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1739 new_edl->create_default_tracks();
1740 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1742 // Disable drawing if the file format isn't fast enough.
1743 // MPEG is now faster than most other codecs.
1744 // if(new_asset->format == FILE_MPEG)
1746 // for(Track *current = new_edl->tracks->first;
1750 // if(current->data_type == TRACK_VIDEO) current->draw = 0;
1756 //printf("MWindow::asset_to_edl 3\n");
1757 new_edl->insert_asset(new_asset, 0, 0, labels);
1758 //printf("MWindow::asset_to_edl 3\n");
1764 char string[BCTEXTLEN];
1766 fs.extract_name(string, new_asset->path);
1767 //printf("MWindow::asset_to_edl 3\n");
1769 strcpy(new_edl->local_session->clip_title, string);
1770 //printf("MWindow::asset_to_edl 4 %s\n", string);
1776 // Reset everything after a load.
1777 void MWindow::update_project(int load_mode)
1780 edl->tracks->update_y_pixels(theme);
1783 gui->update(1, 1, 1, 1, 1, 1, 1);
1785 cwindow->update(0, 0, 1, 1, 1);
1788 if(load_mode == LOAD_REPLACE ||
1789 load_mode == LOAD_REPLACE_CONCATENATE)
1791 vwindow->change_source();
1798 cwindow->gui->slider->set_position();
1799 cwindow->gui->timebar->update(1, 1);
1800 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1805 awindow->gui->lock_window("MWindow::update_project");
1806 awindow->gui->update_assets();
1807 awindow->gui->flush();
1808 awindow->gui->unlock_window();
1813 void MWindow::rebuild_indices()
1815 char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
1817 for(int i = 0; i < session->drag_assets->total; i++)
1819 //printf("MWindow::rebuild_indices 1 %s\n", session->drag_assets->values[i]->path);
1821 IndexFile::get_index_filename(source_filename,
1822 preferences->index_directory,
1824 session->drag_assets->values[i]->path);
1825 remove(index_filename);
1826 // Schedule index build
1827 session->drag_assets->values[i]->index_status = INDEX_NOTTESTED;
1828 mainindexes->add_next_asset(0, session->drag_assets->values[i]);
1830 mainindexes->start_build();
1834 void MWindow::save_backup()
1837 edl->set_project_path(session->filename);
1838 edl->save_xml(plugindb,
1843 file.terminate_string();
1844 char path[BCTEXTLEN];
1846 strcpy(path, BACKUP_PATH);
1847 fs.complete_path(path);
1849 if(file.write_to_file(path))
1852 sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
1853 gui->show_message(string2);
1858 int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
1861 if(!width || !height) return 1;
1862 float fraction = (float)width / height;
1864 for(denominator = 1;
1865 denominator < 100 &&
1866 fabs(fraction * denominator - (int)(fraction * denominator)) > .001;
1870 w = denominator * width / height;
1875 void MWindow::reset_caches()
1877 audio_cache->remove_all();
1878 video_cache->remove_all();
1879 if(cwindow->playback_engine && cwindow->playback_engine->audio_cache)
1880 cwindow->playback_engine->audio_cache->remove_all();
1881 if(cwindow->playback_engine && cwindow->playback_engine->video_cache)
1882 cwindow->playback_engine->video_cache->remove_all();
1883 if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
1884 vwindow->playback_engine->audio_cache->remove_all();
1885 if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
1886 vwindow->playback_engine->video_cache->remove_all();
1889 void MWindow::remove_asset_from_caches(Asset *asset)
1891 audio_cache->delete_entry(asset);
1892 video_cache->delete_entry(asset);
1893 if(cwindow->playback_engine && cwindow->playback_engine->audio_cache)
1894 cwindow->playback_engine->audio_cache->delete_entry(asset);
1895 if(cwindow->playback_engine && cwindow->playback_engine->video_cache)
1896 cwindow->playback_engine->video_cache->delete_entry(asset);
1897 if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
1898 vwindow->playback_engine->audio_cache->delete_entry(asset);
1899 if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
1900 vwindow->playback_engine->video_cache->delete_entry(asset);
1905 void MWindow::remove_assets_from_project(int push_undo)
1907 for(int i = 0; i < session->drag_assets->total; i++)
1909 Asset *asset = session->drag_assets->values[i];
1910 remove_asset_from_caches(asset);
1913 // Remove from VWindow.
1914 for(int i = 0; i < session->drag_clips->total; i++)
1916 if(session->drag_clips->values[i] == vwindow->get_edl())
1918 vwindow->gui->lock_window("MWindow::remove_assets_from_project 1");
1919 vwindow->remove_source();
1920 vwindow->gui->unlock_window();
1924 for(int i = 0; i < session->drag_assets->total; i++)
1926 if(session->drag_assets->values[i] == vwindow->get_asset())
1928 vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
1929 vwindow->remove_source();
1930 vwindow->gui->unlock_window();
1934 edl->remove_from_project(session->drag_assets);
1935 edl->remove_from_project(session->drag_clips);
1937 if(push_undo) undo->update_undo(_("remove assets"), LOAD_ALL);
1940 gui->lock_window("MWindow::remove_assets_from_project 3");
1948 gui->unlock_window();
1950 awindow->gui->lock_window("MWindow::remove_assets_from_project 4");
1951 awindow->gui->update_assets();
1952 awindow->gui->flush();
1953 awindow->gui->unlock_window();
1955 // Removes from playback here
1956 sync_parameters(CHANGE_ALL);
1959 void MWindow::remove_assets_from_disk()
1962 for(int i = 0; i < session->drag_assets->total; i++)
1964 remove(session->drag_assets->values[i]->path);
1967 remove_assets_from_project(1);
1970 void MWindow::dump_plugins()
1972 for(int i = 0; i < plugindb->total; i++)
1974 printf("audio=%d video=%d realtime=%d transition=%d theme=%d %s\n",
1975 plugindb->values[i]->audio,
1976 plugindb->values[i]->video,
1977 plugindb->values[i]->realtime,
1978 plugindb->values[i]->transition,
1979 plugindb->values[i]->theme,
1980 plugindb->values[i]->title);
2008 int MWindow::save_defaults()
2010 gui->save_defaults(defaults);
2011 edl->save_defaults(defaults);
2012 session->save_defaults(defaults);
2013 preferences->save_defaults(defaults);
2019 int MWindow::run_script(FileXML *script)
2021 int result = 0, result2 = 0;
2022 while(!result && !result2)
2024 result = script->read_tag();
2027 if(script->tag.title_is("new_project"))
2029 // Run new in immediate mode.
2030 // gui->mainmenu->new_project->run_script(script);
2033 if(script->tag.title_is("record"))
2035 // Run record as a thread. It is a terminal command.
2037 // Will read the complete scipt file without letting record read it if not
2043 printf("MWindow::run_script: Unrecognized command: %s\n",script->tag.get_title() );
2050 // ================================= synchronization
2053 int MWindow::interrupt_indexes()
2055 mainindexes->interrupt_build();
2061 void MWindow::next_time_format()
2063 switch(edl->session->time_format)
2065 case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
2066 case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
2067 case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
2068 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
2069 case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
2070 case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
2071 case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
2074 time_format_common();
2077 void MWindow::prev_time_format()
2079 switch(edl->session->time_format)
2081 case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
2082 case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
2083 case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
2084 case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
2085 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
2086 case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
2087 case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
2090 time_format_common();
2093 void MWindow::time_format_common()
2095 gui->lock_window("MWindow::next_time_format");
2096 gui->redraw_time_dependancies();
2097 char string[BCTEXTLEN], string2[BCTEXTLEN];
2098 sprintf(string, _("Using %s."), Units::print_time_format(edl->session->time_format, string2));
2099 gui->show_message(string);
2101 gui->unlock_window();
2105 int MWindow::set_filename(char *filename)
2107 strcpy(session->filename, filename);
2110 if(filename[0] == 0)
2112 gui->set_title(PROGRAM_NAME);
2117 char string[BCTEXTLEN], string2[BCTEXTLEN];
2118 dir.extract_name(string, filename);
2119 sprintf(string2, PROGRAM_NAME ": %s", string);
2120 gui->set_title(string2);
2133 int MWindow::set_loop_boundaries()
2135 double start = edl->local_session->get_selectionstart();
2136 double end = edl->local_session->get_selectionend();
2144 if(edl->tracks->total_length())
2147 end = edl->tracks->total_length();
2154 if(edl->local_session->loop_playback && start != end)
2156 edl->local_session->loop_start = start;
2157 edl->local_session->loop_end = end;
2168 int MWindow::reset_meters()
2170 cwindow->gui->lock_window("MWindow::reset_meters 1");
2171 cwindow->gui->meters->reset_meters();
2172 cwindow->gui->unlock_window();
2174 vwindow->gui->lock_window("MWindow::reset_meters 2");
2175 vwindow->gui->meters->reset_meters();
2176 vwindow->gui->unlock_window();
2178 lwindow->gui->lock_window("MWindow::reset_meters 3");
2179 lwindow->gui->panel->reset_meters();
2180 lwindow->gui->unlock_window();
2182 gui->lock_window("MWindow::reset_meters 4");
2183 gui->patchbay->reset_meters();
2184 gui->unlock_window();