r793: Small API addon, so plugins can 'see' camera and projector automation
[cinelerra_cv/mob.git] / cinelerra / mwindow.C
blob045c7c54751e11d27763c47d999410e2ddfeb930
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 "brender.h"
8 #include "cache.h"
9 #include "channel.h"
10 #include "channeldb.h"
11 #include "clip.h"
12 #include "colormodels.h"
13 #include "cplayback.h"
14 #include "ctimebar.h"
15 #include "cwindowgui.h"
16 #include "cwindow.h"
17 #include "defaults.h"
18 #include "editpanel.h"
19 #include "edl.h"
20 #include "edlsession.h"
21 #include "errorbox.h"
22 #include "fileformat.h"
23 #include "file.h"
24 #include "filesystem.h"
25 #include "filexml.h"
26 #include "gwindow.h"
27 #include "gwindowgui.h"
28 #include "indexfile.h"
29 #include "interlacemodes.h"
30 #include "language.h"
31 #include "levelwindowgui.h"
32 #include "levelwindow.h"
33 #include "loadfile.inc"
34 #include "localsession.h"
35 #include "maincursor.h"
36 #include "mainindexes.h"
37 #include "mainmenu.h"
38 #include "mainprogress.h"
39 #include "mainsession.h"
40 #include "mainundo.h"
41 #include "mbuttons.h"
42 #include "mutex.h"
43 #include "mwindowgui.h"
44 #include "mwindow.h"
45 #include "new.h"
46 #include "patchbay.h"
47 #include "playbackengine.h"
48 #include "plugin.h"
49 #include "pluginserver.h"
50 #include "pluginset.h"
51 #include "preferences.h"
52 #include "record.h"
53 #include "recordlabel.h"
54 #include "render.h"
55 #include "samplescroll.h"
56 #include "sighandler.h"
57 #include "splashgui.h"
58 #include "statusbar.h"
59 #include "theme.h"
60 #include "threadloader.h"
61 #include "timebar.h"
62 #include "tipwindow.h"
63 #include "trackcanvas.h"
64 #include "track.h"
65 #include "tracking.h"
66 #include "trackscroll.h"
67 #include "tracks.h"
68 #include "transition.h"
69 #include "transportque.h"
70 #include "vframe.h"
71 #include "videodevice.inc"
72 #include "videowindow.h"
73 #include "vplayback.h"
74 #include "vwindowgui.h"
75 #include "vwindow.h"
76 #include "zoombar.h"
77 #include "exportedl.h"
79 #include <string.h>
83 extern "C"
89 // Hack for libdv to remove glib dependancy
91 // void
92 // g_log (const char    *log_domain,
93 //        int  log_level,
94 //        const char    *format,
95 //        ...)
96 // {
97 // }
98 // 
99 // void
100 // g_logv (const char    *log_domain,
101 //        int  log_level,
102 //        const char    *format,
103 //        ...)
104 // {
105 // }
106 // 
109 // Hack for XFree86 4.1.0
111 int atexit(void (*function)(void))
113         return 0;
124 MWindow::MWindow()
126         plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
127         brender_lock = new Mutex("MWindow::brender_lock");
128         brender = 0;
129         session = 0;
130         channeldb_buz = new ChannelDB;
131         channeldb_v4l2jpeg = new ChannelDB;
134 MWindow::~MWindow()
136         brender_lock->lock("MWindow::~MWindow");
137         if(brender) delete brender;
138         brender = 0;
139         brender_lock->unlock();
140         delete brender_lock;
142         delete mainindexes;
144 TRACE("MWindow::~MWindow 1\n");
145         clean_indexes();
146 TRACE("MWindow::~MWindow 2\n");
148         save_defaults();
149 TRACE("MWindow::~MWindow 3\n");
150 // Give up and go to a movie
151         exit(0);
153 TRACE("MWindow::~MWindow 4\n");
154         delete mainprogress;
155         delete audio_cache;             // delete the cache after the assets
156         delete video_cache;             // delete the cache after the assets
157         if(gui) delete gui;
158         delete undo;
159         delete preferences;
160         delete defaults;
161         delete render;
162 //      delete renderlist;
163         delete awindow;
164         delete vwindow;
165         delete cwindow;
166         delete lwindow;
167         plugin_guis->remove_all_objects();
168         delete plugin_guis;
169         delete plugin_gui_lock;
172 void MWindow::init_defaults(Defaults* &defaults, char *config_path)
174         char path[BCTEXTLEN];
175 // Use user supplied path
176         if(config_path[0])
177         {
178                 strcpy(path, config_path);
179         }
180         else
181         {
182 // set the .bcast path
183                 FileSystem fs;
185                 sprintf(path, "%s", BCASTDIR);
186                 fs.complete_path(path);
187                 if(fs.is_dir(path)) 
188                 {
189                         fs.create_dir(path); 
190                 }
192 // load the defaults
193                 strcat(path, "Cinelerra_rc");
194         }
196         defaults = new Defaults(path);
197         defaults->load();
200 void MWindow::init_plugin_path(Preferences *preferences, 
201         ArrayList<PluginServer*>* &plugindb,
202         FileSystem *fs,
203         SplashGUI *splash_window,
204         int *counter)
206         int result = 0;
207         PluginServer *newplugin;
209         if(!result)
210         {
211                 for(int i = 0; i < fs->dir_list.total; i++)
212                 {
213                         char path[BCTEXTLEN];
214                         strcpy(path, fs->dir_list.values[i]->path);
216 // File is a directory
217                         if(!fs->is_dir(path))
218                         {
219                                 continue;
220                         }
221                         else
222                         {
223 // Try to query the plugin
224                                 fs->complete_path(path);
225 //printf("MWindow::init_plugin_path %s\n", path);
226                                 PluginServer *new_plugin = new PluginServer(path);
227                                 int result = new_plugin->open_plugin(1, preferences, 0, 0, -1);
229                                 if(!result)
230                                 {
231                                         plugindb->append(new_plugin);
232                                         new_plugin->close_plugin();
233                                         if(splash_window)
234                                                 splash_window->operation->update(_(new_plugin->title));
235                                 }
236                                 else
237                                 if(result == PLUGINSERVER_IS_LAD)
238                                 {
239                                         delete new_plugin;
240 // Open LAD subplugins
241                                         int id = 0;
242                                         do
243                                         {
244                                                 new_plugin = new PluginServer(path);
245                                                 result = new_plugin->open_plugin(1,
246                                                         preferences,
247                                                         0,
248                                                         0,
249                                                         id);
250                                                 id++;
251                                                 if(!result)
252                                                 {
253                                                         plugindb->append(new_plugin);
254                                                         new_plugin->close_plugin();
255                                                         if(splash_window)
256                                                                 splash_window->operation->update(_(new_plugin->title));
257                                                 }
258                                         }while(!result);
259                                 }
260                                 else
261                                 {
262 // Plugin failed to open
263                                         delete new_plugin;
264                                 }
265                         }
266                         if(splash_window) splash_window->progress->update((*counter)++);
267                 }
268         }
271 void MWindow::init_plugins(Preferences *preferences, 
272         ArrayList<PluginServer*>* &plugindb,
273         SplashGUI *splash_window)
275         plugindb = new ArrayList<PluginServer*>;
279         FileSystem cinelerra_fs;
280         ArrayList<FileSystem*> lad_fs;
281         int result = 0;
283 // Get directories
284         cinelerra_fs.set_filter("[*.plugin][*.so]");
285         result = cinelerra_fs.update(preferences->global_plugin_dir);
287         if(result)
288         {
289                 fprintf(stderr, 
290                         _("MWindow::init_plugins: couldn't open %s directory\n"),
291                         preferences->global_plugin_dir);
292         }
294 // Parse LAD environment variable
295         char *env = getenv("LADSPA_PATH");
296         if(env)
297         {
298                 char string[BCTEXTLEN];
299                 char *ptr1 = env;
300                 while(ptr1)
301                 {
302                         char *ptr = strchr(ptr1, ':');
303                         char *end;
304                         if(ptr)
305                         {
306                                 end = ptr;
307                         }
308                         else
309                         {
310                                 end = env + strlen(env);
311                         }
313                         if(end > ptr1)
314                         {
315                                 int len = end - ptr1;
316                                 memcpy(string, ptr1, len);
317                                 string[len] = 0;
320                                 FileSystem *fs = new FileSystem;
321                                 lad_fs.append(fs);
322                                 fs->set_filter("*.so");
323                                 result = fs->update(string);
325                                 if(result)
326                                 {
327                                         fprintf(stderr, 
328                                                 _("MWindow::init_plugins: couldn't open %s directory\n"),
329                                                 string);
330                                 }
331                         }
333                         if(ptr)
334                                 ptr1 = ptr + 1;
335                         else
336                                 ptr1 = ptr;
337                 };
338         }
340         int total = cinelerra_fs.total_files();
341         int counter = 0;
342         for(int i = 0; i < lad_fs.total; i++)
343                 total += lad_fs.values[i]->total_files();
344         if(splash_window) splash_window->progress->update_length(total);
346 // Cinelerra
347 #ifndef DO_STATIC
348         init_plugin_path(preferences,
349                 plugindb,
350                 &cinelerra_fs,
351                 splash_window,
352                 &counter);
353 #else
354 // Call automatically generated routine to get plugins
355 #endif
357 // LAD
358         for(int i = 0; i < lad_fs.total; i++)
359                 init_plugin_path(preferences,
360                         plugindb,
361                         lad_fs.values[i],
362                         splash_window,
363                         &counter);
365         lad_fs.remove_all_objects();
368 void MWindow::delete_plugins()
370         for(int i = 0; i < plugindb->total; i++)
371         {
372                 delete plugindb->values[i];
373         }
374         delete plugindb;
377 void MWindow::create_plugindb(int do_audio, 
378                 int do_video, 
379                 int is_realtime, 
380                 int is_transition,
381                 int is_theme,
382                 ArrayList<PluginServer*> &plugindb)
384 // Get plugins
385         for(int i = 0; i < this->plugindb->total; i++)
386         {
387                 PluginServer *current = this->plugindb->values[i];
389                 if(current->audio == do_audio &&
390                         current->video == do_video &&
391                         (current->realtime == is_realtime || is_realtime < 0) &&
392                         current->transition == is_transition &&
393                         current->theme == is_theme)
394                         plugindb.append(current);
395         }
397 // Alphabetize list by title
398         int done = 0;
399         while(!done)
400         {
401                 done = 1;
402                 
403                 for(int i = 0; i < plugindb.total - 1; i++)
404                 {
405                         PluginServer *value1 = plugindb.values[i];
406                         PluginServer *value2 = plugindb.values[i + 1];
407                         if(strcmp(_(value1->title), _(value2->title)) > 0)
408                         {
409                                 done = 0;
410                                 plugindb.values[i] = value2;
411                                 plugindb.values[i + 1] = value1;
412                         }
413                 }
414         }
417 PluginServer* MWindow::scan_plugindb(char *title,
418                 int data_type)
420         if(data_type < 0)
421         {
422                 printf("MWindow::scan_plugindb data_type < 0\n");
423                 return 0;
424         }
426         for(int i = 0; i < plugindb->total; i++)
427         {
428                 PluginServer *server = plugindb->values[i];
429                 if(!strcasecmp(server->title, title) &&
430                 ((data_type == TRACK_AUDIO && server->audio) ||
431                 (data_type == TRACK_VIDEO && server->video))) 
432                         return plugindb->values[i];
433         }
434         return 0;
437 void MWindow::init_preferences()
439         preferences = new Preferences;
440         preferences->load_defaults(defaults);
441         session = new MainSession(this);
442         session->load_defaults(defaults);
445 void MWindow::clean_indexes()
447         FileSystem fs;
448         int total_excess;
449         long oldest;
450         int oldest_item = -1;
451         int result;
452         char string[BCTEXTLEN];
453         char string2[BCTEXTLEN];
455 // Delete extra indexes
456         fs.set_filter("*.idx");
457         fs.complete_path(preferences->index_directory);
458         fs.update(preferences->index_directory);
459 //printf("MWindow::clean_indexes 1 %d\n", fs.dir_list.total);
461 // Eliminate directories
462         result = 1;
463         while(result)
464         {
465                 result = 0;
466                 for(int i = 0; i < fs.dir_list.total && !result; i++)
467                 {
468                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
469                         if(!fs.is_dir(string))
470                         {
471                                 delete fs.dir_list.values[i];
472                                 fs.dir_list.remove_number(i);
473                                 result = 1;
474                         }
475                 }
476         }
477         total_excess = fs.dir_list.total - preferences->index_count;
479 //printf("MWindow::clean_indexes 2 %d\n", fs.dir_list.total);
480         while(total_excess > 0)
481         {
482 // Get oldest
483                 for(int i = 0; i < fs.dir_list.total; i++)
484                 {
485                         fs.join_names(string, preferences->index_directory, fs.dir_list.values[i]->name);
487                         if(i == 0 || fs.get_date(string) <= oldest)
488                         {
489                                 oldest = fs.get_date(string);
490                                 oldest_item = i;
491                         }
492                 }
494                 if(oldest_item >= 0)
495                 {
496 // Remove index file
497                         fs.join_names(string, 
498                                 preferences->index_directory, 
499                                 fs.dir_list.values[oldest_item]->name);
500 //printf("MWindow::clean_indexes 1 %s\n", string);
501                         if(remove(string))
502                                 perror("delete_indexes");
503                         delete fs.dir_list.values[oldest_item];
504                         fs.dir_list.remove_number(oldest_item);
506 // Remove table of contents if it exists
507                         strcpy(string2, string);
508                         char *ptr = strrchr(string2, '.');
509                         if(ptr)
510                         {
511 //printf("MWindow::clean_indexes 2 %s\n", string2);
512                                 sprintf(ptr, ".toc");
513                                 remove(string2);
514                         }
515                 }
517                 total_excess--;
518         }
521 void MWindow::init_awindow()
523         awindow = new AWindow(this);
524         awindow->create_objects();
527 void MWindow::init_gwindow()
529         gwindow = new GWindow(this);
530         gwindow->create_objects();
533 void MWindow::init_tipwindow()
535         twindow = new TipWindow(this);
536         twindow->start();
539 void MWindow::init_theme()
541         theme = 0;
543 // Replace blond theme with SUV since it doesn't work
544         if(!strcasecmp(preferences->theme, "Blond"))
545                 strcpy(preferences->theme, DEFAULT_THEME);
547         for(int i = 0; i < plugindb->total; i++)
548         {
549                 if(plugindb->values[i]->theme &&
550                         !strcasecmp(preferences->theme, plugindb->values[i]->title))
551                 {
552                         PluginServer plugin = *plugindb->values[i];
553                         plugin.open_plugin(0, preferences, 0, 0, -1);
554                         theme = plugin.new_theme();
555                         theme->mwindow = this;
556                         strcpy(theme->path, plugin.path);
557                         plugin.close_plugin();
558                 }
559         }
561         if(!theme)
562         {
563                 fprintf(stderr, _("MWindow::init_theme: theme %s not found.\n"), preferences->theme);
564                 exit(1);
565         }
567 // Load images which may have been forgotten
568         theme->Theme::initialize();
569 // Load user images
570         theme->initialize();
571 // Create menus with user colors
572         theme->build_menus();
573         init_menus();
575         theme->check_used();
578 void MWindow::init_edl()
580         edl = new EDL;
581         edl->create_objects();
582     edl->load_defaults(defaults);
583         edl->create_default_tracks();
584         edl->tracks->update_y_pixels(theme);
587 void MWindow::init_compositor()
589         cwindow = new CWindow(this);
590     cwindow->create_objects();
593 void MWindow::init_levelwindow()
595         lwindow = new LevelWindow(this);
596         lwindow->create_objects();
599 void MWindow::init_viewer()
601         vwindow = new VWindow(this);
602         vwindow->load_defaults();
603         vwindow->create_objects();
606 void MWindow::init_cache()
608         audio_cache = new CICache(edl, preferences, plugindb);
609         video_cache = new CICache(edl, preferences, plugindb);
612 void MWindow::init_channeldb()
614         channeldb_buz->load("channeldb_buz");
615         channeldb_v4l2jpeg->load("channeldb_v4l2jpeg");
618 void MWindow::init_menus()
620         char string[BCTEXTLEN];
622         // Color Models
623         cmodel_to_text(string, BC_RGB888);
624         colormodels.append(new ColormodelItem(string, BC_RGB888));
625         cmodel_to_text(string, BC_RGBA8888);
626         colormodels.append(new ColormodelItem(string, BC_RGBA8888));
627 //      cmodel_to_text(string, BC_RGB161616);
628 //      colormodels.append(new ColormodelItem(string, BC_RGB161616));
629 //      cmodel_to_text(string, BC_RGBA16161616);
630 //      colormodels.append(new ColormodelItem(string, BC_RGBA16161616));
631         cmodel_to_text(string, BC_RGB_FLOAT);
632         colormodels.append(new ColormodelItem(string, BC_RGB_FLOAT));
633         cmodel_to_text(string, BC_RGBA_FLOAT);
634         colormodels.append(new ColormodelItem(string, BC_RGBA_FLOAT));
635         cmodel_to_text(string, BC_YUV888);
636         colormodels.append(new ColormodelItem(string, BC_YUV888));
637         cmodel_to_text(string, BC_YUVA8888);
638         colormodels.append(new ColormodelItem(string, BC_YUVA8888));
639 //      cmodel_to_text(string, BC_YUV161616);
640 //      colormodels.append(new ColormodelItem(string, BC_YUV161616));
641 //      cmodel_to_text(string, BC_YUVA16161616);
642 //      colormodels.append(new ColormodelItem(string, BC_YUVA16161616));
644 #define ILACEPROJECTMODELISTADD(x) ilacemode_to_text(string, x); \
645                            interlace_project_modes.append(new InterlacemodeItem(string, x));
647 #define ILACEASSETMODELISTADD(x) ilacemode_to_text(string, x); \
648                            interlace_asset_modes.append(new InterlacemodeItem(string, x));
650 #define ILACEFIXMETHODLISTADD(x) ilacefixmethod_to_text(string, x); \
651                            interlace_asset_fixmethods.append(new InterlacefixmethodItem(string, x));
653         // Interlacing Modes
654         ILACEASSETMODELISTADD(BC_ILACE_MODE_UNDETECTED); // Not included in the list for the project options.
656         ILACEASSETMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
657         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_TOP_FIRST);
659         ILACEASSETMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
660         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_BOTTOM_FIRST);
662         ILACEASSETMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
663         ILACEPROJECTMODELISTADD(BC_ILACE_MODE_NOTINTERLACED);
665         // Interlacing Fixing Methods
666         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_NONE);
667         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_UPONE);
668         ILACEFIXMETHODLISTADD(BC_ILACE_FIXMETHOD_DOWNONE);
671 void MWindow::init_indexes()
673         mainindexes = new MainIndexes(this);
674         mainindexes->start_loop();
677 void MWindow::init_gui()
679         gui = new MWindowGUI(this);
680         gui->create_objects();
681         gui->load_defaults(defaults);
684 void MWindow::init_signals()
686         sighandler = new SigHandler;
687         sighandler->initialize();
688 ENABLE_BUFFER
691 void MWindow::init_render()
693         render = new Render(this);
694 //      renderlist = new Render(this);
695         batch_render = new BatchRenderThread(this);
698 void MWindow::init_exportedl()
700         exportedl = new ExportEDL(this);
703 void MWindow::init_brender()
705         if(preferences->use_brender && !brender)
706         {
707                 brender_lock->lock("MWindow::init_brender 1");
708                 brender = new BRender(this);
709                 brender->initialize();
710                 session->brender_end = 0;
711                 brender_lock->unlock();
712         }
713         else
714         if(!preferences->use_brender && brender)
715         {
716                 brender_lock->lock("MWindow::init_brender 2");
717                 delete brender;
718                 brender = 0;
719                 session->brender_end = 0;
720                 brender_lock->unlock();
721         }
722         if(brender) brender->restart(edl);
725 void MWindow::restart_brender()
727 //printf("MWindow::restart_brender 1\n");
728         if(brender) brender->restart(edl);
731 void MWindow::stop_brender()
733         if(brender) brender->stop();
736 int MWindow::brender_available(int position)
738         int result = 0;
739         brender_lock->lock("MWindow::brender_available 1");
740         if(brender)
741         {
742                 if(brender->map_valid)
743                 {
744                         brender->map_lock->lock("MWindow::brender_available 2");
745                         if(position < brender->map_size &&
746                                 position >= 0)
747                         {
748 //printf("MWindow::brender_available 1 %d %d\n", position, brender->map[position]);
749                                 if(brender->map[position] == BRender::RENDERED)
750                                         result = 1;
751                         }
752                         brender->map_lock->unlock();
753                 }
754         }
755         brender_lock->unlock();
756         return result;
759 void MWindow::set_brender_start()
761         edl->session->brender_start = edl->local_session->get_selectionstart();
762         restart_brender();
763         gui->canvas->draw_overlays();
764         gui->canvas->flash();
769 int MWindow::load_filenames(ArrayList<char*> *filenames, 
770         int load_mode,
771         int update_filename,
772         char *reel_name,
773         int reel_number,
774         int overwrite_reel)
776 TRACE("MWindow::load_filenames 1");
777         ArrayList<EDL*> new_edls;
778         ArrayList<Asset*> new_assets;
779         ArrayList<File*> new_files;
781         save_defaults();
782         gui->start_hourglass();
784 // Need to stop playback since tracking depends on the EDL not getting
785 // deleted.
786         cwindow->playback_engine->que->send_command(STOP,
787                 CHANGE_NONE, 
788                 0,
789                 0);
790         vwindow->playback_engine->que->send_command(STOP,
791                 CHANGE_NONE, 
792                 0,
793                 0);
794         cwindow->playback_engine->interrupt_playback(0);
795         vwindow->playback_engine->interrupt_playback(0);
798 TRACE("MWindow::load_filenames 80");
800 // Define new_edls and new_assets to load
801         int result = 0;
802         for(int i = 0; i < filenames->total; i++)
803         {
804 // Get type of file
805                 File *new_file = new File;
806                 Asset *new_asset = new Asset(filenames->values[i]);
807                 EDL *new_edl = new EDL;
808                 char string[BCTEXTLEN];
810 // Set reel name and number for the asset
811 // If the user wants to overwrite the last used reel number for the clip,
812 // we have to rebuild the index for the file
814                 if(overwrite_reel)
815                 {
816                         char source_filename[BCTEXTLEN];
817                         char index_filename[BCTEXTLEN];
818                         
819                         strcpy(new_asset->reel_name, reel_name);
820                         new_asset->reel_number = reel_number;
822                         IndexFile::get_index_filename(source_filename,
823                                 preferences->index_directory,
824                                 index_filename,
825                                 new_asset->path);
826                         remove(index_filename);
827                         new_asset->index_status = INDEX_NOTTESTED;
828                 }
829                 
830                 new_edl->create_objects();
831                 new_edl->copy_session(edl);
833                 sprintf(string, "Loading %s", new_asset->path);
834                 gui->show_message(string);
835 TRACE("MWindow::load_filenames 81");
836                 result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
837 TRACE("MWindow::load_filenames 82");
839                 switch(result)
840                 {
841 // Convert media file to EDL
842                         case FILE_OK:
843                                 if(load_mode != LOAD_RESOURCESONLY)
844                                 {
845 TRACE("MWindow::load_filenames 83");
846                                         asset_to_edl(new_edl, new_asset);
847 TRACE("MWindow::load_filenames 84");
848                                         new_edls.append(new_edl);
849 TRACE("MWindow::load_filenames 85");
850                                         delete new_asset;
851                                         new_asset = 0;
852 TRACE("MWindow::load_filenames 86");
853                                 }
854                                 else
855                                 {
856                                         new_assets.append(new_asset);
857                                 }
859 // Set filename to nothing for assets since save EDL would overwrite them.
860                                 if(load_mode == LOAD_REPLACE || 
861                                         load_mode == LOAD_REPLACE_CONCATENATE)
862                                 {
863                                         set_filename("");
864 // Reset timeline position
865                                         new_edl->local_session->view_start = 0;
866                                         new_edl->local_session->track_start = 0;
867                                 }
869                                 result = 0;
870                                 break;
872 // File not found
873                         case FILE_NOT_FOUND:
874                                 sprintf(string, _("Failed to open %s"), new_asset->path);
875                                 gui->show_message(string, theme->message_error);
876                                 result = 1;
877                                 break;
879 // Unknown format
880                         case FILE_UNRECOGNIZED_CODEC:
881                         {
882 // Test index file
883                                 IndexFile indexfile(this);
884                                 result = indexfile.open_index(this, new_asset);
885                                 if(!result)
886                                 {
887                                         indexfile.close_index();
888                                 }
890 // Test existing EDLs
891                                 if(result)
892                                 {
893                                         for(int j = 0; j < new_edls.total + 1; j++)
894                                         {
895                                                 Asset *old_asset;
896                                                 if(j == new_edls.total)
897                                                 {
898                                                         if(old_asset = edl->assets->get_asset(new_asset->path))
899                                                         {
900                                                                 *new_asset = *old_asset;
901                                                                 result = 0;
902                                                         }
903                                                 }
904                                                 else
905                                                 {
906                                                         if(old_asset = new_edls.values[j]->assets->get_asset(new_asset->path))
907                                                         {
908                                                                 *new_asset = *old_asset;
909                                                                 result = 0;
910                                                         }
911                                                 }
912                                         }
913                                 }
915 // Prompt user
916                                 if(result)
917                                 {
918                                         char string[BCTEXTLEN];
919                                         FileSystem fs;
920                                         fs.extract_name(string, new_asset->path);
922                                         strcat(string, _("'s format couldn't be determined."));
923                                         new_asset->audio_data = 1;
924                                         new_asset->format = FILE_PCM;
925                                         new_asset->channels = defaults->get("AUDIO_CHANNELS", 2);
926                                         new_asset->sample_rate = defaults->get("SAMPLE_RATE", 44100);
927                                         new_asset->bits = defaults->get("AUDIO_BITS", 16);
928                                         new_asset->byte_order = defaults->get("BYTE_ORDER", 1);
929                                         new_asset->signed_ = defaults->get("SIGNED_", 1);
930                                         new_asset->header = defaults->get("HEADER", 0);
932                                         FileFormat fwindow(this);
933                                         fwindow.create_objects(new_asset, string);
934                                         result = fwindow.run_window();
936                                         defaults->update("AUDIO_CHANNELS", new_asset->channels);
937                                         defaults->update("SAMPLE_RATE", new_asset->sample_rate);
938                                         defaults->update("AUDIO_BITS", new_asset->bits);
939                                         defaults->update("BYTE_ORDER", new_asset->byte_order);
940                                         defaults->update("SIGNED_", new_asset->signed_);
941                                         defaults->update("HEADER", new_asset->header);
942                                         save_defaults();
943                                 }
945 // Append to list
946                                 if(!result)
947                                 {
948 // Recalculate length
949                                         delete new_file;
950                                         new_file = new File;
951                                         result = new_file->open_file(preferences, new_asset, 1, 0, 0, 0);
953                                         if(load_mode != LOAD_RESOURCESONLY)
954                                         {
955                                                 asset_to_edl(new_edl, new_asset);
956                                                 new_edls.append(new_edl);
957                                                 delete new_asset;
958                                                 new_asset = 0;
959                                         }
960                                         else
961                                         {
962                                                 new_assets.append(new_asset);
963                                         }
964                                 }
965                                 else
966                                 {
967                                         result = 1;
968                                 }
969                                 break;
970                         }
972                         case FILE_IS_XML:
973                         {
974                                 FileXML xml_file;
975                                 xml_file.read_from_file(filenames->values[i]);
976 // Load EDL for pasting
977                                 new_edl->load_xml(plugindb, &xml_file, LOAD_ALL);
978                                 test_plugins(new_edl, filenames->values[i]);
980 // We don't want a valid reel name/number for projects
981                                 strcpy(new_asset->reel_name, "");
982                                 reel_number = -1;
984                                 if(load_mode == LOAD_REPLACE || 
985                                         load_mode == LOAD_REPLACE_CONCATENATE)
986                                 {
987                                         strcpy(session->filename, filenames->values[i]);
988                                         strcpy(new_edl->local_session->clip_title, filenames->values[i]);
989                                         if(update_filename)
990                                                 set_filename(new_edl->local_session->clip_title);
991                                 }
993                                 new_edls.append(new_edl);
994                                 result = 0;
995                                 break;
996                         }
997                 }
999 TRACE("MWindow::load_filenames 87");
1000                 if(result)
1001                 {
1002                         delete new_edl;
1003                         delete new_asset;
1004                         new_edl = 0;
1005                         new_asset = 0;
1006                 }
1007 TRACE("MWindow::load_filenames 88");
1009 // Store for testing index
1010                 new_files.append(new_file);
1011 TRACE("MWindow::load_filenames 89");
1012         }
1016         if(!result) gui->statusbar->default_message();
1020 TRACE("MWindow::load_filenames 90");
1026 // Paste them.
1027 // Don't back up here.
1028         if(new_edls.total)
1029         {
1030 SET_TRACE
1031 // For pasting, clear the active region
1032                 if(load_mode == LOAD_PASTE)
1033                 {
1034 SET_TRACE
1035                         double start = edl->local_session->get_selectionstart();
1036 SET_TRACE
1037                         double end = edl->local_session->get_selectionend();
1038 SET_TRACE
1039                         if(!EQUIV(start, end))
1040                                 edl->clear(start, 
1041                                         end,
1042                                         edl->session->labels_follow_edits,
1043                                         edl->session->plugins_follow_edits);
1044 SET_TRACE
1045                 }
1047 SET_TRACE
1048                 paste_edls(&new_edls, 
1049                         load_mode,
1050                         0,
1051                         -1,
1052                         edl->session->labels_follow_edits, 
1053                         edl->session->plugins_follow_edits);
1054 SET_TRACE
1055         }
1062 TRACE("MWindow::load_filenames 91");
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         }
1093 TRACE("MWindow::load_filenames 100");
1094         update_project(load_mode);
1095 TRACE("MWindow::load_filenames 110");
1097 //printf("MWindow::load_filenames 9\n");
1098 //sleep(10);
1100         new_edls.remove_all_objects();
1101 TRACE("MWindow::load_filenames 120\n");
1102         new_assets.remove_all_objects();
1103 TRACE("MWindow::load_filenames 130\n");
1104         new_files.remove_all_objects();
1105 TRACE("MWindow::load_filenames 140\n");
1107         undo->update_undo(_("load"), LOAD_ALL, 0);
1110         gui->stop_hourglass();
1111 UNTRACE
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         }
1182 void MWindow::create_objects(int want_gui, 
1183         int want_new,
1184         char *config_path)
1186         char string[BCTEXTLEN];
1187         FileSystem fs;
1188         edl = 0;
1191         show_splash();
1193 // For some reason, init_signals must come after show_splash or the signals won't
1194 // get trapped.
1195         init_signals();
1198 TRACE("MWindow::create_objects 1");
1199         init_defaults(defaults, config_path);
1200 TRACE("MWindow::create_objects 2");
1201         init_preferences();
1202 TRACE("MWindow::create_objects 3");
1203         init_plugins(preferences, plugindb, splash_window);
1204         if(splash_window) splash_window->operation->update(_("Initializing GUI"));
1205 TRACE("MWindow::create_objects 4");
1206         init_theme();
1207 // Default project created here
1208 TRACE("MWindow::create_objects 5");
1209         init_edl();
1211 TRACE("MWindow::create_objects 6");
1212         init_awindow();
1213 TRACE("MWindow::create_objects 7");
1214         init_compositor();
1215 TRACE("MWindow::create_objects 8");
1216         init_levelwindow();
1217 TRACE("MWindow::create_objects 9");
1218         init_viewer();
1219 TRACE("MWindow::create_objects 10");
1220         init_cache();
1221 TRACE("MWindow::create_objects 11");
1222         init_indexes();
1223 TRACE("MWindow::create_objects 12");
1224         init_channeldb();
1225 TRACE("MWindow::create_objects 13");
1227         init_gui();
1228         init_gwindow();
1229 TRACE("MWindow::create_objects 14");
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 TRACE("MWindow::create_objects 15");
1239         if(session->show_vwindow) vwindow->gui->show_window();
1240         if(session->show_cwindow) cwindow->gui->show_window();
1241         if(session->show_awindow) awindow->gui->show_window();
1242         if(session->show_lwindow) lwindow->gui->show_window();
1243         if(session->show_gwindow) gwindow->gui->show_window();
1244 TRACE("MWindow::create_objects 16");
1247         gui->mainmenu->load_defaults(defaults);
1248 TRACE("MWindow::create_objects 17");
1249         gui->mainmenu->update_toggles(0);
1250 TRACE("MWindow::create_objects 18");
1251         gui->patchbay->update();
1252 TRACE("MWindow::create_objects 19");
1253         gui->canvas->draw();
1254 TRACE("MWindow::create_objects 20");
1255         gui->cursor->draw();
1256 TRACE("MWindow::create_objects 21");
1257         gui->show_window();
1258         gui->raise_window();
1260         if(preferences->use_tipwindow)
1261                 init_tipwindow();
1262                 
1263 TRACE("MWindow::create_objects 22");
1264 TRACE("MWindow::create_objects 23");
1266         hide_splash();
1267 UNTRACE
1271 void MWindow::show_splash()
1273 #include "data/heroine_logo12_png.h"
1274         VFrame *frame = new VFrame(heroine_logo12_png);
1275         BC_DisplayInfo display_info;
1276         splash_window = new SplashGUI(frame, 
1277                 display_info.get_root_w() / 2 - frame->get_w() / 2,
1278                 display_info.get_root_h() / 2 - frame->get_h() / 2);
1279         splash_window->create_objects();
1282 void MWindow::hide_splash()
1284         if(splash_window)
1285                 delete splash_window;
1286         splash_window = 0;
1290 void MWindow::start()
1292         vwindow->start();
1293         awindow->start();
1294         cwindow->start();
1295         lwindow->start();
1296         gwindow->start();
1297         gui->run_window();
1300 void MWindow::show_vwindow()
1302         session->show_vwindow = 1;
1303         vwindow->gui->lock_window("MWindow::show_vwindow");
1304         vwindow->gui->show_window();
1305         vwindow->gui->raise_window();
1306         vwindow->gui->flush();
1307         vwindow->gui->unlock_window();
1308         gui->mainmenu->show_vwindow->set_checked(1);
1311 void MWindow::show_awindow()
1313         session->show_awindow = 1;
1314         awindow->gui->lock_window("MWindow::show_awindow");
1315         awindow->gui->show_window();
1316         awindow->gui->raise_window();
1317         awindow->gui->flush();
1318         awindow->gui->unlock_window();
1319         gui->mainmenu->show_awindow->set_checked(1);
1322 void MWindow::show_cwindow()
1324         session->show_cwindow = 1;
1325         cwindow->show_window();
1326         gui->mainmenu->show_cwindow->set_checked(1);
1329 void MWindow::show_gwindow()
1331         session->show_gwindow = 1;
1333 SET_TRACE
1334         gwindow->gui->lock_window("MWindow::show_gwindow");
1335 SET_TRACE
1336         gwindow->gui->show_window();
1337 SET_TRACE
1338         gwindow->gui->raise_window();
1339 SET_TRACE
1340         gwindow->gui->flush();
1341 SET_TRACE
1342         gwindow->gui->unlock_window();
1343 SET_TRACE
1345         gui->mainmenu->show_gwindow->set_checked(1);
1346 SET_TRACE
1349 void MWindow::show_lwindow()
1351         session->show_lwindow = 1;
1352         lwindow->gui->lock_window("MWindow::show_lwindow");
1353         lwindow->gui->show_window();
1354         lwindow->gui->raise_window();
1355         lwindow->gui->flush();
1356         lwindow->gui->unlock_window();
1357         gui->mainmenu->show_lwindow->set_checked(1);
1360 void MWindow::tile_windows()
1362         session->default_window_positions();
1363         gui->default_positions();
1366 void MWindow::toggle_loop_playback()
1368         edl->local_session->loop_playback = !edl->local_session->loop_playback;
1369         set_loop_boundaries();
1370         save_backup();
1372         gui->canvas->draw_overlays();
1373         gui->canvas->flash();
1374         sync_parameters(CHANGE_PARAMS);
1377 void MWindow::set_titles(int value)
1379         edl->session->show_titles = value;
1380         trackmovement(edl->local_session->track_start);
1383 void MWindow::set_auto_keyframes(int value)
1385         gui->lock_window("MWindow::set_auto_keyframes");
1386         edl->session->auto_keyframes = value;
1387         gui->mbuttons->edit_panel->keyframe->update(value);
1388         gui->flush();
1389         gui->unlock_window();
1390         cwindow->gui->lock_window("MWindow::set_auto_keyframes");
1391         cwindow->gui->edit_panel->keyframe->update(value);
1392         cwindow->gui->flush();
1393         cwindow->gui->unlock_window();
1396 int MWindow::set_editing_mode(int new_editing_mode)
1398         gui->lock_window("MWindow::set_editing_mode");
1399         edl->session->editing_mode = new_editing_mode;
1400         gui->mbuttons->edit_panel->editing_mode = edl->session->editing_mode;
1401         gui->mbuttons->edit_panel->update();
1402         gui->canvas->update_cursor();
1403         gui->unlock_window();
1404         cwindow->gui->lock_window("MWindow::set_editing_mode");
1405         cwindow->gui->edit_panel->update();
1406         cwindow->gui->edit_panel->editing_mode = edl->session->editing_mode;
1407         cwindow->gui->unlock_window();
1408         return 0;
1412 void MWindow::sync_parameters(int change_type)
1415 // Sync engines which are playing back
1416         if(cwindow->playback_engine->is_playing_back)
1417         {
1418                 if(change_type == CHANGE_PARAMS)
1419                 {
1420 // TODO: block keyframes until synchronization is done
1421                         cwindow->playback_engine->sync_parameters(edl);
1422                 }
1423                 else
1424 // Stop and restart
1425                 {
1426                         int command = cwindow->playback_engine->command->command;
1427                         cwindow->playback_engine->que->send_command(STOP,
1428                                 CHANGE_NONE, 
1429                                 0,
1430                                 0);
1431 // Waiting for tracking to finish would make the restart position more
1432 // accurate but it can't lock the window to stop tracking for some reason.
1433 // Not waiting for tracking gives a faster response but restart position is
1434 // only as accurate as the last tracking update.
1435                         cwindow->playback_engine->interrupt_playback(0);
1436                         cwindow->playback_engine->que->send_command(command,
1437                                         change_type, 
1438                                         edl,
1439                                         1,
1440                                         0);
1441                 }
1442         }
1443         else
1444         {
1445                 cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1446                                                         change_type,
1447                                                         edl,
1448                                                         1);
1449         }
1452 void MWindow::update_caches()
1454         audio_cache->set_edl(edl);
1455         video_cache->set_edl(edl);
1458 void MWindow::show_plugin(Plugin *plugin)
1460         int done = 0;
1461 //printf("MWindow::show_plugin 1\n");
1462         plugin_gui_lock->lock("MWindow::show_plugin");
1463         for(int i = 0; i < plugin_guis->total; i++)
1464         {
1465 // Pointer comparison
1466                 if(plugin_guis->values[i]->plugin == plugin)
1467                 {
1468                         plugin_guis->values[i]->raise_window();
1469                         done = 1;
1470                         break;
1471                 }
1472         }
1474 //printf("MWindow::show_plugin 1\n");
1475         if(!done)
1476         {
1477                 if(!plugin->track)
1478                 {
1479                         printf("MWindow::show_plugin track not defined.\n");
1480                 }
1481                 PluginServer *server = scan_plugindb(plugin->title,
1482                         plugin->track->data_type);
1484 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
1485                 if(server && server->uses_gui)
1486                 {
1487                         PluginServer *gui = plugin_guis->append(new PluginServer(*server));
1488 // Needs mwindow to do GUI
1489                         gui->set_mwindow(this);
1490                         gui->open_plugin(0, preferences, edl, plugin, -1);
1491                         gui->show_gui();
1492                         plugin->show = 1;
1493                 }
1494         }
1495         plugin_gui_lock->unlock();
1496 //printf("MWindow::show_plugin 2\n");
1499 void MWindow::hide_plugin(Plugin *plugin, int lock)
1501         if(lock) plugin_gui_lock->lock("MWindow::hide_plugin");
1502         plugin->show = 0;
1503         for(int i = 0; i < plugin_guis->total; i++)
1504         {
1505                 if(plugin_guis->values[i]->plugin == plugin)
1506                 {
1507                         PluginServer *ptr = plugin_guis->values[i];
1508                         plugin_guis->remove(ptr);
1509                         if(lock) plugin_gui_lock->unlock();
1510 // Last command executed in client side close
1511                         delete ptr;
1512                         return;
1513                 }
1514         }
1515         if(lock) plugin_gui_lock->unlock();
1518 void MWindow::hide_plugins()
1520         plugin_gui_lock->lock("MWindow::hide_plugins");
1521         plugin_guis->remove_all_objects();
1522         plugin_gui_lock->unlock();
1525 void MWindow::update_plugin_guis()
1527         plugin_gui_lock->lock("MWindow::update_plugin_guis");
1529         for(int i = 0; i < plugin_guis->total; i++)
1530         {
1531                 plugin_guis->values[i]->update_gui();
1532         }
1533         plugin_gui_lock->unlock();
1536 void MWindow::render_plugin_gui(void *data, Plugin *plugin)
1538         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1539         for(int i = 0; i < plugin_guis->total; i++)
1540         {
1541                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1542                 {
1543                         plugin_guis->values[i]->render_gui(data);
1544                         break;
1545                 }
1546         }
1547         plugin_gui_lock->unlock();
1550 void MWindow::render_plugin_gui(void *data, int size, Plugin *plugin)
1552         plugin_gui_lock->lock("MWindow::render_plugin_gui");
1553         for(int i = 0; i < plugin_guis->total; i++)
1554         {
1555                 if(plugin_guis->values[i]->plugin->identical_location(plugin))
1556                 {
1557                         plugin_guis->values[i]->render_gui(data, size);
1558                         break;
1559                 }
1560         }
1561         plugin_gui_lock->unlock();
1565 void MWindow::update_plugin_states()
1567         plugin_gui_lock->lock("MWindow::update_plugin_states");
1568         for(int i = 0; i < plugin_guis->total; i++)
1569         {
1570                 int result = 0;
1571 // Get a plugin GUI
1572                 Plugin *src_plugin = plugin_guis->values[i]->plugin;
1573                 PluginServer *src_plugingui = plugin_guis->values[i];
1575 // Search for plugin in EDL.  Only the master EDL shows plugin GUIs.
1576                 for(Track *track = edl->tracks->first; 
1577                         track && !result; 
1578                         track = track->next)
1579                 {
1580                         for(int j = 0; 
1581                                 j < track->plugin_set.total && !result; 
1582                                 j++)
1583                         {
1584                                 PluginSet *plugin_set = track->plugin_set.values[j];
1585                                 for(Plugin *plugin = (Plugin*)plugin_set->first; 
1586                                         plugin && !result; 
1587                                         plugin = (Plugin*)plugin->next)
1588                                 {
1589                                         if(plugin == src_plugin &&
1590                                                 !strcmp(plugin->title, src_plugingui->title)) result = 1;
1591                                 }
1592                         }
1593                 }
1596 // Doesn't exist anymore
1597                 if(!result)
1598                 {
1599                         hide_plugin(src_plugin, 0);
1600                         i--;
1601                 }
1602         }
1603         plugin_gui_lock->unlock();
1607 void MWindow::update_plugin_titles()
1609         for(int i = 0; i < plugin_guis->total; i++)
1610         {
1611                 plugin_guis->values[i]->update_title();
1612         }
1615 int MWindow::asset_to_edl(EDL *new_edl, 
1616         Asset *new_asset, 
1617         RecordLabels *labels)
1619 //printf("MWindow::asset_to_edl 1\n");
1620 //      new_edl->load_defaults(defaults);
1622 // Keep frame rate, sample rate, and output size unchanged.
1623 // These parameters would revert the project if VWindow displayed an asset
1624 // of different size than the project.
1625         if(new_asset->video_data)
1626         {
1627                 new_edl->session->video_tracks = new_asset->layers;
1628 //              new_edl->session->frame_rate = new_asset->frame_rate;
1629 //              new_edl->session->output_w = new_asset->width;
1630 //              new_edl->session->output_h = new_asset->height;
1631         }
1632         else
1633                 new_edl->session->video_tracks = 0;
1640         if(new_asset->audio_data)
1641         {
1642                 new_edl->session->audio_tracks = new_asset->channels;
1643 //              new_edl->session->sample_rate = new_asset->sample_rate;
1644         }
1645         else
1646                 new_edl->session->audio_tracks = 0;
1647 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1649         new_edl->create_default_tracks();
1650 //printf("MWindow::asset_to_edl 2 %d %d\n", new_edl->session->video_tracks, new_edl->session->audio_tracks);
1652 // Disable drawing if the file format isn't fast enough.
1653 // MPEG is now faster than most other codecs.
1654 //      if(new_asset->format == FILE_MPEG)
1655 //      {
1656 //              for(Track *current = new_edl->tracks->first;
1657 //                      current;
1658 //                      current = NEXT)
1659 //              {
1660 //                      if(current->data_type == TRACK_VIDEO) current->draw = 0;
1661 //              }
1662 //      }
1666 //printf("MWindow::asset_to_edl 3\n");
1667         new_edl->insert_asset(new_asset, 0, 0, labels);
1668 //printf("MWindow::asset_to_edl 3\n");
1674         char string[BCTEXTLEN];
1675         FileSystem fs;
1676         fs.extract_name(string, new_asset->path);
1677 //printf("MWindow::asset_to_edl 3\n");
1679         strcpy(new_edl->local_session->clip_title, string);
1680 //printf("MWindow::asset_to_edl 4 %s\n", string);
1682 //      new_edl->dump();
1683         return 0;
1686 // Reset everything after a load.
1687 void MWindow::update_project(int load_mode)
1689         restart_brender();
1690 //TRACE("MWindow::update_project 1");
1691         edl->tracks->update_y_pixels(theme);
1693 // Draw timeline
1694 //TRACE("MWindow::update_project 2");
1695         update_caches();
1697 TRACE("MWindow::update_project 3");
1698         gui->update(1, 1, 1, 1, 1, 1, 1);
1700 TRACE("MWindow::update_project 4");
1701         cwindow->update(0, 0, 1, 1, 1);
1703 TRACE("MWindow::update_project 5");
1705         if(load_mode == LOAD_REPLACE ||
1706                 load_mode == LOAD_REPLACE_CONCATENATE)
1707         {
1708                 vwindow->change_source();
1709         }
1710         else
1711         {
1712                 vwindow->update(1);
1713         }
1715 TRACE("MWindow::update_project 6");
1717         cwindow->gui->slider->set_position();
1718 TRACE("MWindow::update_project 6.1");
1719         cwindow->gui->timebar->update(1, 1);
1720 TRACE("MWindow::update_project 6.2");
1721         cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1722                 CHANGE_ALL,
1723                 edl,
1724                 1);
1726 TRACE("MWindow::update_project 7");
1727         awindow->gui->lock_window("MWindow::update_project");
1728         awindow->gui->update_assets();
1729         awindow->gui->flush();
1730         awindow->gui->unlock_window();
1731         gui->flush();
1732 TRACE("MWindow::update_project 100");
1736 void MWindow::rebuild_indices()
1738         char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
1740         for(int i = 0; i < session->drag_assets->total; i++)
1741         {
1742 //printf("MWindow::rebuild_indices 1 %s\n", session->drag_assets->values[i]->path);
1743 // Erase file
1744                 IndexFile::get_index_filename(source_filename, 
1745                         preferences->index_directory,
1746                         index_filename, 
1747                         session->drag_assets->values[i]->path);
1748                 remove(index_filename);
1749 // Schedule index build
1750                 session->drag_assets->values[i]->index_status = INDEX_NOTTESTED;
1751                 mainindexes->add_next_asset(0, session->drag_assets->values[i]);
1752         }
1753         mainindexes->start_build();
1757 void MWindow::save_backup()
1759         FileXML file;
1760         edl->set_project_path(session->filename);
1761         edl->save_xml(plugindb, 
1762                 &file, 
1763                 BACKUP_PATH,
1764                 0,
1765                 0);
1766         file.terminate_string();
1767         char path[BCTEXTLEN];
1768         FileSystem fs;
1769         strcpy(path, BACKUP_PATH);
1770         fs.complete_path(path);
1772         if(file.write_to_file(path))
1773         {
1774                 char string2[256];
1775                 sprintf(string2, _("Couldn't open %s for writing."), BACKUP_PATH);
1776                 gui->show_message(string2);
1777         }
1781 int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
1783         int denominator;
1784         if(!width || !height) return 1;
1785         float fraction = (float)width / height;
1787         for(denominator = 1; 
1788                 denominator < 100 && 
1789                         fabs(fraction * denominator - (int)(fraction * denominator)) > .001; 
1790                 denominator++)
1791                 ;
1793         w = denominator * width / height;
1794         h = denominator;
1795         return 0;
1800 void MWindow::remove_assets_from_project(int push_undo)
1802 // Remove from caches
1803         for(int i = 0; i < session->drag_assets->total; i++)
1804         {
1805                 audio_cache->delete_entry(session->drag_assets->values[i]);
1806                 video_cache->delete_entry(session->drag_assets->values[i]);
1807         }
1809 printf("MWindow::remove_assets_from_project 1\n");
1810 video_cache->dump();
1811 audio_cache->dump();
1812 printf("MWindow::remove_assets_from_project 100\n");
1814 // Remove from VWindow.
1815         for(int i = 0; i < session->drag_clips->total; i++)
1816         {
1817                 if(session->drag_clips->values[i] == vwindow->get_edl())
1818                 {
1819                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 1");
1820                         vwindow->remove_source();
1821                         vwindow->gui->unlock_window();
1822                 }
1823         }
1824         
1825         for(int i = 0; i < session->drag_assets->total; i++)
1826         {
1827                 if(session->drag_assets->values[i] == vwindow->get_asset())
1828                 {
1829                         vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
1830                         vwindow->remove_source();
1831                         vwindow->gui->unlock_window();
1832                 }
1833         }
1834         
1835         edl->remove_from_project(session->drag_assets);
1836         edl->remove_from_project(session->drag_clips);
1837         save_backup();
1838         if(push_undo) undo->update_undo(_("remove assets"), LOAD_ALL);
1839         restart_brender();
1841         gui->lock_window("MWindow::remove_assets_from_project 3");
1842         gui->update(1,
1843                 1,
1844                 1,
1845                 1,
1846                 0, 
1847                 1,
1848                 0);
1849         gui->unlock_window();
1851         awindow->gui->lock_window("MWindow::remove_assets_from_project 4");
1852         awindow->gui->update_assets();
1853         awindow->gui->flush();
1854         awindow->gui->unlock_window();
1856 // Removes from playback here
1857         sync_parameters(CHANGE_ALL);
1860 void MWindow::remove_assets_from_disk()
1862 // Remove from disk
1863         for(int i = 0; i < session->drag_assets->total; i++)
1864         {
1865                 remove(session->drag_assets->values[i]->path);
1866         }
1868         remove_assets_from_project(1);
1871 void MWindow::dump_plugins()
1873         for(int i = 0; i < plugindb->total; i++)
1874         {
1875                 printf("audio=%d video=%d realtime=%d transition=%d theme=%d %s\n",
1876                         plugindb->values[i]->audio,
1877                         plugindb->values[i]->video,
1878                         plugindb->values[i]->realtime,
1879                         plugindb->values[i]->transition,
1880                         plugindb->values[i]->theme,
1881                         plugindb->values[i]->title);
1882         }
1909 int MWindow::save_defaults()
1911         gui->save_defaults(defaults);
1912         edl->save_defaults(defaults);
1913         session->save_defaults(defaults);
1914         preferences->save_defaults(defaults);
1916         defaults->save();
1917         return 0;
1920 int MWindow::run_script(FileXML *script)
1922         int result = 0, result2 = 0;
1923         while(!result && !result2)
1924         {
1925                 result = script->read_tag();
1926                 if(!result)
1927                 {
1928                         if(script->tag.title_is("new_project"))
1929                         {
1930 // Run new in immediate mode.
1931 //                              gui->mainmenu->new_project->run_script(script);
1932                         }
1933                         else
1934                         if(script->tag.title_is("record"))
1935                         {
1936 // Run record as a thread.  It is a terminal command.
1937                                 ;
1938 // Will read the complete scipt file without letting record read it if not
1939 // terminated.
1940                                 result2 = 1;
1941                         }
1942                         else
1943                         {
1944                                 printf("MWindow::run_script: Unrecognized command: %s\n",script->tag.get_title() );
1945                         }
1946                 }
1947         }
1948         return result2;
1951 // ================================= synchronization
1954 int MWindow::interrupt_indexes()
1956         mainindexes->interrupt_build();
1957         return 0; 
1962 void MWindow::next_time_format()
1964         switch(edl->session->time_format)
1965         {
1966                 case TIME_HMS: edl->session->time_format = TIME_HMSF; break;
1967                 case TIME_HMSF: edl->session->time_format = TIME_SAMPLES; break;
1968                 case TIME_SAMPLES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1969                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_FRAMES; break;
1970                 case TIME_FRAMES: edl->session->time_format = TIME_FEET_FRAMES; break;
1971                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_SECONDS; break;
1972                 case TIME_SECONDS: edl->session->time_format = TIME_HMS; break;
1973         }
1975         time_format_common();
1978 void MWindow::prev_time_format()
1980         switch(edl->session->time_format)
1981         {
1982                 case TIME_HMS: edl->session->time_format = TIME_SECONDS; break;
1983                 case TIME_SECONDS: edl->session->time_format = TIME_FEET_FRAMES; break;
1984                 case TIME_FEET_FRAMES: edl->session->time_format = TIME_FRAMES; break;
1985                 case TIME_FRAMES: edl->session->time_format = TIME_SAMPLES_HEX; break;
1986                 case TIME_SAMPLES_HEX: edl->session->time_format = TIME_SAMPLES; break;
1987                 case TIME_SAMPLES: edl->session->time_format = TIME_HMSF; break;
1988                 case TIME_HMSF: edl->session->time_format = TIME_HMS; break;
1989         }
1991         time_format_common();
1994 void MWindow::time_format_common()
1996         gui->lock_window("MWindow::next_time_format");
1997         gui->redraw_time_dependancies();
1998         char string[BCTEXTLEN], string2[BCTEXTLEN];
1999         sprintf(string, _("Using %s."), Units::print_time_format(edl->session->time_format, string2));
2000         gui->show_message(string);
2001         gui->flush();
2002         gui->unlock_window();
2006 int MWindow::set_filename(char *filename)
2008         strcpy(session->filename, filename);
2009         if(gui)
2010         {
2011                 if(filename[0] == 0)
2012                 {
2013                         gui->set_title(PROGRAM_NAME);
2014                 }
2015                 else
2016                 {
2017                         FileSystem dir;
2018                         char string[BCTEXTLEN], string2[BCTEXTLEN];
2019                         dir.extract_name(string, filename);
2020                         sprintf(string2, PROGRAM_NAME ": %s", string);
2021                         gui->set_title(string2);
2022                 }
2023         }
2024         return 0; 
2034 int MWindow::set_loop_boundaries()
2036         double start = edl->local_session->get_selectionstart();
2037         double end = edl->local_session->get_selectionend();
2038         
2039         if(start != 
2040                 end) 
2041         {
2042                 ;
2043         }
2044         else
2045         if(edl->tracks->total_length())
2046         {
2047                 start = 0;
2048                 end = edl->tracks->total_length();
2049         }
2050         else
2051         {
2052                 start = end = 0;
2053         }
2055         if(edl->local_session->loop_playback && start != end)
2056         {
2057                 edl->local_session->loop_start = start;
2058                 edl->local_session->loop_end = end;
2059         }
2060         return 0; 
2069 int MWindow::reset_meters()
2071         cwindow->gui->lock_window("MWindow::reset_meters 1");
2072         cwindow->gui->meters->reset_meters();
2073         cwindow->gui->unlock_window();
2075         vwindow->gui->lock_window("MWindow::reset_meters 2");
2076         vwindow->gui->meters->reset_meters();
2077         vwindow->gui->unlock_window();
2079         lwindow->gui->lock_window("MWindow::reset_meters 3");
2080         lwindow->gui->panel->reset_meters();
2081         lwindow->gui->unlock_window();
2083         gui->lock_window("MWindow::reset_meters 4");
2084         gui->patchbay->reset_meters();
2085         gui->unlock_window();
2086         return 0;