r851: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / mwindow.C
blob630c492faf69b18c50de0fa5bffc03f3592eeb7f
1 #include "asset.h"
2 #include "assets.h"
3 #include "awindowgui.h"
4 #include "awindow.h"
5 #include "batchrender.h"
6 #include "bcdisplayinfo.h"
7 #include "bcsignals.h"
8 #include "brender.h"
9 #include "cache.h"
10 #include "channel.h"
11 #include "channeldb.h"
12 #include "clip.h"
13 #include "colormodels.h"
14 #include "cplayback.h"
15 #include "ctimebar.h"
16 #include "cwindowgui.h"
17 #include "cwindow.h"
18 #include "bchash.h"
19 #include "editpanel.h"
20 #include "edl.h"
21 #include "edlsession.h"
22 #include "errorbox.h"
23 #include "fileformat.h"
24 #include "file.h"
25 #include "filesystem.h"
26 #include "filexml.h"
27 #include "gwindow.h"
28 #include "gwindowgui.h"
29 #include "indexfile.h"
30 #include "interlacemodes.h"
31 #include "language.h"
32 #include "levelwindowgui.h"
33 #include "levelwindow.h"
34 #include "loadfile.inc"
35 #include "localsession.h"
36 #include "maincursor.h"
37 #include "mainindexes.h"
38 #include "mainmenu.h"
39 #include "mainprogress.h"
40 #include "mainsession.h"
41 #include "mainundo.h"
42 #include "mbuttons.h"
43 #include "mutex.h"
44 #include "mwindowgui.h"
45 #include "mwindow.h"
46 #include "new.h"
47 #include "patchbay.h"
48 #include "playbackengine.h"
49 #include "plugin.h"
50 #include "pluginserver.h"
51 #include "pluginset.h"
52 #include "preferences.h"
53 #include "record.h"
54 #include "recordlabel.h"
55 #include "render.h"
56 #include "samplescroll.h"
57 #include "sighandler.h"
58 #include "splashgui.h"
59 #include "statusbar.h"
60 #include "theme.h"
61 #include "threadloader.h"
62 #include "timebar.h"
63 #include "tipwindow.h"
64 #include "trackcanvas.h"
65 #include "track.h"
66 #include "tracking.h"
67 #include "trackscroll.h"
68 #include "tracks.h"
69 #include "transition.h"
70 #include "transportque.h"
71 #include "vframe.h"
72 #include "videodevice.inc"
73 #include "videowindow.h"
74 #include "vplayback.h"
75 #include "vwindowgui.h"
76 #include "vwindow.h"
77 #include "zoombar.h"
78 #include "exportedl.h"
80 #include <string.h>
84 extern "C"
90 // Hack for libdv to remove glib dependancy
92 // void
93 // g_log (const char    *log_domain,
94 //        int  log_level,
95 //        const char    *format,
96 //        ...)
97 // {
98 // }
99 // 
100 // void
101 // g_logv (const char    *log_domain,
102 //        int  log_level,
103 //        const char    *format,
104 //        ...)
105 // {
106 // }
107 // 
110 // Hack for XFree86 4.1.0
112 int atexit(void (*function)(void))
114         return 0;
123 MWindow::MWindow()
125         plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
126         brender_lock = new Mutex("MWindow::brender_lock");
127         brender = 0;
128         session = 0;
129         channeldb_buz = new ChannelDB;
130         channeldb_v4l2jpeg = new ChannelDB;
133 MWindow::~MWindow()
135         brender_lock->lock("MWindow::~MWindow");
136         if(brender) delete brender;
137         brender = 0;
138         brender_lock->unlock();
139         delete brender_lock;
141         delete mainindexes;
143 SET_TRACE
144         clean_indexes();
145 SET_TRACE
147         save_defaults();
148 SET_TRACE
149 // Give up and go to a movie
150         exit(0);
152 SET_TRACE
153         delete mainprogress;
154         delete audio_cache;             // delete the cache after the assets
155         delete video_cache;             // delete the cache after the assets
156         if(gui) delete gui;
157         delete undo;
158         delete preferences;
159         delete defaults;
160         delete render;
161 //      delete renderlist;
162         delete awindow;
163         delete vwindow;
164         delete cwindow;
165         delete lwindow;
166         plugin_guis->remove_all_objects();
167         delete plugin_guis;
168         delete plugin_gui_lock;
171 void MWindow::create_defaults_path(char *string)
173 // set the .bcast path
174         FileSystem fs;
176         sprintf(string, "%s", BCASTDIR);
177         fs.complete_path(string);
178         if(!fs.is_dir(string)) 
179         {
180                 fs.create_dir(string); 
181         }
183 // load the defaults
184         strcat(string, "Cinelerra_rc");
187 void MWindow::init_defaults(BC_Hash* &defaults, char *config_path)
189         char path[BCTEXTLEN];
190 // Use user supplied path
191         if(config_path[0])
192         {
193                 strcpy(path, config_path);
194         }
195         else
196         {
197                 create_defaults_path(path);
198         }
200         defaults = new BC_Hash(path);
201         defaults->load();
204 void MWindow::init_plugin_path(Preferences *preferences, 
205         ArrayList<PluginServer*>* &plugindb,
206         FileSystem *fs,
207         SplashGUI *splash_window,
208         int *counter)
210         int result = 0;
211         PluginServer *newplugin;
213         if(!result)
214         {
215                 for(int i = 0; i < fs->dir_list.total; i++)
216                 {
217                         char path[BCTEXTLEN];
218                         strcpy(path, fs->dir_list.values[i]->path);
220 // File is a directory
221                         if(!fs->is_dir(path))
222                         {
223                                 continue;
224                         }
225                         else
226                         {
227 // Try to query the plugin
228                                 fs->complete_path(path);
229 //printf("MWindow::init_plugin_path %s\n", path);
230                                 PluginServer *new_plugin = new PluginServer(path);
231                                 int result = new_plugin->open_plugin(1, preferences, 0, 0, -1);
233                                 if(!result)
234                                 {
235                                         plugindb->append(new_plugin);
236                                         new_plugin->close_plugin();
237                                         if(splash_window)
238                                                 splash_window->operation->update(_(new_plugin->title));
239                                 }
240                                 else
241                                 if(result == PLUGINSERVER_IS_LAD)
242                                 {
243                                         delete new_plugin;
244 // Open LAD subplugins
245                                         int id = 0;
246                                         do
247                                         {
248                                                 new_plugin = new PluginServer(path);
249                                                 result = new_plugin->open_plugin(1,
250                                                         preferences,
251                                                         0,
252                                                         0,
253                                                         id);
254                                                 id++;
255                                                 if(!result)
256                                                 {
257                                                         plugindb->append(new_plugin);
258                                                         new_plugin->close_plugin();
259                                                         if(splash_window)
260                                                                 splash_window->operation->update(_(new_plugin->title));
261                                                         else
262                                                         {
263                                                         }
264                                                 }
265                                         }while(!result);
266                                 }
267                                 else
268                                 {
269 // Plugin failed to open
270                                         delete new_plugin;
271                                 }
272                         }
274                         if(splash_window) splash_window->progress->update((*counter)++);
275                 }
276         }
279 void MWindow::init_plugins(Preferences *preferences, 
280         ArrayList<PluginServer*>* &plugindb,
281         SplashGUI *splash_window)
283         plugindb = new ArrayList<PluginServer*>;
287         FileSystem cinelerra_fs;
288         ArrayList<FileSystem*> lad_fs;
289         int result = 0;
291 // Get directories
292         cinelerra_fs.set_filter("[*.plugin][*.so]");
293         result = cinelerra_fs.update(preferences->global_plugin_dir);
295         if(result)
296         {
297                 fprintf(stderr, 
298                         _("MWindow::init_plugins: couldn't open %s directory\n"),
299                         preferences->global_plugin_dir);
300         }
302 // Parse LAD environment variable
303         char *env = getenv("LADSPA_PATH");
304         if(env)
305         {
306                 char string[BCTEXTLEN];
307                 char *ptr1 = env;
308                 while(ptr1)
309                 {
310                         char *ptr = strchr(ptr1, ':');
311                         char *end;
312                         if(ptr)
313                         {
314                                 end = ptr;
315                         }
316                         else
317                         {
318                                 end = env + strlen(env);
319                         }
321                         if(end > ptr1)
322                         {
323                                 int len = end - ptr1;
324                                 memcpy(string, ptr1, len);
325                                 string[len] = 0;
328                                 FileSystem *fs = new FileSystem;
329                                 lad_fs.append(fs);
330                                 fs->set_filter("*.so");
331                                 result = fs->update(string);
333                                 if(result)
334                                 {
335                                         fprintf(stderr, 
336                                                 _("MWindow::init_plugins: couldn't open %s directory\n"),
337                                                 string);
338                                 }
339                         }
341                         if(ptr)
342                                 ptr1 = ptr + 1;
343                         else
344                                 ptr1 = ptr;
345                 };
346         }
348         int total = cinelerra_fs.total_files();
349         int counter = 0;
350         for(int i = 0; i < lad_fs.total; i++)
351                 total += lad_fs.values[i]->total_files();
352         if(splash_window) splash_window->progress->update_length(total);
355 // Cinelerra
356 #ifndef DO_STATIC
357         init_plugin_path(preferences,
358                 plugindb,
359                 &cinelerra_fs,
360                 splash_window,
361                 &counter);
362 #else
363 // Call automatically generated routine to get plugins
364 #endif
366 // LAD
367         for(int i = 0; i < lad_fs.total; i++)
368                 init_plugin_path(preferences,
369                         plugindb,
370                         lad_fs.values[i],
371                         splash_window,
372                         &counter);
374         lad_fs.remove_all_objects();
377 void MWindow::delete_plugins()
379         for(int i = 0; i < plugindb->total; i++)
380         {
381                 delete plugindb->values[i];
382         }
383         delete plugindb;
386 void MWindow::create_plugindb(int do_audio, 
387                 int do_video, 
388                 int is_realtime, 
389                 int is_transition,
390                 int is_theme,
391                 ArrayList<PluginServer*> &plugindb)
393 // Get plugins
394         for(int i = 0; i < this->plugindb->total; i++)
395         {
396                 PluginServer *current = this->plugindb->values[i];
398                 if(current->audio == do_audio &&
399                         current->video == do_video &&
400                         (current->realtime == is_realtime || is_realtime < 0) &&
401                         current->transition == is_transition &&
402                         current->theme == is_theme)
403                         plugindb.append(current);
404         }
406 // Alphabetize list by title
407         int done = 0;
408         while(!done)
409         {
410                 done = 1;
411                 
412                 for(int i = 0; i < plugindb.total - 1; i++)
413                 {
414                         PluginServer *value1 = plugindb.values[i];
415                         PluginServer *value2 = plugindb.values[i + 1];
416                         if(strcmp(_(value1->title), _(value2->title)) > 0)
417                         {
418                                 done = 0;
419                                 plugindb.values[i] = value2;
420                                 plugindb.values[i + 1] = value1;
421                         }
422                 }
423         }
426 PluginServer* MWindow::scan_plugindb(char *title,
427                 int data_type)
429         if(data_type < 0)
430         {
431                 printf("MWindow::scan_plugindb data_type < 0\n");
432                 return 0;
433         }
435         for(int i = 0; i < plugindb->total; i++)
436         {
437                 PluginServer *server = plugindb->values[i];
438                 if(!strcasecmp(server->title, title) &&
439                 ((data_type == TRACK_AUDIO && server->audio) ||
440                 (data_type == TRACK_VIDEO && server->video))) 
441                         return plugindb->values[i];
442         }
443         return 0;
446 void MWindow::init_preferences()
448         preferences = new Preferences;
449         preferences->load_defaults(defaults);
450         session = new MainSession(this);
451         session->load_defaults(defaults);
454 void MWindow::clean_indexes()
456         FileSystem fs;
457         int total_excess;
458         long oldest;
459         int oldest_item = -1;
460         int result;
461         char string[BCTEXTLEN];
462         char string2[BCTEXTLEN];
464 // Delete extra indexes
465         fs.set_filter("*.idx");
466         fs.complete_path(preferences->index_directory);
467         fs.update(preferences->index_directory);
468 //printf("MWindow::clean_indexes 1 %d\n", fs.dir_list.total);
470 // Eliminate directories
471         result = 1;
472         while(result)
473         {
474                 result = 0;
475                 for(int i = 0; i < fs.dir_list.total && !result; i++)
476                 {
477                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
478                         if(!fs.is_dir(string))
479                         {
480                                 delete fs.dir_list.values[i];
481                                 fs.dir_list.remove_number(i);
482                                 result = 1;
483                         }
484                 }
485         }
486         total_excess = fs.dir_list.total - preferences->index_count;
488 //printf("MWindow::clean_indexes 2 %d\n", fs.dir_list.total);
489         while(total_excess > 0)
490         {
491 // Get oldest
492                 for(int i = 0; i < fs.dir_list.total; i++)
493                 {
494                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
496                         if(i == 0 || fs.get_date(string) <= oldest)
497                         {
498                                 oldest = fs.get_date(string);
499                                 oldest_item = i;
500                         }
501                 }
503                 if(oldest_item >= 0)
504                 {
505 // Remove index file
506                         fs.join_names(string, 
507                                 preferences->index_directory, 
508                                 fs.dir_list.values[oldest_item]->name);
509 //printf("MWindow::clean_indexes 1 %s\n", string);
510                         if(remove(string))
511                                 perror("delete_indexes");
512                         delete fs.dir_list.values[oldest_item];
513                         fs.dir_list.remove_number(oldest_item);
515 // Remove table of contents if it exists
516                         strcpy(string2, string);
517                         char *ptr = strrchr(string2, '.');
518                         if(ptr)
519                         {
520 //printf("MWindow::clean_indexes 2 %s\n", string2);
521                                 sprintf(ptr, ".toc");
522                                 remove(string2);
523                         }
524                 }
526                 total_excess--;
527         }
530 void MWindow::init_awindow()
532         awindow = new AWindow(this);
533         awindow->create_objects();
536 void MWindow::init_gwindow()
538         gwindow = new GWindow(this);
539         gwindow->create_objects();
542 void MWindow::init_tipwindow()
544         twindow = new TipWindow(this);
545         twindow->start();
548 void MWindow::init_theme()
550         theme = 0;
552 // Replace blond theme with SUV since it doesn't work
553         if(!strcasecmp(preferences->theme, "Blond"))
554                 strcpy(preferences->theme, DEFAULT_THEME);
556         for(int i = 0; i < plugindb->total; i++)
557         {
558                 if(plugindb->values[i]->theme &&
559                         !strcasecmp(preferences->theme, plugindb->values[i]->title))
560                 {
561                         PluginServer plugin = *plugindb->values[i];
562                         plugin.open_plugin(0, preferences, 0, 0, -1);
563                         theme = plugin.new_theme();
564                         theme->mwindow = this;
565                         strcpy(theme->path, plugin.path);
566                         plugin.close_plugin();
567                 }
568         }
570         if(!theme)
571         {
572                 fprintf(stderr, _("MWindow::init_theme: theme %s not found.\n"), preferences->theme);
573                 exit(1);
574         }
576 // Load images which may have been forgotten
577         theme->Theme::initialize();
578 // Load user images
579         theme->initialize();
580 // Create menus with user colors
581         theme->build_menus();
582         init_menus();
584         theme->check_used();
587 void MWindow::init_edl()
589         edl = new EDL;
590         edl->create_objects();
591     edl->load_defaults(defaults);
592         edl->create_default_tracks();
593         edl->tracks->update_y_pixels(theme);
596 void MWindow::init_compositor()
598         cwindow = new CWindow(this);
599     cwindow->create_objects();
602 void MWindow::init_levelwindow()
604         lwindow = new LevelWindow(this);
605         lwindow->create_objects();
608 void MWindow::init_viewer()
610         vwindow = new VWindow(this);
611         vwindow->load_defaults();
612         vwindow->create_objects();
615 void MWindow::init_cache()
617         audio_cache = new CICache(edl, preferences, plugindb);
618         video_cache = new CICache(edl, preferences, plugindb);
621 void MWindow::init_channeldb()
623         channeldb_buz->load("channeldb_buz");
624         channeldb_v4l2jpeg->load("channeldb_v4l2jpeg");
627 void MWindow::init_menus()
629         char string[BCTEXTLEN];
631         // Color Models
632         cmodel_to_text(string, BC_RGB888);
633         colormodels.append(new ColormodelItem(string, BC_RGB888));
634         cmodel_to_text(string, BC_RGBA8888);
635         colormodels.append(new ColormodelItem(string, BC_RGBA8888));
636 //      cmodel_to_text(string, BC_RGB161616);
637 //      colormodels.append(new ColormodelItem(string, BC_RGB161616));
638 //      cmodel_to_text(string, BC_RGBA16161616);
639 //      colormodels.append(new ColormodelItem(string, BC_RGBA16161616));
640         cmodel_to_text(string, BC_RGB_FLOAT);
641         colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT));
642         cmodel_to_text(string, BC_RGBA_FLOAT);
643         colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT));
644         cmodel_to_text(string, BC_YUV888);
645         colormodels.append(new ColormodelItem(string, BC_YUV888));
646         cmodel_to_text(string, BC_YUVA8888);
647         colormodels.append(new ColormodelItem(string, BC_YUVA8888));
648 //      cmodel_to_text(string, BC_YUV161616);
649 //      colormodels.append(new ColormodelItem(string, BC_YUV161616));
650 //      cmodel_to_text(string, BC_YUVA16161616);
651 //      colormodels.append(new ColormodelItem(string, BC_YUVA16161616));
653 #define ILACEPROJECTMODELISTADD(x) ilacemode_to_text(string, x); \
654                            interlace_project_modes.append(new InterlacemodeItem(string, x));
656 #define ILACEASSETMODELISTADD(x) ilacemode_to_text(string, x); \
657                            interlace_asset_modes.append(new InterlacemodeItem(string, x));
659 #define ILACEFIXMETHODLISTADD(x) ilacefixmethod_to_text(string, x); \
660                            interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
662         // Interlacing Modes
663         ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
665         ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
666         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
668         ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
669         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
671         ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
672         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
674         // Interlacing Fixing Methods
675         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
676         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
677         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
680 void MWindow::init_indexes()
682         mainindexes = new MainIndexes(this);
683         mainindexes->start_loop();
686 void MWindow::init_gui()
688         gui = new MWindowGUI(this);
689         gui->create_objects();
690         gui->load_defaults(defaults);
693 void MWindow::init_signals()
695         sighandler = new SigHandler;
696         sighandler->initialize();
697 ENABLE_BUFFER
700 void MWindow::init_render()
702         render = new Render(this);
703 //      renderlist = new Render(this);
704         batch_render = new BatchRenderThread(this);
707 void MWindow::init_exportedl()
709         exportedl = new ExportEDL(this);
712 void MWindow::init_brender()
714         if(preferences->use_brender && !brender)
715         {
716                 brender_lock->lock("MWindow::init_brender 1");
717                 brender = new BRender(this);
718                 brender->initialize();
719                 session->brender_end = 0;
720                 brender_lock->unlock();
721         }
722         else
723         if(!preferences->use_brender && brender)
724         {
725                 brender_lock->lock("MWindow::init_brender 2");
726                 delete brender;
727                 brender = 0;
728                 session->brender_end = 0;
729                 brender_lock->unlock();
730         }
731         if(brender) brender->restart(edl);
734 void MWindow::restart_brender()
736 //printf("MWindow::restart_brender 1\n");
737         if(brender) brender->restart(edl);
740 void MWindow::stop_brender()
742         if(brender) brender->stop();
745 int MWindow::brender_available(int position)
747         int result = 0;
748         brender_lock->lock("MWindow::brender_available 1");
749         if(brender)
750         {
751                 if(brender->map_valid)
752                 {
753                         brender->map_lock->lock("MWindow::brender_available 2");
754                         if(position < brender->map_size &&
755                                 position >= 0)
756                         {
757 //printf("MWindow::brender_available 1 %d %d\n", position, brender->map[position]);
758                                 if(brender->map[position] == BRender::RENDERED)
759                                         result = 1;
760                         }
761                         brender->map_lock->unlock();
762                 }
763         }
764         brender_lock->unlock();
765         return result;
768 void MWindow::set_brender_start()
770         edl->session->brender_start = edl->local_session->get_selectionstart();
771         restart_brender();
772         gui->canvas->draw_overlays();
773         gui->canvas->flash();
778 int MWindow::load_filenames(ArrayList<char*> *filenames, 
779         int load_mode,
780         int update_filename,
781         char *reel_name,
782         int reel_number,
783         int overwrite_reel)
785 SET_TRACE
786         ArrayList<EDL*> new_edls;
787         ArrayList<Asset*> new_assets;
788         ArrayList<File*> new_files;
790         save_defaults();
791         gui->start_hourglass();
793 // Need to stop playback since tracking depends on the EDL not getting
794 // deleted.
795         cwindow->playback_engine->que->send_command(STOP,
796                 CHANGE_NONE, 
797                 0,
798                 0);
799         vwindow->playback_engine->que->send_command(STOP,
800                 CHANGE_NONE, 
801                 0,
802                 0);
803         cwindow->playback_engine->interrupt_playback(0);
804         vwindow->playback_engine->interrupt_playback(0);
808 // Define new_edls and new_assets to load
809         int result = 0;
810         for(int i = 0; i < filenames->total; i++)
811         {
812 // Get type of file
813                 File *new_file = new File;
814                 Asset *new_asset = new Asset(filenames->values[i]);
815                 EDL *new_edl = new EDL;
816                 char string[BCTEXTLEN];
818 // Set reel name and number for the asset
819 // If the user wants to overwrite the last used reel number for the clip,
820 // we have to rebuild the index for the file
822                 if(overwrite_reel)
823                 {
824                         char source_filename[BCTEXTLEN];
825                         char index_filename[BCTEXTLEN];
826                         
827                         strcpy(new_asset->reel_name, reel_name);
828                         new_asset->reel_number = reel_number;
830                         IndexFile::get_index_filename(source_filename,
831                                 preferences->index_directory,
832                                 index_filename,
833                                 new_asset->path);
834                         remove(index_filename);
835                         new_asset->index_status = INDEX_NOTTESTED;
836                 }
837                 
838                 new_edl->create_objects();
839                 new_edl->copy_session(edl);
841                 sprintf(string, "Loading %s", new_asset->path);
842                 gui->show_message(string);
843 SET_TRACE
844                 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
845 SET_TRACE
847                 switch(result)
848                 {
849 // Convert media file to EDL
850                         case FILE_OK:
851                                 if(load_mode != LOAD_RESOURCESONLY)
852                                 {
853 SET_TRACE
854                                         asset_to_edl(new_edl, new_asset);
855 SET_TRACE
856                                         new_edls.append(new_edl);
857 SET_TRACE
858                                         delete new_asset;
859                                         new_asset = 0;
860 SET_TRACE
861                                 }
862                                 else
863                                 {
864                                         new_assets.append(new_asset);
865                                 }
867 // Set filename to nothing for assets since save EDL would overwrite them.
868                                 if(load_mode == LOAD_REPLACE || 
869                                         load_mode == LOAD_REPLACE_CONCATENATE)
870                                 {
871                                         set_filename("");
872 // Reset timeline position
873                                         new_edl->local_session->view_start = 0;
874                                         new_edl->local_session->track_start = 0;
875                                 }
877                                 result = 0;
878                                 break;
880 // File not found
881                         case FILE_NOT_FOUND:
882                                 sprintf(string, _("Failed to open %s"), new_asset->path);
883                                 gui->show_message(string, theme->message_error);
884                                 result = 1;
885                                 break;
887 // Unknown format
888                         case FILE_UNRECOGNIZED_CODEC:
889                         {
890 // Test index file
891                                 IndexFile indexfile(this);
892                                 result = indexfile.open_index(this, new_asset);
893                                 if(!result)
894                                 {
895                                         indexfile.close_index();
896                                 }
898 // Test existing EDLs
899                                 if(result)
900                                 {
901                                         for(int j = 0; j < new_edls.total + 1; j++)
902                                         {
903                                                 Asset *old_asset;
904                                                 if(j == new_edls.total)
905                                                 {
906                                                         if(old_asset = edl->assets->get_asset(new_asset->path))
907                                                         {
908                                                                 *new_asset = *old_asset;
909                                                                 result = 0;
910                                                         }
911                                                 }
912                                                 else
913                                                 {
914                                                         if(old_asset = new_edls.values[j]->assets->get_asset(new_asset->path))
915                                                         {
916                                                                 *new_asset = *old_asset;
917                                                                 result = 0;
918                                                         }
919                                                 }
920                                         }
921                                 }
923 // Prompt user
924                                 if(result)
925                                 {
926                                         char string[BCTEXTLEN];
927                                         FileSystem fs;
928                                         fs.extract_name(string, new_asset->path);
930                                         strcat(string, _("'s format couldn't be determined."));
931                                         new_asset->audio_data = 1;
932                                         new_asset->format = FILE_PCM;
933                                         new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
934                                         new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
935                                         new_asset->bits = defaults->get("AUDIO_BITS", 16);
936                                         new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
937                                         new_asset->signed_ = defaults->get("SIGNED_", 1);
938                                         new_asset->header = defaults->get("HEADER", 0);
940                                         FileFormat fwindow(this);
941                                         fwindow.create_objects(new_asset, string);
942                                         result = fwindow.run_window();
944                                         defaults->update("AUDIO_CHANNELS", new_asset->channels);
945                                         defaults->update("SAMPLE_RATE", new_asset->sample_rate);
946                                         defaults->update("AUDIO_BITS", new_asset->bits);
947                                         defaults->update("BYTE_ORDER", new_asset->byte_order);
948                                         defaults->update("SIGNED_", new_asset->signed_);
949                                         defaults->update("HEADER", new_asset->header);
950                                         save_defaults();
951                                 }
953 // Append to list
954                                 if(!result)
955                                 {
956 // Recalculate length
957                                         delete new_file;
958                                         new_file = new File;
959                                         result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
961                                         if(load_mode != LOAD_RESOURCESONLY)
962                                         {
963                                                 asset_to_edl(new_edl, new_asset);
964                                                 new_edls.append(new_edl);
965                                                 delete new_asset;
966                                                 new_asset = 0;
967                                         }
968                                         else
969                                         {
970                                                 new_assets.append(new_asset);
971                                         }
972                                 }
973                                 else
974                                 {
975                                         result = 1;
976                                 }
977                                 break;
978                         }
980                         case FILE_IS_XML:
981                         {
982                                 FileXML xml_file;
983                                 xml_file.read_from_file(filenames->values[i]);
984 // Load EDL for pasting
985                                 new_edl->load_xml(plugindb, &xml_file, LOAD_ALL);
986                                 test_plugins(new_edl, filenames->values[i]);
988 // We don't want a valid reel name/number for projects
989                                 strcpy(new_asset->reel_name, "");
990                                 reel_number = -1;
992                                 if(load_mode == LOAD_REPLACE || 
993                                         load_mode == LOAD_REPLACE_CONCATENATE)
994                                 {
995                                         strcpy(session->filename, filenames->values[i]);
996                                         strcpy(new_edl->local_session->clip_title, filenames->values[i]);
997                                         if(update_filename)
998                                                 set_filename(new_edl->local_session->clip_title);
999                                 }
1001                                 new_edls.append(new_edl);
1002                                 result = 0;
1003                                 break;
1004                         }
1005                 }
1007 SET_TRACE
1008                 if(result)
1009                 {
1010                         delete new_edl;
1011                         delete new_asset;
1012                         new_edl = 0;
1013                         new_asset = 0;
1014                 }
1015 SET_TRACE
1017 // Store for testing index
1018                 new_files.append(new_file);
1019 SET_TRACE
1020         }
1024         if(!result) gui->statusbar->default_message();
1033 // Paste them.
1034 // Don't back up here.
1035         if(new_edls.total)
1036         {
1037 // For pasting, clear the active region
1038                 if(load_mode == LOAD_PASTE)
1039                 {
1040                         double start = edl->local_session->get_selectionstart();
1041                         double end = edl->local_session->get_selectionend();
1042                         if(!EQUIV(start, end))
1043                                 edl->clear(start, 
1044                                         end,
1045                                         edl->session->labels_follow_edits,
1046                                         edl->session->plugins_follow_edits);
1047                 }
1049                 paste_edls(&new_edls, 
1050                         load_mode,
1051                         0,
1052                         -1,
1053                         edl->session->labels_follow_edits, 
1054                         edl->session->plugins_follow_edits);
1055         }
1062 // Add new assets to EDL and schedule assets for index building.
1063 // Used for loading resources only.
1064         if(new_assets.total)
1065         {
1066                 for(int i = 0; i < new_assets.total; i++)
1067                 {
1068                         Asset *new_asset = new_assets.values[i];
1069                         File *new_file = 0;
1070                         File *index_file = 0;
1071                         int got_it = 0;
1072                         for(int j = 0; j < new_files.total; j++)
1073                         {
1074                                 new_file = new_files.values[j];
1075                                 if(!strcmp(new_file->asset->path,
1076                                         new_asset->path))
1077                                 {
1078                                         got_it = 1;
1079                                         break;
1080                                 }
1081                         }
1083                         mainindexes->add_next_asset(got_it ? new_file : 0, 
1084                                 new_assets.values[i]);
1085                         edl->assets->update(new_assets.values[i]);
1086                 }
1089 // Start examining next batch of index files
1090                 mainindexes->start_build();
1091         }
1094         update_project(load_mode);
1095 SET_TRACE
1099         new_edls.remove_all_objects();
1100 SET_TRACE
1101         new_assets.remove_all_objects();
1102 SET_TRACE
1103         new_files.remove_all_objects();
1105 SET_TRACE
1106         undo->update_undo(_("load"), LOAD_ALL, 0);
1109 SET_TRACE
1110         gui->stop_hourglass();
1111 SET_TRACE
1113         return 0;
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)
1123         {
1124                 for(int k = 0; k < track->plugin_set.total; k++)
1125                 {
1126                         PluginSet *plugin_set = track->plugin_set.values[k];
1127                         for(Plugin *plugin = (Plugin*)plugin_set->first; 
1128                         plugin; 
1129                         plugin = (Plugin*)plugin->next)
1130                         {
1131                                 if(plugin->plugin_type == PLUGIN_STANDALONE)
1132                                 {
1133                                         // ok we need to find it in plugindb
1134                                         int plugin_found = 0;
1135                                         for(int j = 0; j < plugindb->total; j++)
1136                                         {
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))
1142                                                         plugin_found = 1;
1143                                         }
1144                                         if (!plugin_found) 
1145                                         {
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); 
1147                                         }
1148                                 }
1149                         }
1150                 }
1151                 for(Edit *edit = (Edit*)track->edits->first; 
1152                 edit; 
1153                 edit = (Edit*)edit->next)
1154                 {
1155                         if (edit->transition)
1156                         {
1157                                 // ok we need to find transition in plugindb
1158                                 int transition_found = 0;
1159                                 for(int j = 0; j < plugindb->total; j++)
1160                                 {
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;
1167                                 }
1168                                 if (!transition_found) 
1169                                 {
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); 
1171                                 }
1172                         }
1173                 }
1174         }
1181 void MWindow::create_objects(int want_gui, 
1182         int want_new,
1183         char *config_path)
1185         char string[BCTEXTLEN];
1186         FileSystem fs;
1187         edl = 0;
1190         show_splash();
1192 // For some reason, init_signals must come after show_splash or the signals won't
1193 // get trapped.
1194         init_signals();
1197 SET_TRACE
1199         init_defaults(defaults, config_path);
1200 SET_TRACE
1201         init_preferences();
1202 SET_TRACE
1203         init_plugins(preferences, plugindb, splash_window);
1204         if(splash_window) splash_window->operation->update(_("Initializing GUI"));
1205 SET_TRACE
1206         init_theme();
1207 // Default project created here
1208 SET_TRACE
1209         init_edl();
1211 SET_TRACE
1212         init_awindow();
1213 SET_TRACE
1214         init_compositor();
1215 SET_TRACE
1216         init_levelwindow();
1217 SET_TRACE
1218         init_viewer();
1219 SET_TRACE
1220         init_cache();
1221 SET_TRACE
1222         init_indexes();
1223 SET_TRACE
1224         init_channeldb();
1225 SET_TRACE
1227         init_gui();
1228         init_gwindow();
1229 SET_TRACE
1230         init_render();
1231         init_brender();
1232         init_exportedl();
1233         mainprogress = new MainProgress(this, gui);
1234         undo = new MainUndo(this);
1236         plugin_guis = new ArrayList<PluginServer*>;
1238 SET_TRACE
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 SET_TRACE
1247         gui->mainmenu->load_defaults(defaults);
1248 SET_TRACE
1249         gui->mainmenu->update_toggles(0);
1250 SET_TRACE
1251         gui->patchbay->update();
1252 SET_TRACE
1253         gui->canvas->draw();
1254 SET_TRACE
1255         gui->cursor->draw(1);
1256 SET_TRACE
1257         gui->show_window();
1258         gui->raise_window();
1260         if(preferences->use_tipwindow)
1261                 init_tipwindow();
1262                 
1263 SET_TRACE
1265         hide_splash();
1266 SET_TRACE
1270 void MWindow::show_splash()
1272 #include "data/heroine_logo12_png.h"
1273         VFrame *frame = new VFrame(heroine_logo12_png);
1274         BC_DisplayInfo display_info;
1275         splash_window = new SplashGUI(frame, 
1276                 display_info.get_root_w() / 2 - frame->get_w() / 2,
1277                 display_info.get_root_h() / 2 - frame->get_h() / 2);
1278         splash_window->create_objects();
1281 void MWindow::hide_splash()
1283         if(splash_window)
1284                 delete splash_window;
1285         splash_window = 0;
1289 void MWindow::start()
1291         vwindow->start();
1292         awindow->start();
1293         cwindow->start();
1294         lwindow->start();
1295         gwindow->start();
1296         gui->run_window();
1299 void MWindow::show_vwindow()
1301         session->show_vwindow = 1;
1302         vwindow->gui->lock_window("MWindow::show_vwindow");
1303         vwindow->gui->show_window();
1304         vwindow->gui->raise_window();
1305         vwindow->gui->flush();
1306         vwindow->gui->unlock_window();
1307         gui->mainmenu->show_vwindow->set_checked(1);
1310 void MWindow::show_awindow()
1312         session->show_awindow = 1;
1313         awindow->gui->lock_window("MWindow::show_awindow");
1314         awindow->gui->show_window();
1315         awindow->gui->raise_window();
1316         awindow->gui->flush();
1317         awindow->gui->unlock_window();
1318         gui->mainmenu->show_awindow->set_checked(1);
1321 void MWindow::show_cwindow()
1323         session->show_cwindow = 1;
1324         cwindow->show_window();
1325         gui->mainmenu->show_cwindow->set_checked(1);
1328 void MWindow::show_gwindow()
1330         session->show_gwindow = 1;
1332         gwindow->gui->lock_window("MWindow::show_gwindow");
1333         gwindow->gui->show_window();
1334         gwindow->gui->raise_window();
1335         gwindow->gui->flush();
1336         gwindow->gui->unlock_window();
1338         gui->mainmenu->show_gwindow->set_checked(1);
1341 void MWindow::show_lwindow()
1343         session->show_lwindow = 1;
1344         lwindow->gui->lock_window("MWindow::show_lwindow");
1345         lwindow->gui->show_window();
1346         lwindow->gui->raise_window();
1347         lwindow->gui->flush();
1348         lwindow->gui->unlock_window();
1349         gui->mainmenu->show_lwindow->set_checked(1);
1352 void MWindow::tile_windows()
1354         session->default_window_positions();
1355         gui->default_positions();
1358 void MWindow::toggle_loop_playback()
1360         edl->local_session->loop_playback = !edl->local_session->loop_playback;
1361         set_loop_boundaries();
1362         save_backup();
1364         gui->canvas->draw_overlays();
1365         gui->canvas->flash();
1366         sync_parameters(CHANGE_PARAMS);
1369 void MWindow::set_titles(int value)
1371         edl->session->show_titles = value;
1372         trackmovement(edl->local_session->track_start);
1375 void MWindow::set_auto_keyframes(int value)
1377         gui->lock_window("MWindow::set_auto_keyframes");
1378         edl->session->auto_keyframes = value;
1379         gui->mbuttons->edit_panel->keyframe->update(value);
1380         gui->flush();
1381         gui->unlock_window();
1382         cwindow->gui->lock_window("MWindow::set_auto_keyframes");
1383         cwindow->gui->edit_panel->keyframe->update(value);
1384         cwindow->gui->flush();
1385         cwindow->gui->unlock_window();
1388 int MWindow::set_editing_mode(int new_editing_mode)
1390         gui->lock_window("MWindow::set_editing_mode");
1391         edl->session->editing_mode = new_editing_mode;
1392         gui->mbuttons->edit_panel->editing_mode = edl->session->editing_mode;
1393         gui->mbuttons->edit_panel->update();
1394         gui->canvas->update_cursor();
1395         gui->unlock_window();
1396         cwindow->gui->lock_window("MWindow::set_editing_mode");
1397         cwindow->gui->edit_panel->update();
1398         cwindow->gui->edit_panel->editing_mode = edl->session->editing_mode;
1399         cwindow->gui->unlock_window();
1400         return 0;
1404 void MWindow::sync_parameters(int change_type)
1407 // Sync engines which are playing back
1408         if(cwindow->playback_engine->is_playing_back)
1409         {
1410                 if(change_type == CHANGE_PARAMS)
1411                 {
1412 // TODO: block keyframes until synchronization is done
1413                         cwindow->playback_engine->sync_parameters(edl);
1414                 }
1415                 else
1416 // Stop and restart
1417                 {
1418                         int command = cwindow->playback_engine->command->command;
1419                         cwindow->playback_engine->que->send_command(STOP,
1420                                 CHANGE_NONE, 
1421                                 0,
1422                                 0);
1423 // Waiting for tracking to finish would make the restart position more
1424 // accurate but it can't lock the window to stop tracking for some reason.
1425 // Not waiting for tracking gives a faster response but restart position is
1426 // only as accurate as the last tracking update.
1427                         cwindow->playback_engine->interrupt_playback(0);
1428                         cwindow->playback_engine->que->send_command(command,
1429                                         change_type, 
1430                                         edl,
1431                                         1,
1432                                         0);
1433                 }
1434         }
1435         else
1436         {
1437                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1438                                                         change_type,
1439                                                         edl,
1440                                                         1);
1441         }
1444 void MWindow::update_caches()
1446         audio_cache->set_edl(edl);
1447         video_cache->set_edl(edl);
1450 void MWindow::show_plugin(Plugin *plugin)
1452         int done = 0;
1453 //printf("MWindow::show_plugin 1\n");
1454         plugin_gui_lock->lock("MWindow::show_plugin");
1455         for(int i = 0; i < plugin_guis->total; i++)
1456         {
1457 // Pointer comparison
1458                 if(plugin_guis->values[i]->plugin == plugin)
1459                 {
1460                         plugin_guis->values[i]->raise_window();
1461                         done = 1;
1462                         break;
1463                 }
1464         }
1466 //printf("MWindow::show_plugin 1\n");
1467         if(!done)
1468         {
1469                 if(!plugin->track)
1470                 {
1471                         printf("MWindow::show_plugin track not defined.\n");
1472                 }
1473                 PluginServer *server = scan_plugindb(plugin->title,
1474                         plugin->track->data_type);
1476 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
1477                 if(server && server->uses_gui)
1478                 {
1479                         PluginServer *gui = plugin_guis->append(new PluginServer(*server));
1480 // Needs mwindow to do GUI
1481                         gui->set_mwindow(this);
1482                         gui->open_plugin(0, preferences, edl, plugin, -1);
1483                         gui->show_gui();
1484                         plugin->show = 1;
1485                 }
1486         }
1487         plugin_gui_lock->unlock();
1488 //printf("MWindow::show_plugin 2\n");
1491 void MWindow::hide_plugin(Plugin *plugin, int lock)
1493         if(lock) plugin_gui_lock->lock("MWindow::hide_plugin");
1494         plugin->show = 0;
1495         for(int i = 0; i < plugin_guis->total; i++)
1496         {
1497                 if(plugin_guis->values[i]->plugin == plugin)
1498                 {
1499                         PluginServer *ptr = plugin_guis->values[i];
1500                         plugin_guis->remove(ptr);
1501                         if(lock) plugin_gui_lock->unlock();
1502 // Last command executed in client side close
1503                         delete ptr;
1504                         return;
1505                 }
1506         }
1507         if(lock) plugin_gui_lock->unlock();
1511 void MWindow::hide_plugins()
1513         plugin_gui_lock->lock("MWindow::hide_plugins");
1514         plugin_guis->remove_all_objects();
1515         plugin_gui_lock->unlock();
1518 void MWindow::update_plugin_guis()
1520         plugin_gui_lock->lock("MWindow::update_plugin_guis");
1522         for(int i = 0; i < plugin_guis->total; i++)
1523         {
1524                 plugin_guis->values[i]->update_gui();
1525         }
1526         plugin_gui_lock->unlock();
1529 void MWindow::render_plugin_gui(void *data, Plugin *plugin)
1531         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1532         for(int i = 0; i < plugin_guis->total; i++)
1533         {
1534                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1535                 {
1536                         plugin_guis->values[i]->render_gui(data);
1537                         break;
1538                 }
1539         }
1540         plugin_gui_lock->unlock();
1543 void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin)
1545         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1546         for(int i = 0; i < plugin_guis->total; i++)
1547         {
1548                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1549                 {
1550                         plugin_guis->values[i]->render_gui(data, size);
1551                         break;
1552                 }
1553         }
1554         plugin_gui_lock->unlock();
1558 void MWindow::update_plugin_states()
1560         plugin_gui_lock->lock("MWindow::update_plugin_states");
1561         for(int i = 0; i < plugin_guis->total; i++)
1562         {
1563                 int result = 0;
1564 // Get a plugin GUI
1565                 Plugin *src_plugin = plugin_guis->values[i]->plugin;
1566                 PluginServer *src_plugingui = plugin_guis->values[i];
1568 // Search for plugin in EDL.  Only the master EDL shows plugin GUIs.
1569                 for(Track *track = edl->tracks->first; 
1570                         track && !result; 
1571                         track = track->next)
1572                 {
1573                         for(int j = 0; 
1574                                 j < track->plugin_set.total && !result; 
1575                                 j++)
1576                         {
1577                                 PluginSet *plugin_set = track->plugin_set.values[j];
1578                                 for(Plugin *plugin = (Plugin*)plugin_set->first; 
1579                                         plugin && !result; 
1580                                         plugin = (Plugin*)plugin->next)
1581                                 {
1582                                         if(plugin == src_plugin &&
1583                                                 !strcmp(plugin->title, src_plugingui->title)) result = 1;
1584                                 }
1585                         }
1586                 }
1589 // Doesn't exist anymore
1590                 if(!result)
1591                 {
1592                         hide_plugin(src_plugin, 0);
1593                         i--;
1594                 }
1595         }
1596         plugin_gui_lock->unlock();
1600 void MWindow::update_plugin_titles()
1602         for(int i = 0; i < plugin_guis->total; i++)
1603         {
1604                 plugin_guis->values[i]->update_title();
1605         }
1608 int MWindow::asset_to_edl(EDL *new_edl, 
1609         Asset *new_asset, 
1610         RecordLabels *labels)
1612 //printf("MWindow::asset_to_edl 1\n");
1613 //      new_edl->load_defaults(defaults);
1615 // Keep frame rate, sample rate, and output size unchanged.
1616 // These parameters would revert the project if VWindow displayed an asset
1617 // of different size than the project.
1618         if(new_asset->video_data)
1619         {
1620                 new_edl->session->video_tracks = new_asset->layers;
1621 //              new_edl->session->frame_rate = new_asset->frame_rate;
1622 //              new_edl->session->output_w = new_asset->width;
1623 //              new_edl->session->output_h = new_asset->height;
1624         }
1625         else
1626                 new_edl->session->video_tracks = 0;
1633         if(new_asset->audio_data)
1634         {
1635                 new_edl->session->audio_tracks = new_asset->channels;
1636 //              new_edl->session->sample_rate = new_asset->sample_rate;
1637         }
1638         else
1639                 new_edl->session->audio_tracks = 0;
1640 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1642         new_edl->create_default_tracks();
1643 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1645 // Disable drawing if the file format isn't fast enough.
1646 // MPEG is now faster than most other codecs.
1647 //      if(new_asset->format == FILE_MPEG)
1648 //      {
1649 //              for(Track *current = new_edl->tracks->first;
1650 //                      current;
1651 //                      current = NEXT)
1652 //              {
1653 //                      if(current->data_type == TRACK_VIDEO) current->draw = 0;
1654 //              }
1655 //      }
1659 //printf("MWindow::asset_to_edl 3\n");
1660         new_edl->insert_asset(new_asset, 0, 0, labels);
1661 //printf("MWindow::asset_to_edl 3\n");
1667         char string[BCTEXTLEN];
1668         FileSystem fs;
1669         fs.extract_name(string, new_asset->path);
1670 //printf("MWindow::asset_to_edl 3\n");
1672         strcpy(new_edl->local_session->clip_title, string);
1673 //printf("MWindow::asset_to_edl 4 %s\n", string);
1675 //      new_edl->dump();
1676         return 0;
1679 // Reset everything after a load.
1680 void MWindow::update_project(int load_mode)
1682         restart_brender();
1683         edl->tracks->update_y_pixels(theme);
1685 // Draw timeline
1686         update_caches();
1688         gui->update(1, 1, 1, 1, 1, 1, 1);
1690         cwindow->update(0, 0, 1, 1, 1);
1693         if(load_mode == LOAD_REPLACE ||
1694                 load_mode == LOAD_REPLACE_CONCATENATE)
1695         {
1696                 vwindow->change_source();
1697         }
1698         else
1699         {
1700                 vwindow->update(1);
1701         }
1703         cwindow->gui->slider->set_position();
1704         cwindow->gui->timebar->update(1, 1);
1705         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1706                 CHANGE_ALL,
1707                 edl,
1708                 1);
1710         awindow->gui->lock_window("MWindow::update_project");
1711         awindow->gui->update_assets();
1712         awindow->gui->flush();
1713         awindow->gui->unlock_window();
1714         gui->flush();
1718 void MWindow::rebuild_indices()
1720         char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
1722         for(int i = 0; i < session->drag_assets->total; i++)
1723         {
1724 //printf("MWindow::rebuild_indices 1 %s\n", session->drag_assets->values[i]->path);
1725 // Erase file
1726                 IndexFile::get_index_filename(source_filename, 
1727                         preferences->index_directory,
1728                         index_filename, 
1729                         session->drag_assets->values[i]->path);
1730                 remove(index_filename);
1731 // Schedule index build
1732                 session->drag_assets->values[i]->index_status = INDEX_NOTTESTED;
1733                 mainindexes->add_next_asset(0, session->drag_assets->values[i]);
1734         }
1735         mainindexes->start_build();
1739 void MWindow::save_backup()
1741         FileXML file;
1742         edl->set_project_path(session->filename);
1743         edl->save_xml(plugindb, 
1744                 &file, 
1745                 BACKUP_PATH,
1746                 0,
1747                 0);
1748         file.terminate_string();
1749         char path[BCTEXTLEN];
1750         FileSystem fs;
1751         strcpy(path, BACKUP_PATH);
1752         fs.complete_path(path);
1754         if(file.write_to_file(path))
1755         {
1756                 char string2[256];
1757                 sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
1758                 gui->show_message(string2);
1759         }
1763 int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
1765         int denominator;
1766         if(!width || !height) return 1;
1767         float fraction = (float)width / height;
1769         for(denominator = 1; 
1770                 denominator < 100 && 
1771                         fabs(fraction * denominator - (int)(fraction * denominator)) > .001; 
1772                 denominator++)
1773                 ;
1775         w = denominator * width / height;
1776         h = denominator;
1777         return 0;
1782 void MWindow::remove_assets_from_project(int push_undo)
1784 // Remove from caches
1785         for(int i = 0; i < session->drag_assets->total; i++)
1786         {
1787                 audio_cache->delete_entry(session->drag_assets->values[i]);
1788                 video_cache->delete_entry(session->drag_assets->values[i]);
1789         }
1791 video_cache->dump();
1792 audio_cache->dump();
1794 // Remove from VWindow.
1795         for(int i = 0; i < session->drag_clips->total; i++)
1796         {
1797                 if(session->drag_clips->values[i] == vwindow->get_edl())
1798                 {
1799                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 1");
1800                         vwindow->remove_source();
1801                         vwindow->gui->unlock_window();
1802                 }
1803         }
1804         
1805         for(int i = 0; i < session->drag_assets->total; i++)
1806         {
1807                 if(session->drag_assets->values[i] == vwindow->get_asset())
1808                 {
1809                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
1810                         vwindow->remove_source();
1811                         vwindow->gui->unlock_window();
1812                 }
1813         }
1814         
1815         edl->remove_from_project(session->drag_assets);
1816         edl->remove_from_project(session->drag_clips);
1817         save_backup();
1818         if(push_undo) undo->update_undo(_("remove assets"), LOAD_ALL);
1819         restart_brender();
1821         gui->lock_window("MWindow::remove_assets_from_project 3");
1822         gui->update(1,
1823                 1,
1824                 1,
1825                 1,
1826                 0, 
1827                 1,
1828                 0);
1829         gui->unlock_window();
1831         awindow->gui->lock_window("MWindow::remove_assets_from_project 4");
1832         awindow->gui->update_assets();
1833         awindow->gui->flush();
1834         awindow->gui->unlock_window();
1836 // Removes from playback here
1837         sync_parameters(CHANGE_ALL);
1840 void MWindow::remove_assets_from_disk()
1842 // Remove from disk
1843         for(int i = 0; i < session->drag_assets->total; i++)
1844         {
1845                 remove(session->drag_assets->values[i]->path);
1846         }
1848         remove_assets_from_project(1);
1851 void MWindow::dump_plugins()
1853         for(int i = 0; i < plugindb->total; i++)
1854         {
1855                 printf("audio=%d video=%d realtime=%d transition=%d theme=%d %s\n",
1856                         plugindb->values[i]->audio,
1857                         plugindb->values[i]->video,
1858                         plugindb->values[i]->realtime,
1859                         plugindb->values[i]->transition,
1860                         plugindb->values[i]->theme,
1861                         plugindb->values[i]->title);
1862         }
1889 int MWindow::save_defaults()
1891         gui->save_defaults(defaults);
1892         edl->save_defaults(defaults);
1893         session->save_defaults(defaults);
1894         preferences->save_defaults(defaults);
1896         defaults->save();
1897         return 0;
1900 int MWindow::run_script(FileXML *script)
1902         int result = 0, result2 = 0;
1903         while(!result && !result2)
1904         {
1905                 result = script->read_tag();
1906                 if(!result)
1907                 {
1908                         if(script->tag.title_is("new_project"))
1909                         {
1910 // Run new in immediate mode.
1911 //                              gui->mainmenu->new_project->run_script(script);
1912                         }
1913                         else
1914                         if(script->tag.title_is("record"))
1915                         {
1916 // Run record as a thread.  It is a terminal command.
1917                                 ;
1918 // Will read the complete scipt file without letting record read it if not
1919 // terminated.
1920                                 result2 = 1;
1921                         }
1922                         else
1923                         {
1924                                 printf("MWindow::run_script: Unrecognized command: %s\n",script->tag.get_title() );
1925                         }
1926                 }
1927         }
1928         return result2;
1931 // ================================= synchronization
1934 int MWindow::interrupt_indexes()
1936         mainindexes->interrupt_build();
1937         return 0; 
1942 void MWindow::next_time_format()
1944         switch(edl->session->time_format)
1945         {
1946                 case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
1947                 case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
1948                 case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1949                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
1950                 case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
1951                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
1952                 case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
1953         }
1955         time_format_common();
1958 void MWindow::prev_time_format()
1960         switch(edl->session->time_format)
1961         {
1962                 case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
1963                 case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
1964                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
1965                 case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1966                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
1967                 case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
1968                 case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
1969         }
1971         time_format_common();
1974 void MWindow::time_format_common()
1976         gui->lock_window("MWindow::next_time_format");
1977         gui->redraw_time_dependancies();
1978         char string[BCTEXTLEN], string2[BCTEXTLEN];
1979         sprintf(string, _("Using %s."), Units::print_time_format(edl->session->time_format, string2));
1980         gui->show_message(string);
1981         gui->flush();
1982         gui->unlock_window();
1986 int MWindow::set_filename(char *filename)
1988         strcpy(session->filename, filename);
1989         if(gui)
1990         {
1991                 if(filename[0] == 0)
1992                 {
1993                         gui->set_title(PROGRAM_NAME);
1994                 }
1995                 else
1996                 {
1997                         FileSystem dir;
1998                         char string[BCTEXTLEN], string2[BCTEXTLEN];
1999                         dir.extract_name(string, filename);
2000                         sprintf(string2, PROGRAM_NAME ": %s", string);
2001                         gui->set_title(string2);
2002                 }
2003         }
2004         return 0; 
2014 int MWindow::set_loop_boundaries()
2016         double start = edl->local_session->get_selectionstart();
2017         double end = edl->local_session->get_selectionend();
2018         
2019         if(start != 
2020                 end) 
2021         {
2022                 ;
2023         }
2024         else
2025         if(edl->tracks->total_length())
2026         {
2027                 start = 0;
2028                 end = edl->tracks->total_length();
2029         }
2030         else
2031         {
2032                 start = end = 0;
2033         }
2035         if(edl->local_session->loop_playback && start != end)
2036         {
2037                 edl->local_session->loop_start = start;
2038                 edl->local_session->loop_end = end;
2039         }
2040         return 0; 
2049 int MWindow::reset_meters()
2051         cwindow->gui->lock_window("MWindow::reset_meters 1");
2052         cwindow->gui->meters->reset_meters();
2053         cwindow->gui->unlock_window();
2055         vwindow->gui->lock_window("MWindow::reset_meters 2");
2056         vwindow->gui->meters->reset_meters();
2057         vwindow->gui->unlock_window();
2059         lwindow->gui->lock_window("MWindow::reset_meters 3");
2060         lwindow->gui->panel->reset_meters();
2061         lwindow->gui->unlock_window();
2063         gui->lock_window("MWindow::reset_meters 4");
2064         gui->patchbay->reset_meters();
2065         gui->unlock_window();
2066         return 0;