r858: Merge 2.1:
[cinelerra_cv.git] / cinelerra / mwindow.C
blobf113fae4c2070af0bc8f244216c7f5f31fb47068
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 "mainerror.h"
38 #include "mainindexes.h"
39 #include "mainmenu.h"
40 #include "mainprogress.h"
41 #include "mainsession.h"
42 #include "mainundo.h"
43 #include "mbuttons.h"
44 #include "mutex.h"
45 #include "mwindowgui.h"
46 #include "mwindow.h"
47 #include "new.h"
48 #include "patchbay.h"
49 #include "playback3d.h"
50 #include "playbackengine.h"
51 #include "plugin.h"
52 #include "pluginserver.h"
53 #include "pluginset.h"
54 #include "preferences.h"
55 #include "record.h"
56 #include "recordlabel.h"
57 #include "render.h"
58 #include "samplescroll.h"
59 #include "sighandler.h"
60 #include "splashgui.h"
61 #include "statusbar.h"
62 #include "theme.h"
63 #include "threadloader.h"
64 #include "timebar.h"
65 #include "tipwindow.h"
66 #include "trackcanvas.h"
67 #include "track.h"
68 #include "tracking.h"
69 #include "trackscroll.h"
70 #include "tracks.h"
71 #include "transition.h"
72 #include "transportque.h"
73 #include "vframe.h"
74 #include "videodevice.inc"
75 #include "videowindow.h"
76 #include "vplayback.h"
77 #include "vwindowgui.h"
78 #include "vwindow.h"
79 #include "zoombar.h"
80 #include "exportedl.h"
82 #include <string.h>
86 extern "C"
92 // Hack for libdv to remove glib dependancy
94 // void
95 // g_log (const char    *log_domain,
96 //        int  log_level,
97 //        const char    *format,
98 //        ...)
99 // {
100 // }
101 // 
102 // void
103 // g_logv (const char    *log_domain,
104 //        int  log_level,
105 //        const char    *format,
106 //        ...)
107 // {
108 // }
109 // 
112 // Hack for XFree86 4.1.0
114 int atexit(void (*function)(void))
116         return 0;
125 MWindow::MWindow()
126  : Thread(1, 0, 0)
128         plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
129         brender_lock = new Mutex("MWindow::brender_lock");
130         brender = 0;
131         session = 0;
132         channeldb_buz = new ChannelDB;
133         channeldb_v4l2jpeg = new ChannelDB;
136 MWindow::~MWindow()
138         brender_lock->lock("MWindow::~MWindow");
139         if(brender) delete brender;
140         brender = 0;
141         brender_lock->unlock();
142         delete brender_lock;
144         delete mainindexes;
146 SET_TRACE
147         clean_indexes();
148 SET_TRACE
150         save_defaults();
151 SET_TRACE
152 // Give up and go to a movie
153         exit(0);
155 SET_TRACE
156         delete mainprogress;
157         delete audio_cache;             // delete the cache after the assets
158         delete video_cache;             // delete the cache after the assets
159         if(gui) delete gui;
160         delete undo;
161         delete preferences;
162         delete defaults;
163         delete render;
164 //      delete renderlist;
165         delete awindow;
166         delete vwindow;
167         delete cwindow;
168         delete lwindow;
169         plugin_guis->remove_all_objects();
170         delete plugin_guis;
171         delete plugin_gui_lock;
174 void MWindow::init_error()
176         new MainError(this);
179 void MWindow::create_defaults_path(char *string)
181 // set the .bcast path
182         FileSystem fs;
184         sprintf(string, "%s", BCASTDIR);
185         fs.complete_path(string);
186         if(!fs.is_dir(string)) 
187         {
188                 fs.create_dir(string); 
189         }
191 // load the defaults
192         strcat(string, "Cinelerra_rc");
195 void MWindow::init_defaults(BC_Hash* &defaults, char *config_path)
197         char path[BCTEXTLEN];
198 // Use user supplied path
199         if(config_path[0])
200         {
201                 strcpy(path, config_path);
202         }
203         else
204         {
205                 create_defaults_path(path);
206         }
208         defaults = new BC_Hash(path);
209         defaults->load();
212 void MWindow::init_plugin_path(Preferences *preferences, 
213         ArrayList<PluginServer*>* &plugindb,
214         FileSystem *fs,
215         SplashGUI *splash_window,
216         int *counter)
218         int result = 0;
219         PluginServer *newplugin;
221         if(!result)
222         {
223                 for(int i = 0; i < fs->dir_list.total; i++)
224                 {
225                         char path[BCTEXTLEN];
226                         strcpy(path, fs->dir_list.values[i]->path);
228 // File is a directory
229                         if(fs->is_dir(path))
230                         {
231                                 continue;
232                         }
233                         else
234                         {
235 // Try to query the plugin
236                                 fs->complete_path(path);
237 //printf("MWindow::init_plugin_path %s\n", path);
238                                 PluginServer *new_plugin = new PluginServer(path);
239                                 int result = new_plugin->open_plugin(1, preferences, 0, 0, -1);
241                                 if(!result)
242                                 {
243                                         plugindb->append(new_plugin);
244                                         new_plugin->close_plugin();
245                                         if(splash_window)
246                                                 splash_window->operation->update(_(new_plugin->title));
247                                 }
248                                 else
249                                 if(result == PLUGINSERVER_IS_LAD)
250                                 {
251                                         delete new_plugin;
252 // Open LAD subplugins
253                                         int id = 0;
254                                         do
255                                         {
256                                                 new_plugin = new PluginServer(path);
257                                                 result = new_plugin->open_plugin(1,
258                                                         preferences,
259                                                         0,
260                                                         0,
261                                                         id);
262                                                 id++;
263                                                 if(!result)
264                                                 {
265                                                         plugindb->append(new_plugin);
266                                                         new_plugin->close_plugin();
267                                                         if(splash_window)
268                                                                 splash_window->operation->update(_(new_plugin->title));
269                                                         else
270                                                         {
271                                                         }
272                                                 }
273                                         }while(!result);
274                                 }
275                                 else
276                                 {
277 // Plugin failed to open
278                                         delete new_plugin;
279                                 }
280                         }
282                         if(splash_window) splash_window->progress->update((*counter)++);
283                 }
284         }
287 void MWindow::init_plugins(Preferences *preferences, 
288         ArrayList<PluginServer*>* &plugindb,
289         SplashGUI *splash_window)
291         plugindb = new ArrayList<PluginServer*>;
295         FileSystem cinelerra_fs;
296         ArrayList<FileSystem*> lad_fs;
297         int result = 0;
299 // Get directories
300         cinelerra_fs.set_filter("[*.plugin][*.so]");
301         result = cinelerra_fs.update(preferences->global_plugin_dir);
303         if(result)
304         {
305                 fprintf(stderr, 
306                         _("MWindow::init_plugins: couldn't open %s directory\n"),
307                         preferences->global_plugin_dir);
308         }
310 // Parse LAD environment variable
311         char *env = getenv("LADSPA_PATH");
312         if(env)
313         {
314                 char string[BCTEXTLEN];
315                 char *ptr1 = env;
316                 while(ptr1)
317                 {
318                         char *ptr = strchr(ptr1, ':');
319                         char *end;
320                         if(ptr)
321                         {
322                                 end = ptr;
323                         }
324                         else
325                         {
326                                 end = env + strlen(env);
327                         }
329                         if(end > ptr1)
330                         {
331                                 int len = end - ptr1;
332                                 memcpy(string, ptr1, len);
333                                 string[len] = 0;
336                                 FileSystem *fs = new FileSystem;
337                                 lad_fs.append(fs);
338                                 fs->set_filter("*.so");
339                                 result = fs->update(string);
341                                 if(result)
342                                 {
343                                         fprintf(stderr, 
344                                                 _("MWindow::init_plugins: couldn't open %s directory\n"),
345                                                 string);
346                                 }
347                         }
349                         if(ptr)
350                                 ptr1 = ptr + 1;
351                         else
352                                 ptr1 = ptr;
353                 };
354         }
356         int total = cinelerra_fs.total_files();
357         int counter = 0;
358         for(int i = 0; i < lad_fs.total; i++)
359                 total += lad_fs.values[i]->total_files();
360         if(splash_window) splash_window->progress->update_length(total);
363 // Cinelerra
364 #ifndef DO_STATIC
365         init_plugin_path(preferences,
366                 plugindb,
367                 &cinelerra_fs,
368                 splash_window,
369                 &counter);
370 #else
371 // Call automatically generated routine to get plugins
372 #endif
374 // LAD
375         for(int i = 0; i < lad_fs.total; i++)
376                 init_plugin_path(preferences,
377                         plugindb,
378                         lad_fs.values[i],
379                         splash_window,
380                         &counter);
382         lad_fs.remove_all_objects();
385 void MWindow::delete_plugins()
387         for(int i = 0; i < plugindb->total; i++)
388         {
389                 delete plugindb->values[i];
390         }
391         delete plugindb;
394 void MWindow::create_plugindb(int do_audio, 
395                 int do_video, 
396                 int is_realtime, 
397                 int is_transition,
398                 int is_theme,
399                 ArrayList<PluginServer*> &plugindb)
401 // Get plugins
402         for(int i = 0; i < this->plugindb->total; i++)
403         {
404                 PluginServer *current = this->plugindb->values[i];
406                 if(current->audio == do_audio &&
407                         current->video == do_video &&
408                         (current->realtime == is_realtime || is_realtime < 0) &&
409                         current->transition == is_transition &&
410                         current->theme == is_theme)
411                         plugindb.append(current);
412         }
414 // Alphabetize list by title
415         int done = 0;
416         while(!done)
417         {
418                 done = 1;
419                 
420                 for(int i = 0; i < plugindb.total - 1; i++)
421                 {
422                         PluginServer *value1 = plugindb.values[i];
423                         PluginServer *value2 = plugindb.values[i + 1];
424                         if(strcmp(_(value1->title), _(value2->title)) > 0)
425                         {
426                                 done = 0;
427                                 plugindb.values[i] = value2;
428                                 plugindb.values[i + 1] = value1;
429                         }
430                 }
431         }
434 PluginServer* MWindow::scan_plugindb(char *title,
435                 int data_type)
437         if(data_type < 0)
438         {
439                 printf("MWindow::scan_plugindb data_type < 0\n");
440                 return 0;
441         }
443         for(int i = 0; i < plugindb->total; i++)
444         {
445                 PluginServer *server = plugindb->values[i];
446                 if(!strcasecmp(server->title, title) &&
447                 ((data_type == TRACK_AUDIO && server->audio) ||
448                 (data_type == TRACK_VIDEO && server->video))) 
449                         return plugindb->values[i];
450         }
451         return 0;
454 void MWindow::init_preferences()
456         preferences = new Preferences;
457         preferences->load_defaults(defaults);
458         session = new MainSession(this);
459         session->load_defaults(defaults);
462 void MWindow::clean_indexes()
464         FileSystem fs;
465         int total_excess;
466         long oldest;
467         int oldest_item = -1;
468         int result;
469         char string[BCTEXTLEN];
470         char string2[BCTEXTLEN];
472 // Delete extra indexes
473         fs.set_filter("*.idx");
474         fs.complete_path(preferences->index_directory);
475         fs.update(preferences->index_directory);
476 //printf("MWindow::clean_indexes 1 %d\n", fs.dir_list.total);
478 // Eliminate directories
479         result = 1;
480         while(result)
481         {
482                 result = 0;
483                 for(int i = 0; i < fs.dir_list.total && !result; i++)
484                 {
485                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
486                         if(fs.is_dir(string))
487                         {
488                                 delete fs.dir_list.values[i];
489                                 fs.dir_list.remove_number(i);
490                                 result = 1;
491                         }
492                 }
493         }
494         total_excess = fs.dir_list.total - preferences->index_count;
496 //printf("MWindow::clean_indexes 2 %d\n", fs.dir_list.total);
497         while(total_excess > 0)
498         {
499 // Get oldest
500                 for(int i = 0; i < fs.dir_list.total; i++)
501                 {
502                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
504                         if(i == 0 || fs.get_date(string) <= oldest)
505                         {
506                                 oldest = fs.get_date(string);
507                                 oldest_item = i;
508                         }
509                 }
511                 if(oldest_item >= 0)
512                 {
513 // Remove index file
514                         fs.join_names(string, 
515                                 preferences->index_directory, 
516                                 fs.dir_list.values[oldest_item]->name);
517 //printf("MWindow::clean_indexes 1 %s\n", string);
518                         if(remove(string))
519                                 perror("delete_indexes");
520                         delete fs.dir_list.values[oldest_item];
521                         fs.dir_list.remove_number(oldest_item);
523 // Remove table of contents if it exists
524                         strcpy(string2, string);
525                         char *ptr = strrchr(string2, '.');
526                         if(ptr)
527                         {
528 //printf("MWindow::clean_indexes 2 %s\n", string2);
529                                 sprintf(ptr, ".toc");
530                                 remove(string2);
531                         }
532                 }
534                 total_excess--;
535         }
538 void MWindow::init_awindow()
540         awindow = new AWindow(this);
541         awindow->create_objects();
544 void MWindow::init_gwindow()
546         gwindow = new GWindow(this);
547         gwindow->create_objects();
550 void MWindow::init_tipwindow()
552         twindow = new TipWindow(this);
553         twindow->start();
556 void MWindow::init_theme()
558         theme = 0;
560 // Replace blond theme with SUV since it doesn't work
561         if(!strcasecmp(preferences->theme, "Blond"))
562                 strcpy(preferences->theme, DEFAULT_THEME);
564         for(int i = 0; i < plugindb->total; i++)
565         {
566                 if(plugindb->values[i]->theme &&
567                         !strcasecmp(preferences->theme, plugindb->values[i]->title))
568                 {
569                         PluginServer plugin = *plugindb->values[i];
570                         plugin.open_plugin(0, preferences, 0, 0, -1);
571                         theme = plugin.new_theme();
572                         theme->mwindow = this;
573                         strcpy(theme->path, plugin.path);
574                         plugin.close_plugin();
575                 }
576         }
578         if(!theme)
579         {
580                 fprintf(stderr, _("MWindow::init_theme: theme %s not found.\n"), preferences->theme);
581                 exit(1);
582         }
584 // Load images which may have been forgotten
585         theme->Theme::initialize();
586 // Load user images
587         theme->initialize();
588 // Create menus with user colors
589         theme->build_menus();
590         init_menus();
592         theme->check_used();
595 void MWindow::init_3d()
597         playback_3d = new Playback3D(this);
598         playback_3d->create_objects();
601 void MWindow::init_edl()
603         edl = new EDL;
604         edl->create_objects();
605     edl->load_defaults(defaults);
606         edl->create_default_tracks();
607         edl->tracks->update_y_pixels(theme);
610 void MWindow::init_compositor()
612         cwindow = new CWindow(this);
613     cwindow->create_objects();
616 void MWindow::init_levelwindow()
618         lwindow = new LevelWindow(this);
619         lwindow->create_objects();
622 void MWindow::init_viewer()
624         vwindow = new VWindow(this);
625         vwindow->load_defaults();
626         vwindow->create_objects();
629 void MWindow::init_cache()
631         audio_cache = new CICache(preferences, plugindb);
632         video_cache = new CICache(preferences, plugindb);
635 void MWindow::init_channeldb()
637         channeldb_buz->load("channeldb_buz");
638         channeldb_v4l2jpeg->load("channeldb_v4l2jpeg");
641 void MWindow::init_menus()
643         char string[BCTEXTLEN];
645         // Color Models
646         cmodel_to_text(string, BC_RGB888);
647         colormodels.append(new ColormodelItem(string, BC_RGB888));
648         cmodel_to_text(string, BC_RGBA8888);
649         colormodels.append(new ColormodelItem(string, BC_RGBA8888));
650 //      cmodel_to_text(string, BC_RGB161616);
651 //      colormodels.append(new ColormodelItem(string, BC_RGB161616));
652 //      cmodel_to_text(string, BC_RGBA16161616);
653 //      colormodels.append(new ColormodelItem(string, BC_RGBA16161616));
654         cmodel_to_text(string, BC_RGB_FLOAT);
655         colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT));
656         cmodel_to_text(string, BC_RGBA_FLOAT);
657         colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT));
658         cmodel_to_text(string, BC_YUV888);
659         colormodels.append(new ColormodelItem(string, BC_YUV888));
660         cmodel_to_text(string, BC_YUVA8888);
661         colormodels.append(new ColormodelItem(string, BC_YUVA8888));
662 //      cmodel_to_text(string, BC_YUV161616);
663 //      colormodels.append(new ColormodelItem(string, BC_YUV161616));
664 //      cmodel_to_text(string, BC_YUVA16161616);
665 //      colormodels.append(new ColormodelItem(string, BC_YUVA16161616));
667 #define ILACEPROJECTMODELISTADD(x) ilacemode_to_text(string, x); \
668                            interlace_project_modes.append(new InterlacemodeItem(string, x));
670 #define ILACEASSETMODELISTADD(x) ilacemode_to_text(string, x); \
671                            interlace_asset_modes.append(new InterlacemodeItem(string, x));
673 #define ILACEFIXMETHODLISTADD(x) ilacefixmethod_to_text(string, x); \
674                            interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
676         // Interlacing Modes
677         ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
679         ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
680         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
682         ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
683         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
685         ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
686         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
688         // Interlacing Fixing Methods
689         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
690         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
691         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
694 void MWindow::init_indexes()
696         mainindexes = new MainIndexes(this);
697         mainindexes->start_loop();
700 void MWindow::init_gui()
702         gui = new MWindowGUI(this);
703         gui->create_objects();
704         gui->load_defaults(defaults);
707 void MWindow::init_signals()
709         sighandler = new SigHandler;
710         sighandler->initialize();
711 ENABLE_BUFFER
714 void MWindow::init_render()
716         render = new Render(this);
717 //      renderlist = new Render(this);
718         batch_render = new BatchRenderThread(this);
721 void MWindow::init_exportedl()
723         exportedl = new ExportEDL(this);
726 void MWindow::init_brender()
728         if(preferences->use_brender && !brender)
729         {
730                 brender_lock->lock("MWindow::init_brender 1");
731                 brender = new BRender(this);
732                 brender->initialize();
733                 session->brender_end = 0;
734                 brender_lock->unlock();
735         }
736         else
737         if(!preferences->use_brender && brender)
738         {
739                 brender_lock->lock("MWindow::init_brender 2");
740                 delete brender;
741                 brender = 0;
742                 session->brender_end = 0;
743                 brender_lock->unlock();
744         }
745         if(brender) brender->restart(edl);
748 void MWindow::restart_brender()
750 //printf("MWindow::restart_brender 1\n");
751         if(brender) brender->restart(edl);
754 void MWindow::stop_brender()
756         if(brender) brender->stop();
759 int MWindow::brender_available(int position)
761         int result = 0;
762         brender_lock->lock("MWindow::brender_available 1");
763         if(brender)
764         {
765                 if(brender->map_valid)
766                 {
767                         brender->map_lock->lock("MWindow::brender_available 2");
768                         if(position < brender->map_size &&
769                                 position >= 0)
770                         {
771 //printf("MWindow::brender_available 1 %d %d\n", position, brender->map[position]);
772                                 if(brender->map[position] == BRender::RENDERED)
773                                         result = 1;
774                         }
775                         brender->map_lock->unlock();
776                 }
777         }
778         brender_lock->unlock();
779         return result;
782 void MWindow::set_brender_start()
784         edl->session->brender_start = edl->local_session->get_selectionstart();
785         restart_brender();
786         gui->canvas->draw_overlays();
787         gui->canvas->flash();
792 int MWindow::load_filenames(ArrayList<char*> *filenames, 
793         int load_mode,
794         int update_filename,
795         char *reel_name,
796         int reel_number,
797         int overwrite_reel)
799 SET_TRACE
800         ArrayList<EDL*> new_edls;
801         ArrayList<Asset*> new_assets;
802         ArrayList<File*> new_files;
804         save_defaults();
805         gui->start_hourglass();
807 // Need to stop playback since tracking depends on the EDL not getting
808 // deleted.
809         cwindow->playback_engine->que->send_command(STOP,
810                 CHANGE_NONE, 
811                 0,
812                 0);
813         vwindow->playback_engine->que->send_command(STOP,
814                 CHANGE_NONE, 
815                 0,
816                 0);
817         cwindow->playback_engine->interrupt_playback(0);
818         vwindow->playback_engine->interrupt_playback(0);
822 // Define new_edls and new_assets to load
823         int result = 0;
824         for(int i = 0; i < filenames->total; i++)
825         {
826 // Get type of file
827                 File *new_file = new File;
828                 Asset *new_asset = new Asset(filenames->values[i]);
829                 EDL *new_edl = new EDL;
830                 char string[BCTEXTLEN];
832 // Set reel name and number for the asset
833 // If the user wants to overwrite the last used reel number for the clip,
834 // we have to rebuild the index for the file
836                 if(overwrite_reel)
837                 {
838                         char source_filename[BCTEXTLEN];
839                         char index_filename[BCTEXTLEN];
840                         
841                         strcpy(new_asset->reel_name, reel_name);
842                         new_asset->reel_number = reel_number;
844                         IndexFile::get_index_filename(source_filename,
845                                 preferences->index_directory,
846                                 index_filename,
847                                 new_asset->path);
848                         remove(index_filename);
849                         new_asset->index_status = INDEX_NOTTESTED;
850                 }
851                 
852                 new_edl->create_objects();
853                 new_edl->copy_session(edl);
855                 sprintf(string, "Loading %s", new_asset->path);
856                 gui->show_message(string);
857 SET_TRACE
858                 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
859 SET_TRACE
861                 switch(result)
862                 {
863 // Convert media file to EDL
864                         case FILE_OK:
865 // Warn about odd image dimensions
866                                 if(new_asset->video_data &&
867                                         ((new_asset->width % 2) ||
868                                         (new_asset->height % 2)))
869                                 {
870                                         char string[BCTEXTLEN];
871                                         sprintf(string, "%s's resolution is %dx%d.\nImages with odd dimensions may not decode properly.",
872                                                 new_asset->path,
873                                                 new_asset->width,
874                                                 new_asset->height);
875                                         MainError::show_error(string);
876                                 }
879                                 if(load_mode != LOAD_RESOURCESONLY)
880                                 {
881 SET_TRACE
882                                         asset_to_edl(new_edl, new_asset);
883 SET_TRACE
884                                         new_edls.append(new_edl);
885 SET_TRACE
886                                         Garbage::delete_object(new_asset);
887                                         new_asset = 0;
888 SET_TRACE
889                                 }
890                                 else
891                                 {
892                                         new_assets.append(new_asset);
893                                 }
895 // Set filename to nothing for assets since save EDL would overwrite them.
896                                 if(load_mode == LOAD_REPLACE || 
897                                         load_mode == LOAD_REPLACE_CONCATENATE)
898                                 {
899                                         set_filename("");
900 // Reset timeline position
901                                         new_edl->local_session->view_start = 0;
902                                         new_edl->local_session->track_start = 0;
903                                 }
905                                 result = 0;
906                                 break;
908 // File not found
909                         case FILE_NOT_FOUND:
910                                 sprintf(string, _("Failed to open %s"), new_asset->path);
911                                 gui->show_message(string, theme->message_error);
912                                 result = 1;
913                                 break;
915 // Unknown format
916                         case FILE_UNRECOGNIZED_CODEC:
917                         {
918 // Test index file
919                                 IndexFile indexfile(this);
920                                 result = indexfile.open_index(this, new_asset);
921                                 if(!result)
922                                 {
923                                         indexfile.close_index();
924                                 }
926 // Test existing EDLs
927                                 if(result)
928                                 {
929                                         for(int j = 0; j < new_edls.total + 1; j++)
930                                         {
931                                                 Asset *old_asset;
932                                                 if(j == new_edls.total)
933                                                 {
934                                                         if(old_asset = edl->assets->get_asset(new_asset->path))
935                                                         {
936                                                                 *new_asset = *old_asset;
937                                                                 result = 0;
938                                                         }
939                                                 }
940                                                 else
941                                                 {
942                                                         if(old_asset = new_edls.values[j]->assets->get_asset(new_asset->path))
943                                                         {
944                                                                 *new_asset = *old_asset;
945                                                                 result = 0;
946                                                         }
947                                                 }
948                                         }
949                                 }
951 // Prompt user
952                                 if(result)
953                                 {
954                                         char string[BCTEXTLEN];
955                                         FileSystem fs;
956                                         fs.extract_name(string, new_asset->path);
958                                         strcat(string, _("'s format couldn't be determined."));
959                                         new_asset->audio_data = 1;
960                                         new_asset->format = FILE_PCM;
961                                         new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
962                                         new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
963                                         new_asset->bits = defaults->get("AUDIO_BITS", 16);
964                                         new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
965                                         new_asset->signed_ = defaults->get("SIGNED_", 1);
966                                         new_asset->header = defaults->get("HEADER", 0);
968                                         FileFormat fwindow(this);
969                                         fwindow.create_objects(new_asset, string);
970                                         result = fwindow.run_window();
972                                         defaults->update("AUDIO_CHANNELS", new_asset->channels);
973                                         defaults->update("SAMPLE_RATE", new_asset->sample_rate);
974                                         defaults->update("AUDIO_BITS", new_asset->bits);
975                                         defaults->update("BYTE_ORDER", new_asset->byte_order);
976                                         defaults->update("SIGNED_", new_asset->signed_);
977                                         defaults->update("HEADER", new_asset->header);
978                                         save_defaults();
979                                 }
981 // Append to list
982                                 if(!result)
983                                 {
984 // Recalculate length
985                                         delete new_file;
986                                         new_file = new File;
987                                         result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
989                                         if(load_mode != LOAD_RESOURCESONLY)
990                                         {
991                                                 asset_to_edl(new_edl, new_asset);
992                                                 new_edls.append(new_edl);
993                                                 Garbage::delete_object(new_asset);
994                                                 new_asset = 0;
995                                         }
996                                         else
997                                         {
998                                                 new_assets.append(new_asset);
999                                         }
1000                                 }
1001                                 else
1002                                 {
1003                                         result = 1;
1004                                 }
1005                                 break;
1006                         }
1008                         case FILE_IS_XML:
1009                         {
1010                                 FileXML xml_file;
1011                                 xml_file.read_from_file(filenames->values[i]);
1012 // Load EDL for pasting
1013                                 new_edl->load_xml(plugindb, &xml_file, LOAD_ALL);
1014                                 test_plugins(new_edl, filenames->values[i]);
1016 // We don't want a valid reel name/number for projects
1017                                 strcpy(new_asset->reel_name, "");
1018                                 reel_number = -1;
1020                                 if(load_mode == LOAD_REPLACE || 
1021                                         load_mode == LOAD_REPLACE_CONCATENATE)
1022                                 {
1023                                         strcpy(session->filename, filenames->values[i]);
1024                                         strcpy(new_edl->local_session->clip_title, filenames->values[i]);
1025                                         if(update_filename)
1026                                                 set_filename(new_edl->local_session->clip_title);
1027                                 }
1029                                 new_edls.append(new_edl);
1030                                 result = 0;
1031                                 break;
1032                         }
1033                 }
1035 SET_TRACE
1036                 if(result)
1037                 {
1038                         delete new_edl;
1039                         Garbage::delete_object(new_asset);
1040                         new_edl = 0;
1041                         new_asset = 0;
1042                 }
1043 SET_TRACE
1045 // Store for testing index
1046                 new_files.append(new_file);
1047 SET_TRACE
1048         }
1052         if(!result) gui->statusbar->default_message();
1061 // Paste them.
1062 // Don't back up here.
1063         if(new_edls.total)
1064         {
1065 // For pasting, clear the active region
1066                 if(load_mode == LOAD_PASTE)
1067                 {
1068                         double start = edl->local_session->get_selectionstart();
1069                         double end = edl->local_session->get_selectionend();
1070                         if(!EQUIV(start, end))
1071                                 edl->clear(start, 
1072                                         end,
1073                                         edl->session->labels_follow_edits,
1074                                         edl->session->plugins_follow_edits);
1075                 }
1077                 paste_edls(&new_edls, 
1078                         load_mode,
1079                         0,
1080                         -1,
1081                         edl->session->labels_follow_edits, 
1082                         edl->session->plugins_follow_edits);
1083         }
1090 // Add new assets to EDL and schedule assets for index building.
1091 // Used for loading resources only.
1092         if(new_assets.total)
1093         {
1094                 for(int i = 0; i < new_assets.total; i++)
1095                 {
1096                         Asset *new_asset = new_assets.values[i];
1097                         File *new_file = 0;
1098                         File *index_file = 0;
1099                         int got_it = 0;
1100                         for(int j = 0; j < new_files.total; j++)
1101                         {
1102                                 new_file = new_files.values[j];
1103                                 if(!strcmp(new_file->asset->path,
1104                                         new_asset->path))
1105                                 {
1106                                         got_it = 1;
1107                                         break;
1108                                 }
1109                         }
1111                         mainindexes->add_next_asset(got_it ? new_file : 0, 
1112                                 new_asset);
1113                         edl->assets->update(new_asset);
1115                 }
1118 // Start examining next batch of index files
1119                 mainindexes->start_build();
1120         }
1123         update_project(load_mode);
1124 SET_TRACE
1128         new_edls.remove_all_objects();
1129 SET_TRACE
1130         for(int i = 0; i < new_assets.total; i++)
1131                 Garbage::delete_object(new_assets.values[i]);
1132 SET_TRACE
1133         new_assets.remove_all();
1134 SET_TRACE
1135         new_files.remove_all_objects();
1137 SET_TRACE
1138         undo->update_undo(_("load"), LOAD_ALL, 0);
1141 SET_TRACE
1142         gui->stop_hourglass();
1143 SET_TRACE
1145         return 0;
1151 void MWindow::test_plugins(EDL *new_edl, char *path)
1153         char string[BCTEXTLEN];
1154 // Do a check weather plugins exist
1155         for(Track *track = new_edl->tracks->first; track; track = track->next)
1156         {
1157                 for(int k = 0; k < track->plugin_set.total; k++)
1158                 {
1159                         PluginSet *plugin_set = track->plugin_set.values[k];
1160                         for(Plugin *plugin = (Plugin*)plugin_set->first; 
1161                         plugin; 
1162                         plugin = (Plugin*)plugin->next)
1163                         {
1164                                 if(plugin->plugin_type == PLUGIN_STANDALONE)
1165                                 {
1166                                         // ok we need to find it in plugindb
1167                                         int plugin_found = 0;
1168                                         for(int j = 0; j < plugindb->total; j++)
1169                                         {
1170                                                 PluginServer *server = plugindb->values[j];
1171                                                 if(!strcasecmp(server->title, plugin->title) &&
1172                                                         ((track->data_type == TRACK_AUDIO && server->audio) ||
1173                                                         (track->data_type == TRACK_VIDEO && server->video)) &&
1174                                                         (!server->transition))
1175                                                         plugin_found = 1;
1176                                         }
1177                                         if (!plugin_found) 
1178                                         {
1179                                                 sprintf(string, 
1180                                                         "The effect '%s' in file '%s' is not part of your installation of Cinelerra.\n"
1181                                                         "The project won't be rendered as it was meant and Cinelerra might crash.\n",
1182                                                         plugin->title, 
1183                                                         path); 
1184                                                 MainError::show_error(string);
1185                                         }
1186                                 }
1187                         }
1188                 }
1189                 for(Edit *edit = (Edit*)track->edits->first; 
1190                 edit; 
1191                 edit = (Edit*)edit->next)
1192                 {
1193                         if (edit->transition)
1194                         {
1195                                 // ok we need to find transition in plugindb
1196                                 int transition_found = 0;
1197                                 for(int j = 0; j < plugindb->total; j++)
1198                                 {
1199                                         PluginServer *server = plugindb->values[j];
1200                                         if(!strcasecmp(server->title, edit->transition->title) &&
1201                                                 ((track->data_type == TRACK_AUDIO && server->audio) ||
1202                                                 (track->data_type == TRACK_VIDEO && server->video)) &&
1203                                                 (server->transition))
1204                                                 transition_found = 1;
1205                                 }
1206                                 if (!transition_found) 
1207                                 {
1208                                         sprintf(string, 
1209                                                 "The transition '%s' in file '%s' is not part of your installation of Cinelerra.\n"
1210                                                 "The project won't be rendered as it was meant and Cinelerra might crash.\n",
1211                                                 edit->transition->title, 
1212                                                 path); 
1213                                         MainError::show_error(string);
1214                                 }
1215                         }
1216                 }
1217         }
1224 void MWindow::create_objects(int want_gui, 
1225         int want_new,
1226         char *config_path)
1228         char string[BCTEXTLEN];
1229         FileSystem fs;
1230         edl = 0;
1234         init_3d();
1235         show_splash();
1237 // For some reason, init_signals must come after show_splash or the signals won't
1238 // get trapped.
1239         init_signals();
1241         init_error();
1243 SET_TRACE
1245         init_defaults(defaults, config_path);
1246 SET_TRACE
1247         init_preferences();
1248 SET_TRACE
1249         init_plugins(preferences, plugindb, splash_window);
1250         if(splash_window) splash_window->operation->update(_("Initializing GUI"));
1251 SET_TRACE
1252         init_theme();
1253 // Default project created here
1254 SET_TRACE
1255         init_edl();
1257 SET_TRACE
1258         init_awindow();
1259 SET_TRACE
1260         init_compositor();
1261 SET_TRACE
1262         init_levelwindow();
1263 SET_TRACE
1264         init_viewer();
1265 SET_TRACE
1266         init_cache();
1267 SET_TRACE
1268         init_indexes();
1269 SET_TRACE
1270         init_channeldb();
1271 SET_TRACE
1273         init_gui();
1274         init_gwindow();
1275 SET_TRACE
1276         init_render();
1277         init_brender();
1278         init_exportedl();
1279         mainprogress = new MainProgress(this, gui);
1280         undo = new MainUndo(this);
1282         plugin_guis = new ArrayList<PluginServer*>;
1284 SET_TRACE
1285         if(session->show_vwindow) vwindow->gui->show_window();
1286         if(session->show_cwindow) cwindow->gui->show_window();
1287         if(session->show_awindow) awindow->gui->show_window();
1288         if(session->show_lwindow) lwindow->gui->show_window();
1289         if(session->show_gwindow) gwindow->gui->show_window();
1290 SET_TRACE
1293         gui->mainmenu->load_defaults(defaults);
1294 SET_TRACE
1295         gui->mainmenu->update_toggles(0);
1296 SET_TRACE
1297         gui->patchbay->update();
1298 SET_TRACE
1299         gui->canvas->draw();
1300 SET_TRACE
1301         gui->cursor->draw(1);
1302 SET_TRACE
1303         gui->show_window();
1304         gui->raise_window();
1306         if(preferences->use_tipwindow)
1307                 init_tipwindow();
1308                 
1309 SET_TRACE
1311         hide_splash();
1312 SET_TRACE
1316 void MWindow::show_splash()
1318 #include "data/heroine_logo12_png.h"
1319         VFrame *frame = new VFrame(heroine_logo12_png);
1320         BC_DisplayInfo display_info;
1321         splash_window = new SplashGUI(frame, 
1322                 display_info.get_root_w() / 2 - frame->get_w() / 2,
1323                 display_info.get_root_h() / 2 - frame->get_h() / 2);
1324         splash_window->create_objects();
1327 void MWindow::hide_splash()
1329         if(splash_window)
1330                 delete splash_window;
1331         splash_window = 0;
1335 void MWindow::start()
1337 ENABLE_BUFFER
1338         vwindow->start();
1339         awindow->start();
1340         cwindow->start();
1341         lwindow->start();
1342         gwindow->start();
1343         Thread::start();
1344         playback_3d->start();
1347 void MWindow::run()
1349         gui->run_window();
1352 void MWindow::show_vwindow()
1354         session->show_vwindow = 1;
1355         vwindow->gui->lock_window("MWindow::show_vwindow");
1356         vwindow->gui->show_window();
1357         vwindow->gui->raise_window();
1358         vwindow->gui->flush();
1359         vwindow->gui->unlock_window();
1360         gui->mainmenu->show_vwindow->set_checked(1);
1363 void MWindow::show_awindow()
1365         session->show_awindow = 1;
1366         awindow->gui->lock_window("MWindow::show_awindow");
1367         awindow->gui->show_window();
1368         awindow->gui->raise_window();
1369         awindow->gui->flush();
1370         awindow->gui->unlock_window();
1371         gui->mainmenu->show_awindow->set_checked(1);
1374 void MWindow::show_cwindow()
1376         session->show_cwindow = 1;
1377         cwindow->show_window();
1378         gui->mainmenu->show_cwindow->set_checked(1);
1381 void MWindow::show_gwindow()
1383         session->show_gwindow = 1;
1385         gwindow->gui->lock_window("MWindow::show_gwindow");
1386         gwindow->gui->show_window();
1387         gwindow->gui->raise_window();
1388         gwindow->gui->flush();
1389         gwindow->gui->unlock_window();
1391         gui->mainmenu->show_gwindow->set_checked(1);
1394 void MWindow::show_lwindow()
1396         session->show_lwindow = 1;
1397         lwindow->gui->lock_window("MWindow::show_lwindow");
1398         lwindow->gui->show_window();
1399         lwindow->gui->raise_window();
1400         lwindow->gui->flush();
1401         lwindow->gui->unlock_window();
1402         gui->mainmenu->show_lwindow->set_checked(1);
1405 void MWindow::tile_windows()
1407         session->default_window_positions();
1408         gui->default_positions();
1411 void MWindow::toggle_loop_playback()
1413         edl->local_session->loop_playback = !edl->local_session->loop_playback;
1414         set_loop_boundaries();
1415         save_backup();
1417         gui->canvas->draw_overlays();
1418         gui->canvas->flash();
1419         sync_parameters(CHANGE_PARAMS);
1422 void MWindow::set_titles(int value)
1424         edl->session->show_titles = value;
1425         trackmovement(edl->local_session->track_start);
1428 void MWindow::set_auto_keyframes(int value)
1430         gui->lock_window("MWindow::set_auto_keyframes");
1431         edl->session->auto_keyframes = value;
1432         gui->mbuttons->edit_panel->keyframe->update(value);
1433         gui->flush();
1434         gui->unlock_window();
1435         cwindow->gui->lock_window("MWindow::set_auto_keyframes");
1436         cwindow->gui->edit_panel->keyframe->update(value);
1437         cwindow->gui->flush();
1438         cwindow->gui->unlock_window();
1441 int MWindow::set_editing_mode(int new_editing_mode)
1443         gui->lock_window("MWindow::set_editing_mode");
1444         edl->session->editing_mode = new_editing_mode;
1445         gui->mbuttons->edit_panel->editing_mode = edl->session->editing_mode;
1446         gui->mbuttons->edit_panel->update();
1447         gui->canvas->update_cursor();
1448         gui->unlock_window();
1449         cwindow->gui->lock_window("MWindow::set_editing_mode");
1450         cwindow->gui->edit_panel->update();
1451         cwindow->gui->edit_panel->editing_mode = edl->session->editing_mode;
1452         cwindow->gui->unlock_window();
1453         return 0;
1457 void MWindow::sync_parameters(int change_type)
1460 // Sync engines which are playing back
1461         if(cwindow->playback_engine->is_playing_back)
1462         {
1463                 if(change_type == CHANGE_PARAMS)
1464                 {
1465 // TODO: block keyframes until synchronization is done
1466                         cwindow->playback_engine->sync_parameters(edl);
1467                 }
1468                 else
1469 // Stop and restart
1470                 {
1471                         int command = cwindow->playback_engine->command->command;
1472                         cwindow->playback_engine->que->send_command(STOP,
1473                                 CHANGE_NONE, 
1474                                 0,
1475                                 0);
1476 // Waiting for tracking to finish would make the restart position more
1477 // accurate but it can't lock the window to stop tracking for some reason.
1478 // Not waiting for tracking gives a faster response but restart position is
1479 // only as accurate as the last tracking update.
1480                         cwindow->playback_engine->interrupt_playback(0);
1481                         cwindow->playback_engine->que->send_command(command,
1482                                         change_type, 
1483                                         edl,
1484                                         1,
1485                                         0);
1486                 }
1487         }
1488         else
1489         {
1490                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1491                                                         change_type,
1492                                                         edl,
1493                                                         1);
1494         }
1497 void MWindow::age_caches()
1499         int64_t prev_memory_usage;
1500         int64_t memory_usage;
1501         int result = 0;
1502         do
1503         {
1504                 memory_usage = audio_cache->get_memory_usage(1) +
1505                         video_cache->get_memory_usage(1);
1507                 if(memory_usage > preferences->cache_size)
1508                 {
1509                         int target = 1;
1510                         int oldest1 = audio_cache->get_oldest();
1511                         int oldest2 = video_cache->get_oldest();
1512                         if(oldest2 < oldest1) target = 2;
1513                         switch(target)
1514                         {
1515                                 case 1: audio_cache->delete_oldest(); break;
1516                                 case 2: video_cache->delete_oldest(); break;
1517                         }
1518                 }
1519                 prev_memory_usage = memory_usage;
1520                 memory_usage = audio_cache->get_memory_usage(1) +
1521                         video_cache->get_memory_usage(1);
1522         }while(!result && 
1523                 prev_memory_usage != memory_usage && 
1524                 memory_usage > preferences->cache_size);
1527 void MWindow::show_plugin(Plugin *plugin)
1529         int done = 0;
1530 //printf("MWindow::show_plugin 1\n");
1531         plugin_gui_lock->lock("MWindow::show_plugin");
1532         for(int i = 0; i < plugin_guis->total; i++)
1533         {
1534 // Pointer comparison
1535                 if(plugin_guis->values[i]->plugin == plugin)
1536                 {
1537                         plugin_guis->values[i]->raise_window();
1538                         done = 1;
1539                         break;
1540                 }
1541         }
1543 //printf("MWindow::show_plugin 1\n");
1544         if(!done)
1545         {
1546                 if(!plugin->track)
1547                 {
1548                         printf("MWindow::show_plugin track not defined.\n");
1549                 }
1550                 PluginServer *server = scan_plugindb(plugin->title,
1551                         plugin->track->data_type);
1553 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
1554                 if(server && server->uses_gui)
1555                 {
1556                         PluginServer *gui = plugin_guis->append(new PluginServer(*server));
1557 // Needs mwindow to do GUI
1558                         gui->set_mwindow(this);
1559                         gui->open_plugin(0, preferences, edl, plugin, -1);
1560                         gui->show_gui();
1561                         plugin->show = 1;
1562                 }
1563         }
1564         plugin_gui_lock->unlock();
1565 //printf("MWindow::show_plugin 2\n");
1568 void MWindow::hide_plugin(Plugin *plugin, int lock)
1570         plugin->show = 0;
1571         gui->lock_window("MWindow::hide_plugin");
1572         gui->update(0, 1, 0, 0, 0, 0, 0);
1573         gui->unlock_window();
1575         if(lock) plugin_gui_lock->lock("MWindow::hide_plugin");
1576         for(int i = 0; i < plugin_guis->total; i++)
1577         {
1578                 if(plugin_guis->values[i]->plugin == plugin)
1579                 {
1580                         PluginServer *ptr = plugin_guis->values[i];
1581                         plugin_guis->remove(ptr);
1582                         if(lock) plugin_gui_lock->unlock();
1583 // Last command executed in client side close
1584                         delete ptr;
1585                         return;
1586                 }
1587         }
1588         if(lock) plugin_gui_lock->unlock();
1592 void MWindow::hide_plugins()
1594         plugin_gui_lock->lock("MWindow::hide_plugins");
1595         plugin_guis->remove_all_objects();
1596         plugin_gui_lock->unlock();
1599 void MWindow::update_plugin_guis()
1601         plugin_gui_lock->lock("MWindow::update_plugin_guis");
1603         for(int i = 0; i < plugin_guis->total; i++)
1604         {
1605                 plugin_guis->values[i]->update_gui();
1606         }
1607         plugin_gui_lock->unlock();
1610 int MWindow::plugin_gui_open(Plugin *plugin)
1612         int result = 0;
1613         plugin_gui_lock->lock("MWindow::plugin_gui_open");
1614         for(int i = 0; i < plugin_guis->total; i++)
1615         {
1616                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1617                 {
1618                         result = 1;
1619                         break;
1620                 }
1621         }
1622         plugin_gui_lock->unlock();
1623         return result;
1626 void MWindow::render_plugin_gui(void *data, Plugin *plugin)
1628         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1629         for(int i = 0; i < plugin_guis->total; i++)
1630         {
1631                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1632                 {
1633                         plugin_guis->values[i]->render_gui(data);
1634                         break;
1635                 }
1636         }
1637         plugin_gui_lock->unlock();
1640 void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin)
1642         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1643         for(int i = 0; i < plugin_guis->total; i++)
1644         {
1645                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1646                 {
1647                         plugin_guis->values[i]->render_gui(data, size);
1648                         break;
1649                 }
1650         }
1651         plugin_gui_lock->unlock();
1655 void MWindow::update_plugin_states()
1657         plugin_gui_lock->lock("MWindow::update_plugin_states");
1658         for(int i = 0; i < plugin_guis->total; i++)
1659         {
1660                 int result = 0;
1661 // Get a plugin GUI
1662                 Plugin *src_plugin = plugin_guis->values[i]->plugin;
1663                 PluginServer *src_plugingui = plugin_guis->values[i];
1665 // Search for plugin in EDL.  Only the master EDL shows plugin GUIs.
1666                 for(Track *track = edl->tracks->first; 
1667                         track && !result; 
1668                         track = track->next)
1669                 {
1670                         for(int j = 0; 
1671                                 j < track->plugin_set.total && !result; 
1672                                 j++)
1673                         {
1674                                 PluginSet *plugin_set = track->plugin_set.values[j];
1675                                 for(Plugin *plugin = (Plugin*)plugin_set->first; 
1676                                         plugin && !result; 
1677                                         plugin = (Plugin*)plugin->next)
1678                                 {
1679                                         if(plugin == src_plugin &&
1680                                                 !strcmp(plugin->title, src_plugingui->title)) result = 1;
1681                                 }
1682                         }
1683                 }
1686 // Doesn't exist anymore
1687                 if(!result)
1688                 {
1689                         hide_plugin(src_plugin, 0);
1690                         i--;
1691                 }
1692         }
1693         plugin_gui_lock->unlock();
1697 void MWindow::update_plugin_titles()
1699         for(int i = 0; i < plugin_guis->total; i++)
1700         {
1701                 plugin_guis->values[i]->update_title();
1702         }
1705 int MWindow::asset_to_edl(EDL *new_edl, 
1706         Asset *new_asset, 
1707         RecordLabels *labels)
1709 //printf("MWindow::asset_to_edl 1\n");
1710 //      new_edl->load_defaults(defaults);
1712 // Keep frame rate, sample rate, and output size unchanged.
1713 // These parameters would revert the project if VWindow displayed an asset
1714 // of different size than the project.
1715         if(new_asset->video_data)
1716         {
1717                 new_edl->session->video_tracks = new_asset->layers;
1718 //              new_edl->session->frame_rate = new_asset->frame_rate;
1719 //              new_edl->session->output_w = new_asset->width;
1720 //              new_edl->session->output_h = new_asset->height;
1721         }
1722         else
1723                 new_edl->session->video_tracks = 0;
1730         if(new_asset->audio_data)
1731         {
1732                 new_edl->session->audio_tracks = new_asset->channels;
1733 //              new_edl->session->sample_rate = new_asset->sample_rate;
1734         }
1735         else
1736                 new_edl->session->audio_tracks = 0;
1737 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1739         new_edl->create_default_tracks();
1740 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1742 // Disable drawing if the file format isn't fast enough.
1743 // MPEG is now faster than most other codecs.
1744 //      if(new_asset->format == FILE_MPEG)
1745 //      {
1746 //              for(Track *current = new_edl->tracks->first;
1747 //                      current;
1748 //                      current = NEXT)
1749 //              {
1750 //                      if(current->data_type == TRACK_VIDEO) current->draw = 0;
1751 //              }
1752 //      }
1756 //printf("MWindow::asset_to_edl 3\n");
1757         new_edl->insert_asset(new_asset, 0, 0, labels);
1758 //printf("MWindow::asset_to_edl 3\n");
1764         char string[BCTEXTLEN];
1765         FileSystem fs;
1766         fs.extract_name(string, new_asset->path);
1767 //printf("MWindow::asset_to_edl 3\n");
1769         strcpy(new_edl->local_session->clip_title, string);
1770 //printf("MWindow::asset_to_edl 4 %s\n", string);
1772 //      new_edl->dump();
1773         return 0;
1776 // Reset everything after a load.
1777 void MWindow::update_project(int load_mode)
1779         restart_brender();
1780         edl->tracks->update_y_pixels(theme);
1783         gui->update(1, 1, 1, 1, 1, 1, 1);
1785         cwindow->update(0, 0, 1, 1, 1);
1788         if(load_mode == LOAD_REPLACE ||
1789                 load_mode == LOAD_REPLACE_CONCATENATE)
1790         {
1791                 vwindow->change_source();
1792         }
1793         else
1794         {
1795                 vwindow->update(1);
1796         }
1798         cwindow->gui->slider->set_position();
1799         cwindow->gui->timebar->update(1, 1);
1800         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1801                 CHANGE_ALL,
1802                 edl,
1803                 1);
1805         awindow->gui->lock_window("MWindow::update_project");
1806         awindow->gui->update_assets();
1807         awindow->gui->flush();
1808         awindow->gui->unlock_window();
1809         gui->flush();
1813 void MWindow::rebuild_indices()
1815         char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
1817         for(int i = 0; i < session->drag_assets->total; i++)
1818         {
1819 //printf("MWindow::rebuild_indices 1 %s\n", session->drag_assets->values[i]->path);
1820 // Erase file
1821                 IndexFile::get_index_filename(source_filename, 
1822                         preferences->index_directory,
1823                         index_filename, 
1824                         session->drag_assets->values[i]->path);
1825                 remove(index_filename);
1826 // Schedule index build
1827                 session->drag_assets->values[i]->index_status = INDEX_NOTTESTED;
1828                 mainindexes->add_next_asset(0, session->drag_assets->values[i]);
1829         }
1830         mainindexes->start_build();
1834 void MWindow::save_backup()
1836         FileXML file;
1837         edl->set_project_path(session->filename);
1838         edl->save_xml(plugindb, 
1839                 &file, 
1840                 BACKUP_PATH,
1841                 0,
1842                 0);
1843         file.terminate_string();
1844         char path[BCTEXTLEN];
1845         FileSystem fs;
1846         strcpy(path, BACKUP_PATH);
1847         fs.complete_path(path);
1849         if(file.write_to_file(path))
1850         {
1851                 char string2[256];
1852                 sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
1853                 gui->show_message(string2);
1854         }
1858 int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
1860         int denominator;
1861         if(!width || !height) return 1;
1862         float fraction = (float)width / height;
1864         for(denominator = 1; 
1865                 denominator < 100 && 
1866                         fabs(fraction * denominator - (int)(fraction * denominator)) > .001; 
1867                 denominator++)
1868                 ;
1870         w = denominator * width / height;
1871         h = denominator;
1872         return 0;
1875 void MWindow::reset_caches()
1877         audio_cache->remove_all();
1878         video_cache->remove_all();
1879         if(cwindow->playback_engine && cwindow->playback_engine->audio_cache)
1880                 cwindow->playback_engine->audio_cache->remove_all();
1881         if(cwindow->playback_engine && cwindow->playback_engine->video_cache)
1882                 cwindow->playback_engine->video_cache->remove_all();
1883         if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
1884                 vwindow->playback_engine->audio_cache->remove_all();
1885         if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
1886                 vwindow->playback_engine->video_cache->remove_all();
1889 void MWindow::remove_asset_from_caches(Asset *asset)
1891         audio_cache->delete_entry(asset);
1892         video_cache->delete_entry(asset);
1893         if(cwindow->playback_engine && cwindow->playback_engine->audio_cache)
1894                 cwindow->playback_engine->audio_cache->delete_entry(asset);
1895         if(cwindow->playback_engine && cwindow->playback_engine->video_cache)
1896                 cwindow->playback_engine->video_cache->delete_entry(asset);
1897         if(vwindow->playback_engine && vwindow->playback_engine->audio_cache)
1898                 vwindow->playback_engine->audio_cache->delete_entry(asset);
1899         if(vwindow->playback_engine && vwindow->playback_engine->video_cache)
1900                 vwindow->playback_engine->video_cache->delete_entry(asset);
1905 void MWindow::remove_assets_from_project(int push_undo)
1907         for(int i = 0; i < session->drag_assets->total; i++)
1908         {
1909                 Asset *asset = session->drag_assets->values[i];
1910                 remove_asset_from_caches(asset);
1911         }
1913 // Remove from VWindow.
1914         for(int i = 0; i < session->drag_clips->total; i++)
1915         {
1916                 if(session->drag_clips->values[i] == vwindow->get_edl())
1917                 {
1918                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 1");
1919                         vwindow->remove_source();
1920                         vwindow->gui->unlock_window();
1921                 }
1922         }
1923         
1924         for(int i = 0; i < session->drag_assets->total; i++)
1925         {
1926                 if(session->drag_assets->values[i] == vwindow->get_asset())
1927                 {
1928                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
1929                         vwindow->remove_source();
1930                         vwindow->gui->unlock_window();
1931                 }
1932         }
1933         
1934         edl->remove_from_project(session->drag_assets);
1935         edl->remove_from_project(session->drag_clips);
1936         save_backup();
1937         if(push_undo) undo->update_undo(_("remove assets"), LOAD_ALL);
1938         restart_brender();
1940         gui->lock_window("MWindow::remove_assets_from_project 3");
1941         gui->update(1,
1942                 1,
1943                 1,
1944                 1,
1945                 0, 
1946                 1,
1947                 0);
1948         gui->unlock_window();
1950         awindow->gui->lock_window("MWindow::remove_assets_from_project 4");
1951         awindow->gui->update_assets();
1952         awindow->gui->flush();
1953         awindow->gui->unlock_window();
1955 // Removes from playback here
1956         sync_parameters(CHANGE_ALL);
1959 void MWindow::remove_assets_from_disk()
1961 // Remove from disk
1962         for(int i = 0; i < session->drag_assets->total; i++)
1963         {
1964                 remove(session->drag_assets->values[i]->path);
1965         }
1967         remove_assets_from_project(1);
1970 void MWindow::dump_plugins()
1972         for(int i = 0; i < plugindb->total; i++)
1973         {
1974                 printf("audio=%d video=%d realtime=%d transition=%d theme=%d %s\n",
1975                         plugindb->values[i]->audio,
1976                         plugindb->values[i]->video,
1977                         plugindb->values[i]->realtime,
1978                         plugindb->values[i]->transition,
1979                         plugindb->values[i]->theme,
1980                         plugindb->values[i]->title);
1981         }
2008 int MWindow::save_defaults()
2010         gui->save_defaults(defaults);
2011         edl->save_defaults(defaults);
2012         session->save_defaults(defaults);
2013         preferences->save_defaults(defaults);
2015         defaults->save();
2016         return 0;
2019 int MWindow::run_script(FileXML *script)
2021         int result = 0, result2 = 0;
2022         while(!result && !result2)
2023         {
2024                 result = script->read_tag();
2025                 if(!result)
2026                 {
2027                         if(script->tag.title_is("new_project"))
2028                         {
2029 // Run new in immediate mode.
2030 //                              gui->mainmenu->new_project->run_script(script);
2031                         }
2032                         else
2033                         if(script->tag.title_is("record"))
2034                         {
2035 // Run record as a thread.  It is a terminal command.
2036                                 ;
2037 // Will read the complete scipt file without letting record read it if not
2038 // terminated.
2039                                 result2 = 1;
2040                         }
2041                         else
2042                         {
2043                                 printf("MWindow::run_script: Unrecognized command: %s\n",script->tag.get_title() );
2044                         }
2045                 }
2046         }
2047         return result2;
2050 // ================================= synchronization
2053 int MWindow::interrupt_indexes()
2055         mainindexes->interrupt_build();
2056         return 0; 
2061 void MWindow::next_time_format()
2063         switch(edl->session->time_format)
2064         {
2065                 case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
2066                 case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
2067                 case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
2068                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
2069                 case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
2070                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
2071                 case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
2072         }
2074         time_format_common();
2077 void MWindow::prev_time_format()
2079         switch(edl->session->time_format)
2080         {
2081                 case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
2082                 case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
2083                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
2084                 case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
2085                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
2086                 case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
2087                 case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
2088         }
2090         time_format_common();
2093 void MWindow::time_format_common()
2095         gui->lock_window("MWindow::next_time_format");
2096         gui->redraw_time_dependancies();
2097         char string[BCTEXTLEN], string2[BCTEXTLEN];
2098         sprintf(string, _("Using %s."), Units::print_time_format(edl->session->time_format, string2));
2099         gui->show_message(string);
2100         gui->flush();
2101         gui->unlock_window();
2105 int MWindow::set_filename(char *filename)
2107         strcpy(session->filename, filename);
2108         if(gui)
2109         {
2110                 if(filename[0] == 0)
2111                 {
2112                         gui->set_title(PROGRAM_NAME);
2113                 }
2114                 else
2115                 {
2116                         FileSystem dir;
2117                         char string[BCTEXTLEN], string2[BCTEXTLEN];
2118                         dir.extract_name(string, filename);
2119                         sprintf(string2, PROGRAM_NAME ": %s", string);
2120                         gui->set_title(string2);
2121                 }
2122         }
2123         return 0; 
2133 int MWindow::set_loop_boundaries()
2135         double start = edl->local_session->get_selectionstart();
2136         double end = edl->local_session->get_selectionend();
2137         
2138         if(start != 
2139                 end) 
2140         {
2141                 ;
2142         }
2143         else
2144         if(edl->tracks->total_length())
2145         {
2146                 start = 0;
2147                 end = edl->tracks->total_length();
2148         }
2149         else
2150         {
2151                 start = end = 0;
2152         }
2154         if(edl->local_session->loop_playback && start != end)
2155         {
2156                 edl->local_session->loop_start = start;
2157                 edl->local_session->loop_end = end;
2158         }
2159         return 0; 
2168 int MWindow::reset_meters()
2170         cwindow->gui->lock_window("MWindow::reset_meters 1");
2171         cwindow->gui->meters->reset_meters();
2172         cwindow->gui->unlock_window();
2174         vwindow->gui->lock_window("MWindow::reset_meters 2");
2175         vwindow->gui->meters->reset_meters();
2176         vwindow->gui->unlock_window();
2178         lwindow->gui->lock_window("MWindow::reset_meters 3");
2179         lwindow->gui->panel->reset_meters();
2180         lwindow->gui->unlock_window();
2182         gui->lock_window("MWindow::reset_meters 4");
2183         gui->patchbay->reset_meters();
2184         gui->unlock_window();
2185         return 0;