3 #include "awindowgui.h"
5 #include "batchrender.h"
6 #include "bcdisplayinfo.h"
10 #include "channeldb.h"
12 #include "colormodels.h"
13 #include "cplayback.h"
15 #include "cwindowgui.h"
18 #include "editpanel.h"
20 #include "edlsession.h"
22 #include "fileformat.h"
24 #include "filesystem.h"
27 #include "gwindowgui.h"
28 #include "indexfile.h"
29 #include "interlacemodes.h"
31 #include "levelwindowgui.h"
32 #include "levelwindow.h"
33 #include "loadfile.inc"
34 #include "localsession.h"
35 #include "maincursor.h"
36 #include "mainindexes.h"
38 #include "mainprogress.h"
39 #include "mainsession.h"
43 #include "mwindowgui.h"
47 #include "playbackengine.h"
49 #include "pluginserver.h"
50 #include "pluginset.h"
51 #include "preferences.h"
53 #include "recordlabel.h"
55 #include "samplescroll.h"
56 #include "sighandler.h"
57 #include "splashgui.h"
58 #include "statusbar.h"
60 #include "threadloader.h"
62 #include "tipwindow.h"
63 #include "trackcanvas.h"
66 #include "trackscroll.h"
68 #include "transition.h"
69 #include "transportque.h"
71 #include "videodevice.inc"
72 #include "videowindow.h"
73 #include "vplayback.h"
74 #include "vwindowgui.h"
77 #include "exportedl.h"
89 // Hack for libdv to remove glib dependancy
92 // g_log (const char *log_domain,
94 // const char *format,
100 // g_logv (const char *log_domain,
102 // const char *format,
109 // Hack for XFree86 4.1.0
111 int atexit(void (*function)(void))
126 plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
127 brender_lock = new Mutex("MWindow::brender_lock");
130 channeldb_buz = new ChannelDB;
131 channeldb_v4l2jpeg = new ChannelDB;
136 brender_lock->lock("MWindow::~MWindow");
137 if(brender) delete brender;
139 brender_lock->unlock();
144 TRACE("MWindow::~MWindow 1\n");
146 TRACE("MWindow::~MWindow 2\n");
149 TRACE("MWindow::~MWindow 3\n");
150 // Give up and go to a movie
153 TRACE("MWindow::~MWindow 4\n");
155 delete audio_cache; // delete the cache after the assets
156 delete video_cache; // delete the cache after the assets
162 // delete renderlist;
167 plugin_guis->remove_all_objects();
169 delete plugin_gui_lock;
172 void MWindow::init_defaults(Defaults* &defaults, char *config_path)
174 char path[BCTEXTLEN];
175 // Use user supplied path
178 strcpy(path, config_path);
182 // set the .bcast path
185 sprintf(path, "%s", BCASTDIR);
186 fs.complete_path(path);
193 strcat(path, "Cinelerra_rc");
196 defaults = new Defaults(path);
200 void MWindow::init_plugin_path(Preferences *preferences,
201 ArrayList<PluginServer*>* &plugindb,
203 SplashGUI *splash_window,
207 PluginServer *newplugin;
211 for(int i = 0; i < fs->dir_list.total; i++)
213 char path[BCTEXTLEN];
214 strcpy(path, fs->dir_list.values[i]->path);
216 // File is a directory
217 if(!fs->is_dir(path))
223 // Try to query the plugin
224 fs->complete_path(path);
225 //printf("MWindow::init_plugin_path %s\n", path);
226 PluginServer *new_plugin = new PluginServer(path);
227 int result = new_plugin->open_plugin(1, preferences, 0, 0, -1);
231 plugindb->append(new_plugin);
232 new_plugin->close_plugin();
234 splash_window->operation->update(_(new_plugin->title));
237 if(result == PLUGINSERVER_IS_LAD)
240 // Open LAD subplugins
244 new_plugin = new PluginServer(path);
245 result = new_plugin->open_plugin(1,
253 plugindb->append(new_plugin);
254 new_plugin->close_plugin();
256 splash_window->operation->update(_(new_plugin->title));
262 // Plugin failed to open
266 if(splash_window) splash_window->progress->update((*counter)++);
271 void MWindow::init_plugins(Preferences *preferences,
272 ArrayList<PluginServer*>* &plugindb,
273 SplashGUI *splash_window)
275 plugindb = new ArrayList<PluginServer*>;
279 FileSystem cinelerra_fs;
280 ArrayList<FileSystem*> lad_fs;
284 cinelerra_fs.set_filter("[*.plugin][*.so]");
285 result = cinelerra_fs.update(preferences->global_plugin_dir);
290 _("MWindow::init_plugins: couldn't open %s directory\n"),
291 preferences->global_plugin_dir);
294 // Parse LAD environment variable
295 char *env = getenv("LADSPA_PATH");
298 char string[BCTEXTLEN];
302 char *ptr = strchr(ptr1, ':');
310 end = env + strlen(env);
315 int len = end - ptr1;
316 memcpy(string, ptr1, len);
320 FileSystem *fs = new FileSystem;
322 fs->set_filter("*.so");
323 result = fs->update(string);
328 _("MWindow::init_plugins: couldn't open %s directory\n"),
340 int total = cinelerra_fs.total_files();
342 for(int i = 0; i < lad_fs.total; i++)
343 total += lad_fs.values[i]->total_files();
344 if(splash_window) splash_window->progress->update_length(total);
348 init_plugin_path(preferences,
354 // Call automatically generated routine to get plugins
358 for(int i = 0; i < lad_fs.total; i++)
359 init_plugin_path(preferences,
365 lad_fs.remove_all_objects();
368 void MWindow::delete_plugins()
370 for(int i = 0; i < plugindb->total; i++)
372 delete plugindb->values[i];
377 void MWindow::create_plugindb(int do_audio,
382 ArrayList<PluginServer*> &plugindb)
385 for(int i = 0; i < this->plugindb->total; i++)
387 PluginServer *current = this->plugindb->values[i];
389 if(current->audio == do_audio &&
390 current->video == do_video &&
391 (current->realtime == is_realtime || is_realtime < 0) &&
392 current->transition == is_transition &&
393 current->theme == is_theme)
394 plugindb.append(current);
397 // Alphabetize list by title
403 for(int i = 0; i < plugindb.total - 1; i++)
405 PluginServer *value1 = plugindb.values[i];
406 PluginServer *value2 = plugindb.values[i + 1];
407 if(strcmp(_(value1->title), _(value2->title)) > 0)
410 plugindb.values[i] = value2;
411 plugindb.values[i + 1] = value1;
417 PluginServer* MWindow::scan_plugindb(char *title,
422 printf("MWindow::scan_plugindb data_type < 0\n");
426 for(int i = 0; i < plugindb->total; i++)
428 PluginServer *server = plugindb->values[i];
429 if(!strcasecmp(server->title, title) &&
430 ((data_type == TRACK_AUDIO && server->audio) ||
431 (data_type == TRACK_VIDEO && server->video)))
432 return plugindb->values[i];
437 void MWindow::init_preferences()
439 preferences = new Preferences;
440 preferences->load_defaults(defaults);
441 session = new MainSession(this);
442 session->load_defaults(defaults);
445 void MWindow::clean_indexes()
450 int oldest_item = -1;
452 char string[BCTEXTLEN];
453 char string2[BCTEXTLEN];
455 // Delete extra indexes
456 fs.set_filter("*.idx");
457 fs.complete_path(preferences->index_directory);
458 fs.update(preferences->index_directory);
459 //printf("MWindow::clean_indexes 1 %d\n", fs.dir_list.total);
461 // Eliminate directories
466 for(int i = 0; i < fs.dir_list.total && !result; i++)
468 fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
469 if(!fs.is_dir(string))
471 delete fs.dir_list.values[i];
472 fs.dir_list.remove_number(i);
477 total_excess = fs.dir_list.total - preferences->index_count;
479 //printf("MWindow::clean_indexes 2 %d\n", fs.dir_list.total);
480 while(total_excess > 0)
483 for(int i = 0; i < fs.dir_list.total; i++)
485 fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
487 if(i == 0 || fs.get_date(string) <= oldest)
489 oldest = fs.get_date(string);
497 fs.join_names(string,
498 preferences->index_directory,
499 fs.dir_list.values[oldest_item]->name);
500 //printf("MWindow::clean_indexes 1 %s\n", string);
502 perror("delete_indexes");
503 delete fs.dir_list.values[oldest_item];
504 fs.dir_list.remove_number(oldest_item);
506 // Remove table of contents if it exists
507 strcpy(string2, string);
508 char *ptr = strrchr(string2, '.');
511 //printf("MWindow::clean_indexes 2 %s\n", string2);
512 sprintf(ptr, ".toc");
521 void MWindow::init_awindow()
523 awindow = new AWindow(this);
524 awindow->create_objects();
527 void MWindow::init_gwindow()
529 gwindow = new GWindow(this);
530 gwindow->create_objects();
533 void MWindow::init_tipwindow()
535 twindow = new TipWindow(this);
539 void MWindow::init_theme()
543 // Replace blond theme with SUV since it doesn't work
544 if(!strcasecmp(preferences->theme, "Blond"))
545 strcpy(preferences->theme, DEFAULT_THEME);
547 for(int i = 0; i < plugindb->total; i++)
549 if(plugindb->values[i]->theme &&
550 !strcasecmp(preferences->theme, plugindb->values[i]->title))
552 PluginServer plugin = *plugindb->values[i];
553 plugin.open_plugin(0, preferences, 0, 0, -1);
554 theme = plugin.new_theme();
555 theme->mwindow = this;
556 strcpy(theme->path, plugin.path);
557 plugin.close_plugin();
563 fprintf(stderr, _("MWindow::init_theme: theme %s not found.\n"), preferences->theme);
567 // Load images which may have been forgotten
568 theme->Theme::initialize();
571 // Create menus with user colors
572 theme->build_menus();
578 void MWindow::init_edl()
581 edl->create_objects();
582 edl->load_defaults(defaults);
583 edl->create_default_tracks();
584 edl->tracks->update_y_pixels(theme);
587 void MWindow::init_compositor()
589 cwindow = new CWindow(this);
590 cwindow->create_objects();
593 void MWindow::init_levelwindow()
595 lwindow = new LevelWindow(this);
596 lwindow->create_objects();
599 void MWindow::init_viewer()
601 vwindow = new VWindow(this);
602 vwindow->load_defaults();
603 vwindow->create_objects();
606 void MWindow::init_cache()
608 audio_cache = new CICache(edl, preferences, plugindb);
609 video_cache = new CICache(edl, preferences, plugindb);
612 void MWindow::init_channeldb()
614 channeldb_buz->load("channeldb_buz");
615 channeldb_v4l2jpeg->load("channeldb_v4l2jpeg");
618 void MWindow::init_menus()
620 char string[BCTEXTLEN];
623 cmodel_to_text(string, BC_RGB888);
624 colormodels.append(new ColormodelItem(string, BC_RGB888));
625 cmodel_to_text(string, BC_RGBA8888);
626 colormodels.append(new ColormodelItem(string, BC_RGBA8888));
627 // cmodel_to_text(string, BC_RGB161616);
628 // colormodels.append(new ColormodelItem(string, BC_RGB161616));
629 // cmodel_to_text(string, BC_RGBA16161616);
630 // colormodels.append(new ColormodelItem(string, BC_RGBA16161616));
631 cmodel_to_text(string, BC_RGB_FLOAT);
632 colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT));
633 cmodel_to_text(string, BC_RGBA_FLOAT);
634 colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT));
635 cmodel_to_text(string, BC_YUV888);
636 colormodels.append(new ColormodelItem(string, BC_YUV888));
637 cmodel_to_text(string, BC_YUVA8888);
638 colormodels.append(new ColormodelItem(string, BC_YUVA8888));
639 // cmodel_to_text(string, BC_YUV161616);
640 // colormodels.append(new ColormodelItem(string, BC_YUV161616));
641 // cmodel_to_text(string, BC_YUVA16161616);
642 // colormodels.append(new ColormodelItem(string, BC_YUVA16161616));
644 #define ILACEPROJECTMODELISTADD(x) ilacemode_to_text(string, x); \
645 interlace_project_modes.append(new InterlacemodeItem(string, x));
647 #define ILACEASSETMODELISTADD(x) ilacemode_to_text(string, x); \
648 interlace_asset_modes.append(new InterlacemodeItem(string, x));
650 #define ILACEFIXMETHODLISTADD(x) ilacefixmethod_to_text(string, x); \
651 interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
654 ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
656 ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
657 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
659 ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
660 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
662 ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
663 ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
665 // Interlacing Fixing Methods
666 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
667 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
668 ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
671 void MWindow::init_indexes()
673 mainindexes = new MainIndexes(this);
674 mainindexes->start_loop();
677 void MWindow::init_gui()
679 gui = new MWindowGUI(this);
680 gui->create_objects();
681 gui->load_defaults(defaults);
684 void MWindow::init_signals()
686 sighandler = new SigHandler;
687 sighandler->initialize();
691 void MWindow::init_render()
693 render = new Render(this);
694 // renderlist = new Render(this);
695 batch_render = new BatchRenderThread(this);
698 void MWindow::init_exportedl()
700 exportedl = new ExportEDL(this);
703 void MWindow::init_brender()
705 if(preferences->use_brender && !brender)
707 brender_lock->lock("MWindow::init_brender 1");
708 brender = new BRender(this);
709 brender->initialize();
710 session->brender_end = 0;
711 brender_lock->unlock();
714 if(!preferences->use_brender && brender)
716 brender_lock->lock("MWindow::init_brender 2");
719 session->brender_end = 0;
720 brender_lock->unlock();
722 if(brender) brender->restart(edl);
725 void MWindow::restart_brender()
727 //printf("MWindow::restart_brender 1\n");
728 if(brender) brender->restart(edl);
731 void MWindow::stop_brender()
733 if(brender) brender->stop();
736 int MWindow::brender_available(int position)
739 brender_lock->lock("MWindow::brender_available 1");
742 if(brender->map_valid)
744 brender->map_lock->lock("MWindow::brender_available 2");
745 if(position < brender->map_size &&
748 //printf("MWindow::brender_available 1 %d %d\n", position, brender->map[position]);
749 if(brender->map[position] == BRender::RENDERED)
752 brender->map_lock->unlock();
755 brender_lock->unlock();
759 void MWindow::set_brender_start()
761 edl->session->brender_start = edl->local_session->get_selectionstart();
763 gui->canvas->draw_overlays();
764 gui->canvas->flash();
769 int MWindow::load_filenames(ArrayList<char*> *filenames,
776 TRACE("MWindow::load_filenames 1");
777 ArrayList<EDL*> new_edls;
778 ArrayList<Asset*> new_assets;
779 ArrayList<File*> new_files;
782 gui->start_hourglass();
784 // Need to stop playback since tracking depends on the EDL not getting
786 cwindow->playback_engine->que->send_command(STOP,
790 vwindow->playback_engine->que->send_command(STOP,
794 cwindow->playback_engine->interrupt_playback(0);
795 vwindow->playback_engine->interrupt_playback(0);
798 TRACE("MWindow::load_filenames 80");
800 // Define new_edls and new_assets to load
802 for(int i = 0; i < filenames->total; i++)
805 File *new_file = new File;
806 Asset *new_asset = new Asset(filenames->values[i]);
807 EDL *new_edl = new EDL;
808 char string[BCTEXTLEN];
810 // Set reel name and number for the asset
811 // If the user wants to overwrite the last used reel number for the clip,
812 // we have to rebuild the index for the file
816 char source_filename[BCTEXTLEN];
817 char index_filename[BCTEXTLEN];
819 strcpy(new_asset->reel_name, reel_name);
820 new_asset->reel_number = reel_number;
822 IndexFile::get_index_filename(source_filename,
823 preferences->index_directory,
826 remove(index_filename);
827 new_asset->index_status = INDEX_NOTTESTED;
830 new_edl->create_objects();
831 new_edl->copy_session(edl);
833 sprintf(string, "Loading %s", new_asset->path);
834 gui->show_message(string);
835 TRACE("MWindow::load_filenames 81");
836 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
837 TRACE("MWindow::load_filenames 82");
841 // Convert media file to EDL
843 if(load_mode != LOAD_RESOURCESONLY)
845 TRACE("MWindow::load_filenames 83");
846 asset_to_edl(new_edl, new_asset);
847 TRACE("MWindow::load_filenames 84");
848 new_edls.append(new_edl);
849 TRACE("MWindow::load_filenames 85");
852 TRACE("MWindow::load_filenames 86");
856 new_assets.append(new_asset);
859 // Set filename to nothing for assets since save EDL would overwrite them.
860 if(load_mode == LOAD_REPLACE ||
861 load_mode == LOAD_REPLACE_CONCATENATE)
864 // Reset timeline position
865 new_edl->local_session->view_start = 0;
866 new_edl->local_session->track_start = 0;
874 sprintf(string, _("Failed to open %s"), new_asset->path);
875 gui->show_message(string, theme->message_error);
880 case FILE_UNRECOGNIZED_CODEC:
883 IndexFile indexfile(this);
884 result = indexfile.open_index(this, new_asset);
887 indexfile.close_index();
890 // Test existing EDLs
893 for(int j = 0; j < new_edls.total + 1; j++)
896 if(j == new_edls.total)
898 if(old_asset = edl->assets->get_asset(new_asset->path))
900 *new_asset = *old_asset;
906 if(old_asset = new_edls.values[j]->assets->get_asset(new_asset->path))
908 *new_asset = *old_asset;
918 char string[BCTEXTLEN];
920 fs.extract_name(string, new_asset->path);
922 strcat(string, _("'s format couldn't be determined."));
923 new_asset->audio_data = 1;
924 new_asset->format = FILE_PCM;
925 new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
926 new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
927 new_asset->bits = defaults->get("AUDIO_BITS", 16);
928 new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
929 new_asset->signed_ = defaults->get("SIGNED_", 1);
930 new_asset->header = defaults->get("HEADER", 0);
932 FileFormat fwindow(this);
933 fwindow.create_objects(new_asset, string);
934 result = fwindow.run_window();
936 defaults->update("AUDIO_CHANNELS", new_asset->channels);
937 defaults->update("SAMPLE_RATE", new_asset->sample_rate);
938 defaults->update("AUDIO_BITS", new_asset->bits);
939 defaults->update("BYTE_ORDER", new_asset->byte_order);
940 defaults->update("SIGNED_", new_asset->signed_);
941 defaults->update("HEADER", new_asset->header);
948 // Recalculate length
951 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
953 if(load_mode != LOAD_RESOURCESONLY)
955 asset_to_edl(new_edl, new_asset);
956 new_edls.append(new_edl);
962 new_assets.append(new_asset);
975 xml_file.read_from_file(filenames->values[i]);
976 // Load EDL for pasting
977 new_edl->load_xml(plugindb, &xml_file, LOAD_ALL);
978 test_plugins(new_edl, filenames->values[i]);
980 // We don't want a valid reel name/number for projects
981 strcpy(new_asset->reel_name, "");
984 if(load_mode == LOAD_REPLACE ||
985 load_mode == LOAD_REPLACE_CONCATENATE)
987 strcpy(session->filename, filenames->values[i]);
988 strcpy(new_edl->local_session->clip_title, filenames->values[i]);
990 set_filename(new_edl->local_session->clip_title);
993 new_edls.append(new_edl);
999 TRACE("MWindow::load_filenames 87");
1007 TRACE("MWindow::load_filenames 88");
1009 // Store for testing index
1010 new_files.append(new_file);
1011 TRACE("MWindow::load_filenames 89");
1016 if(!result) gui->statusbar->default_message();
1020 TRACE("MWindow::load_filenames 90");
1027 // Don't back up here.
1031 // For pasting, clear the active region
1032 if(load_mode == LOAD_PASTE)
1035 double start = edl->local_session->get_selectionstart();
1037 double end = edl->local_session->get_selectionend();
1039 if(!EQUIV(start, end))
1042 edl->session->labels_follow_edits,
1043 edl->session->plugins_follow_edits);
1048 paste_edls(&new_edls,
1052 edl->session->labels_follow_edits,
1053 edl->session->plugins_follow_edits);
1062 TRACE("MWindow::load_filenames 91");
1064 if(new_assets.total)
1066 for(int i = 0; i < new_assets.total; i++)
1068 Asset *new_asset = new_assets.values[i];
1070 File *index_file = 0;
1072 for(int j = 0; j < new_files.total; j++)
1074 new_file = new_files.values[j];
1075 if(!strcmp(new_file->asset->path,
1083 mainindexes->add_next_asset(got_it ? new_file : 0,
1084 new_assets.values[i]);
1085 edl->assets->update(new_assets.values[i]);
1089 // Start examining next batch of index files
1090 mainindexes->start_build();
1093 TRACE("MWindow::load_filenames 100");
1094 update_project(load_mode);
1095 TRACE("MWindow::load_filenames 110");
1097 //printf("MWindow::load_filenames 9\n");
1100 new_edls.remove_all_objects();
1101 TRACE("MWindow::load_filenames 120\n");
1102 new_assets.remove_all_objects();
1103 TRACE("MWindow::load_filenames 130\n");
1104 new_files.remove_all_objects();
1105 TRACE("MWindow::load_filenames 140\n");
1107 undo->update_undo(_("load"), LOAD_ALL, 0);
1110 gui->stop_hourglass();
1119 void MWindow::test_plugins(EDL *new_edl, char *path)
1121 // Do a check weather plugins exist
1122 for(Track *track = new_edl->tracks->first; track; track = track->next)
1124 for(int k = 0; k < track->plugin_set.total; k++)
1126 PluginSet *plugin_set = track->plugin_set.values[k];
1127 for(Plugin *plugin = (Plugin*)plugin_set->first;
1129 plugin = (Plugin*)plugin->next)
1131 if(plugin->plugin_type == PLUGIN_STANDALONE)
1133 // ok we need to find it in plugindb
1134 int plugin_found = 0;
1135 for(int j = 0; j < plugindb->total; j++)
1137 PluginServer *server = plugindb->values[j];
1138 if(!strcasecmp(server->title, plugin->title) &&
1139 ((track->data_type == TRACK_AUDIO && server->audio) ||
1140 (track->data_type == TRACK_VIDEO && server->video)) &&
1141 (!server->transition))
1146 printf("\nWARNING: The plugin '%s' named in file '%s' is not part of your installation of Cinelerra. This means project will not be rendered as it was meant and it might result in Cinelerra crashing.\n", plugin->title, path);
1151 for(Edit *edit = (Edit*)track->edits->first;
1153 edit = (Edit*)edit->next)
1155 if (edit->transition)
1157 // ok we need to find transition in plugindb
1158 int transition_found = 0;
1159 for(int j = 0; j < plugindb->total; j++)
1161 PluginServer *server = plugindb->values[j];
1162 if(!strcasecmp(server->title, edit->transition->title) &&
1163 ((track->data_type == TRACK_AUDIO && server->audio) ||
1164 (track->data_type == TRACK_VIDEO && server->video)) &&
1165 (server->transition))
1166 transition_found = 1;
1168 if (!transition_found)
1170 printf("\nWARNING: The transition '%s' named in file '%s' is not part of your installation of Cinelerra. This means project will not be rendered as it was meant and it might result in Cinelerra crashing.\n", edit->transition->title, path);
1182 void MWindow::create_objects(int want_gui,
1186 char string[BCTEXTLEN];
1193 // For some reason, init_signals must come after show_splash or the signals won't
1198 TRACE("MWindow::create_objects 1");
1199 init_defaults(defaults, config_path);
1200 TRACE("MWindow::create_objects 2");
1202 TRACE("MWindow::create_objects 3");
1203 init_plugins(preferences, plugindb, splash_window);
1204 if(splash_window) splash_window->operation->update(_("Initializing GUI"));
1205 TRACE("MWindow::create_objects 4");
1207 // Default project created here
1208 TRACE("MWindow::create_objects 5");
1211 TRACE("MWindow::create_objects 6");
1213 TRACE("MWindow::create_objects 7");
1215 TRACE("MWindow::create_objects 8");
1217 TRACE("MWindow::create_objects 9");
1219 TRACE("MWindow::create_objects 10");
1221 TRACE("MWindow::create_objects 11");
1223 TRACE("MWindow::create_objects 12");
1225 TRACE("MWindow::create_objects 13");
1229 TRACE("MWindow::create_objects 14");
1233 mainprogress = new MainProgress(this, gui);
1234 undo = new MainUndo(this);
1236 plugin_guis = new ArrayList<PluginServer*>;
1238 TRACE("MWindow::create_objects 15");
1239 if(session->show_vwindow) vwindow->gui->show_window();
1240 if(session->show_cwindow) cwindow->gui->show_window();
1241 if(session->show_awindow) awindow->gui->show_window();
1242 if(session->show_lwindow) lwindow->gui->show_window();
1243 if(session->show_gwindow) gwindow->gui->show_window();
1244 TRACE("MWindow::create_objects 16");
1247 gui->mainmenu->load_defaults(defaults);
1248 TRACE("MWindow::create_objects 17");
1249 gui->mainmenu->update_toggles(0);
1250 TRACE("MWindow::create_objects 18");
1251 gui->patchbay->update();
1252 TRACE("MWindow::create_objects 19");
1253 gui->canvas->draw();
1254 TRACE("MWindow::create_objects 20");
1255 gui->cursor->draw();
1256 TRACE("MWindow::create_objects 21");
1258 gui->raise_window();
1260 if(preferences->use_tipwindow)
1263 TRACE("MWindow::create_objects 22");
1264 TRACE("MWindow::create_objects 23");
1271 void MWindow::show_splash()
1273 #include "data/heroine_logo12_png.h"
1274 VFrame *frame = new VFrame(heroine_logo12_png);
1275 BC_DisplayInfo display_info;
1276 splash_window = new SplashGUI(frame,
1277 display_info.get_root_w() / 2 - frame->get_w() / 2,
1278 display_info.get_root_h() / 2 - frame->get_h() / 2);
1279 splash_window->create_objects();
1282 void MWindow::hide_splash()
1285 delete splash_window;
1290 void MWindow::start()
1300 void MWindow::show_vwindow()
1302 session->show_vwindow = 1;
1303 vwindow->gui->lock_window("MWindow::show_vwindow");
1304 vwindow->gui->show_window();
1305 vwindow->gui->raise_window();
1306 vwindow->gui->flush();
1307 vwindow->gui->unlock_window();
1308 gui->mainmenu->show_vwindow->set_checked(1);
1311 void MWindow::show_awindow()
1313 session->show_awindow = 1;
1314 awindow->gui->lock_window("MWindow::show_awindow");
1315 awindow->gui->show_window();
1316 awindow->gui->raise_window();
1317 awindow->gui->flush();
1318 awindow->gui->unlock_window();
1319 gui->mainmenu->show_awindow->set_checked(1);
1322 void MWindow::show_cwindow()
1324 session->show_cwindow = 1;
1325 cwindow->show_window();
1326 gui->mainmenu->show_cwindow->set_checked(1);
1329 void MWindow::show_gwindow()
1331 session->show_gwindow = 1;
1334 gwindow->gui->lock_window("MWindow::show_gwindow");
1336 gwindow->gui->show_window();
1338 gwindow->gui->raise_window();
1340 gwindow->gui->flush();
1342 gwindow->gui->unlock_window();
1345 gui->mainmenu->show_gwindow->set_checked(1);
1349 void MWindow::show_lwindow()
1351 session->show_lwindow = 1;
1352 lwindow->gui->lock_window("MWindow::show_lwindow");
1353 lwindow->gui->show_window();
1354 lwindow->gui->raise_window();
1355 lwindow->gui->flush();
1356 lwindow->gui->unlock_window();
1357 gui->mainmenu->show_lwindow->set_checked(1);
1360 void MWindow::tile_windows()
1362 session->default_window_positions();
1363 gui->default_positions();
1366 void MWindow::toggle_loop_playback()
1368 edl->local_session->loop_playback = !edl->local_session->loop_playback;
1369 set_loop_boundaries();
1372 gui->canvas->draw_overlays();
1373 gui->canvas->flash();
1374 sync_parameters(CHANGE_PARAMS);
1377 void MWindow::set_titles(int value)
1379 edl->session->show_titles = value;
1380 trackmovement(edl->local_session->track_start);
1383 void MWindow::set_auto_keyframes(int value)
1385 gui->lock_window("MWindow::set_auto_keyframes");
1386 edl->session->auto_keyframes = value;
1387 gui->mbuttons->edit_panel->keyframe->update(value);
1389 gui->unlock_window();
1390 cwindow->gui->lock_window("MWindow::set_auto_keyframes");
1391 cwindow->gui->edit_panel->keyframe->update(value);
1392 cwindow->gui->flush();
1393 cwindow->gui->unlock_window();
1396 int MWindow::set_editing_mode(int new_editing_mode)
1398 gui->lock_window("MWindow::set_editing_mode");
1399 edl->session->editing_mode = new_editing_mode;
1400 gui->mbuttons->edit_panel->editing_mode = edl->session->editing_mode;
1401 gui->mbuttons->edit_panel->update();
1402 gui->canvas->update_cursor();
1403 gui->unlock_window();
1404 cwindow->gui->lock_window("MWindow::set_editing_mode");
1405 cwindow->gui->edit_panel->update();
1406 cwindow->gui->edit_panel->editing_mode = edl->session->editing_mode;
1407 cwindow->gui->unlock_window();
1412 void MWindow::sync_parameters(int change_type)
1415 // Sync engines which are playing back
1416 if(cwindow->playback_engine->is_playing_back)
1418 if(change_type == CHANGE_PARAMS)
1420 // TODO: block keyframes until synchronization is done
1421 cwindow->playback_engine->sync_parameters(edl);
1426 int command = cwindow->playback_engine->command->command;
1427 cwindow->playback_engine->que->send_command(STOP,
1431 // Waiting for tracking to finish would make the restart position more
1432 // accurate but it can't lock the window to stop tracking for some reason.
1433 // Not waiting for tracking gives a faster response but restart position is
1434 // only as accurate as the last tracking update.
1435 cwindow->playback_engine->interrupt_playback(0);
1436 cwindow->playback_engine->que->send_command(command,
1445 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1452 void MWindow::update_caches()
1454 audio_cache->set_edl(edl);
1455 video_cache->set_edl(edl);
1458 void MWindow::show_plugin(Plugin *plugin)
1461 //printf("MWindow::show_plugin 1\n");
1462 plugin_gui_lock->lock("MWindow::show_plugin");
1463 for(int i = 0; i < plugin_guis->total; i++)
1465 // Pointer comparison
1466 if(plugin_guis->values[i]->plugin == plugin)
1468 plugin_guis->values[i]->raise_window();
1474 //printf("MWindow::show_plugin 1\n");
1479 printf("MWindow::show_plugin track not defined.\n");
1481 PluginServer *server = scan_plugindb(plugin->title,
1482 plugin->track->data_type);
1484 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
1485 if(server && server->uses_gui)
1487 PluginServer *gui = plugin_guis->append(new PluginServer(*server));
1488 // Needs mwindow to do GUI
1489 gui->set_mwindow(this);
1490 gui->open_plugin(0, preferences, edl, plugin, -1);
1495 plugin_gui_lock->unlock();
1496 //printf("MWindow::show_plugin 2\n");
1499 void MWindow::hide_plugin(Plugin *plugin, int lock)
1501 if(lock) plugin_gui_lock->lock("MWindow::hide_plugin");
1503 for(int i = 0; i < plugin_guis->total; i++)
1505 if(plugin_guis->values[i]->plugin == plugin)
1507 PluginServer *ptr = plugin_guis->values[i];
1508 plugin_guis->remove(ptr);
1509 if(lock) plugin_gui_lock->unlock();
1510 // Last command executed in client side close
1515 if(lock) plugin_gui_lock->unlock();
1518 void MWindow::hide_plugins()
1520 plugin_gui_lock->lock("MWindow::hide_plugins");
1521 plugin_guis->remove_all_objects();
1522 plugin_gui_lock->unlock();
1525 void MWindow::update_plugin_guis()
1527 plugin_gui_lock->lock("MWindow::update_plugin_guis");
1529 for(int i = 0; i < plugin_guis->total; i++)
1531 plugin_guis->values[i]->update_gui();
1533 plugin_gui_lock->unlock();
1536 void MWindow::render_plugin_gui(void *data, Plugin *plugin)
1538 plugin_gui_lock->lock("MWindow::render_plugin_gui");
1539 for(int i = 0; i < plugin_guis->total; i++)
1541 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1543 plugin_guis->values[i]->render_gui(data);
1547 plugin_gui_lock->unlock();
1550 void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin)
1552 plugin_gui_lock->lock("MWindow::render_plugin_gui");
1553 for(int i = 0; i < plugin_guis->total; i++)
1555 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1557 plugin_guis->values[i]->render_gui(data, size);
1561 plugin_gui_lock->unlock();
1565 void MWindow::update_plugin_states()
1567 plugin_gui_lock->lock("MWindow::update_plugin_states");
1568 for(int i = 0; i < plugin_guis->total; i++)
1572 Plugin *src_plugin = plugin_guis->values[i]->plugin;
1573 PluginServer *src_plugingui = plugin_guis->values[i];
1575 // Search for plugin in EDL. Only the master EDL shows plugin GUIs.
1576 for(Track *track = edl->tracks->first;
1578 track = track->next)
1581 j < track->plugin_set.total && !result;
1584 PluginSet *plugin_set = track->plugin_set.values[j];
1585 for(Plugin *plugin = (Plugin*)plugin_set->first;
1587 plugin = (Plugin*)plugin->next)
1589 if(plugin == src_plugin &&
1590 !strcmp(plugin->title, src_plugingui->title)) result = 1;
1596 // Doesn't exist anymore
1599 hide_plugin(src_plugin, 0);
1603 plugin_gui_lock->unlock();
1607 void MWindow::update_plugin_titles()
1609 for(int i = 0; i < plugin_guis->total; i++)
1611 plugin_guis->values[i]->update_title();
1615 int MWindow::asset_to_edl(EDL *new_edl,
1617 RecordLabels *labels)
1619 //printf("MWindow::asset_to_edl 1\n");
1620 // new_edl->load_defaults(defaults);
1622 // Keep frame rate, sample rate, and output size unchanged.
1623 // These parameters would revert the project if VWindow displayed an asset
1624 // of different size than the project.
1625 if(new_asset->video_data)
1627 new_edl->session->video_tracks = new_asset->layers;
1628 // new_edl->session->frame_rate = new_asset->frame_rate;
1629 // new_edl->session->output_w = new_asset->width;
1630 // new_edl->session->output_h = new_asset->height;
1633 new_edl->session->video_tracks = 0;
1640 if(new_asset->audio_data)
1642 new_edl->session->audio_tracks = new_asset->channels;
1643 // new_edl->session->sample_rate = new_asset->sample_rate;
1646 new_edl->session->audio_tracks = 0;
1647 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1649 new_edl->create_default_tracks();
1650 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1652 // Disable drawing if the file format isn't fast enough.
1653 // MPEG is now faster than most other codecs.
1654 // if(new_asset->format == FILE_MPEG)
1656 // for(Track *current = new_edl->tracks->first;
1660 // if(current->data_type == TRACK_VIDEO) current->draw = 0;
1666 //printf("MWindow::asset_to_edl 3\n");
1667 new_edl->insert_asset(new_asset, 0, 0, labels);
1668 //printf("MWindow::asset_to_edl 3\n");
1674 char string[BCTEXTLEN];
1676 fs.extract_name(string, new_asset->path);
1677 //printf("MWindow::asset_to_edl 3\n");
1679 strcpy(new_edl->local_session->clip_title, string);
1680 //printf("MWindow::asset_to_edl 4 %s\n", string);
1686 // Reset everything after a load.
1687 void MWindow::update_project(int load_mode)
1690 //TRACE("MWindow::update_project 1");
1691 edl->tracks->update_y_pixels(theme);
1694 //TRACE("MWindow::update_project 2");
1697 TRACE("MWindow::update_project 3");
1698 gui->update(1, 1, 1, 1, 1, 1, 1);
1700 TRACE("MWindow::update_project 4");
1701 cwindow->update(0, 0, 1, 1, 1);
1703 TRACE("MWindow::update_project 5");
1705 if(load_mode == LOAD_REPLACE ||
1706 load_mode == LOAD_REPLACE_CONCATENATE)
1708 vwindow->change_source();
1715 TRACE("MWindow::update_project 6");
1717 cwindow->gui->slider->set_position();
1718 TRACE("MWindow::update_project 6.1");
1719 cwindow->gui->timebar->update(1, 1);
1720 TRACE("MWindow::update_project 6.2");
1721 cwindow->playback_engine->que->send_command(CURRENT_FRAME,
1726 TRACE("MWindow::update_project 7");
1727 awindow->gui->lock_window("MWindow::update_project");
1728 awindow->gui->update_assets();
1729 awindow->gui->flush();
1730 awindow->gui->unlock_window();
1732 TRACE("MWindow::update_project 100");
1736 void MWindow::rebuild_indices()
1738 char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
1740 for(int i = 0; i < session->drag_assets->total; i++)
1742 //printf("MWindow::rebuild_indices 1 %s\n", session->drag_assets->values[i]->path);
1744 IndexFile::get_index_filename(source_filename,
1745 preferences->index_directory,
1747 session->drag_assets->values[i]->path);
1748 remove(index_filename);
1749 // Schedule index build
1750 session->drag_assets->values[i]->index_status = INDEX_NOTTESTED;
1751 mainindexes->add_next_asset(0, session->drag_assets->values[i]);
1753 mainindexes->start_build();
1757 void MWindow::save_backup()
1760 edl->set_project_path(session->filename);
1761 edl->save_xml(plugindb,
1766 file.terminate_string();
1767 char path[BCTEXTLEN];
1769 strcpy(path, BACKUP_PATH);
1770 fs.complete_path(path);
1772 if(file.write_to_file(path))
1775 sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
1776 gui->show_message(string2);
1781 int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
1784 if(!width || !height) return 1;
1785 float fraction = (float)width / height;
1787 for(denominator = 1;
1788 denominator < 100 &&
1789 fabs(fraction * denominator - (int)(fraction * denominator)) > .001;
1793 w = denominator * width / height;
1800 void MWindow::remove_assets_from_project(int push_undo)
1802 // Remove from caches
1803 for(int i = 0; i < session->drag_assets->total; i++)
1805 audio_cache->delete_entry(session->drag_assets->values[i]);
1806 video_cache->delete_entry(session->drag_assets->values[i]);
1809 printf("MWindow::remove_assets_from_project 1\n");
1810 video_cache->dump();
1811 audio_cache->dump();
1812 printf("MWindow::remove_assets_from_project 100\n");
1814 // Remove from VWindow.
1815 for(int i = 0; i < session->drag_clips->total; i++)
1817 if(session->drag_clips->values[i] == vwindow->get_edl())
1819 vwindow->gui->lock_window("MWindow::remove_assets_from_project 1");
1820 vwindow->remove_source();
1821 vwindow->gui->unlock_window();
1825 for(int i = 0; i < session->drag_assets->total; i++)
1827 if(session->drag_assets->values[i] == vwindow->get_asset())
1829 vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
1830 vwindow->remove_source();
1831 vwindow->gui->unlock_window();
1835 edl->remove_from_project(session->drag_assets);
1836 edl->remove_from_project(session->drag_clips);
1838 if(push_undo) undo->update_undo(_("remove assets"), LOAD_ALL);
1841 gui->lock_window("MWindow::remove_assets_from_project 3");
1849 gui->unlock_window();
1851 awindow->gui->lock_window("MWindow::remove_assets_from_project 4");
1852 awindow->gui->update_assets();
1853 awindow->gui->flush();
1854 awindow->gui->unlock_window();
1856 // Removes from playback here
1857 sync_parameters(CHANGE_ALL);
1860 void MWindow::remove_assets_from_disk()
1863 for(int i = 0; i < session->drag_assets->total; i++)
1865 remove(session->drag_assets->values[i]->path);
1868 remove_assets_from_project(1);
1871 void MWindow::dump_plugins()
1873 for(int i = 0; i < plugindb->total; i++)
1875 printf("audio=%d video=%d realtime=%d transition=%d theme=%d %s\n",
1876 plugindb->values[i]->audio,
1877 plugindb->values[i]->video,
1878 plugindb->values[i]->realtime,
1879 plugindb->values[i]->transition,
1880 plugindb->values[i]->theme,
1881 plugindb->values[i]->title);
1909 int MWindow::save_defaults()
1911 gui->save_defaults(defaults);
1912 edl->save_defaults(defaults);
1913 session->save_defaults(defaults);
1914 preferences->save_defaults(defaults);
1920 int MWindow::run_script(FileXML *script)
1922 int result = 0, result2 = 0;
1923 while(!result && !result2)
1925 result = script->read_tag();
1928 if(script->tag.title_is("new_project"))
1930 // Run new in immediate mode.
1931 // gui->mainmenu->new_project->run_script(script);
1934 if(script->tag.title_is("record"))
1936 // Run record as a thread. It is a terminal command.
1938 // Will read the complete scipt file without letting record read it if not
1944 printf("MWindow::run_script: Unrecognized command: %s\n",script->tag.get_title() );
1951 // ================================= synchronization
1954 int MWindow::interrupt_indexes()
1956 mainindexes->interrupt_build();
1962 void MWindow::next_time_format()
1964 switch(edl->session->time_format)
1966 case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
1967 case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
1968 case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1969 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
1970 case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
1971 case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
1972 case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
1975 time_format_common();
1978 void MWindow::prev_time_format()
1980 switch(edl->session->time_format)
1982 case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
1983 case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
1984 case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
1985 case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1986 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
1987 case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
1988 case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
1991 time_format_common();
1994 void MWindow::time_format_common()
1996 gui->lock_window("MWindow::next_time_format");
1997 gui->redraw_time_dependancies();
1998 char string[BCTEXTLEN], string2[BCTEXTLEN];
1999 sprintf(string, _("Using %s."), Units::print_time_format(edl->session->time_format, string2));
2000 gui->show_message(string);
2002 gui->unlock_window();
2006 int MWindow::set_filename(char *filename)
2008 strcpy(session->filename, filename);
2011 if(filename[0] == 0)
2013 gui->set_title(PROGRAM_NAME);
2018 char string[BCTEXTLEN], string2[BCTEXTLEN];
2019 dir.extract_name(string, filename);
2020 sprintf(string2, PROGRAM_NAME ": %s", string);
2021 gui->set_title(string2);
2034 int MWindow::set_loop_boundaries()
2036 double start = edl->local_session->get_selectionstart();
2037 double end = edl->local_session->get_selectionend();
2045 if(edl->tracks->total_length())
2048 end = edl->tracks->total_length();
2055 if(edl->local_session->loop_playback && start != end)
2057 edl->local_session->loop_start = start;
2058 edl->local_session->loop_end = end;
2069 int MWindow::reset_meters()
2071 cwindow->gui->lock_window("MWindow::reset_meters 1");
2072 cwindow->gui->meters->reset_meters();
2073 cwindow->gui->unlock_window();
2075 vwindow->gui->lock_window("MWindow::reset_meters 2");
2076 vwindow->gui->meters->reset_meters();
2077 vwindow->gui->unlock_window();
2079 lwindow->gui->lock_window("MWindow::reset_meters 3");
2080 lwindow->gui->panel->reset_meters();
2081 lwindow->gui->unlock_window();
2083 gui->lock_window("MWindow::reset_meters 4");
2084 gui->patchbay->reset_meters();
2085 gui->unlock_window();