add timecode units/alignment/probe, add prefs auto_rotate,
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mainmenu.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "assets.h"
23 #include "auto.h"
24 #include "batchrender.h"
25 #include "bcdisplayinfo.h"
26 #include "bchash.h"
27 #include "bcsignals.h"
28 #include "bdcreate.h"
29 #include "cache.h"
30 #include "channelinfo.h"
31 #include "convert.h"
32 #include "cplayback.h"
33 #include "cropvideo.h"
34 #include "cwindow.h"
35 #include "cwindowgui.h"
36 #include "dbwindow.h"
37 #include "dvdcreate.h"
38 #include "edl.h"
39 #include "edlsession.h"
40 #include "exportedl.h"
41 #include "file.h"
42 #include "filesystem.h"
43 #include "filexml.h"
44 #include "floatauto.h"
45 #include "keys.h"
46 #include "language.h"
47 #include "levelwindow.h"
48 #include "loadfile.h"
49 #include "localsession.h"
50 #include "mainclock.h"
51 #include "mainmenu.h"
52 #include "mainsession.h"
53 #include "mainundo.h"
54 #include "menuattacheffect.h"
55 #include "menuattachtransition.h"
56 #include "menuaeffects.h"
57 #include "menueditlength.h"
58 #include "menutransitionlength.h"
59 #include "menuveffects.h"
60 #include "mixersalign.h"
61 #include "mwindowgui.h"
62 #include "mwindow.h"
63 #include "new.h"
64 #include "patchbay.h"
65 #include "playbackengine.h"
66 #include "preferences.h"
67 #include "proxy.h"
68 #include "preferencesthread.h"
69 #include "quit.h"
70 #include "record.h"
71 #include "render.h"
72 #include "savefile.h"
73 #include "setformat.h"
74 #include "swindow.h"
75 #include "timebar.h"
76 #include "trackcanvas.h"
77 #include "tracks.h"
78 #include "transition.h"
79 #include "transportque.h"
80 #include "viewmenu.h"
81 #include "zoombar.h"
82 #include "zwindow.h"
83 #include "zwindowgui.h"
84
85 #include <string.h>
86
87
88 MainMenu::MainMenu(MWindow *mwindow, MWindowGUI *gui, int w)
89  : BC_MenuBar(0, 0, w)
90 {
91         this->gui = gui;
92         this->mwindow = mwindow;
93 }
94
95 MainMenu::~MainMenu()
96 {
97 }
98
99 void MainMenu::create_objects()
100 {
101         BC_Menu *viewmenu, *windowmenu, *settingsmenu, *trackmenu;
102         PreferencesMenuitem *preferences;
103
104         add_menu(filemenu = new BC_Menu(_("File")));
105         filemenu->add_item(new_project = new NewProject(mwindow));
106         new_project->create_objects();
107
108 // file loaders
109         filemenu->add_item(load_file = new Load(mwindow, this));
110         load_file->create_objects();
111         filemenu->add_item(load_recent = new LoadRecent(mwindow, this));
112         load_recent->create_objects();
113
114 // new and load can be undone so no need to prompt save
115         Save *save;                   //  affected by saveas
116         filemenu->add_item(save = new Save(mwindow));
117         SaveAs *saveas;
118         filemenu->add_item(saveas = new SaveAs(mwindow));
119         save->create_objects(saveas);
120         saveas->set_mainmenu(this);
121         SaveProject *save_project;
122         filemenu->add_item(save_project = new SaveProject(mwindow));
123
124         filemenu->add_item(record_menu_item = new RecordMenuItem(mwindow));
125 #ifdef HAVE_DVB
126         filemenu->add_item(new ChannelScan(mwindow));
127 #endif
128 #ifdef HAVE_COMMERCIAL
129         if( mwindow->has_commercials() )
130                 filemenu->add_item(new DbWindowScan(mwindow));
131 #endif
132         filemenu->add_item(new SubttlSWin(mwindow));
133
134         filemenu->add_item(render = new RenderItem(mwindow));
135         filemenu->add_item(new ExportEDLItem(mwindow));
136         filemenu->add_item(new BatchRenderMenuItem(mwindow));
137         filemenu->add_item(new CreateBD_MenuItem(mwindow));
138         filemenu->add_item(new CreateDVD_MenuItem(mwindow));
139         filemenu->add_item(new BC_MenuItem("-"));
140         filemenu->add_item(quit_program = new Quit(mwindow));
141         quit_program->create_objects(save);
142         filemenu->add_item(dump_menu = new MainDumpsMenu(mwindow));
143         dump_menu->create_objects();
144         filemenu->add_item(new LoadBackup(mwindow));
145         filemenu->add_item(new SaveBackup(mwindow));
146
147         BC_Menu *editmenu;
148         add_menu(editmenu = new BC_Menu(_("Edit")));
149         editmenu->add_item(undo = new Undo(mwindow));
150         editmenu->add_item(redo = new Redo(mwindow));
151         editmenu->add_item(new BC_MenuItem("-"));
152         editmenu->add_item(new Cut(mwindow));
153         editmenu->add_item(new Copy(mwindow));
154         editmenu->add_item(new Paste(mwindow));
155         editmenu->add_item(new PasteSilence(mwindow));
156         editmenu->add_item(clear_menu = new EditClearMenu(mwindow));
157         clear_menu->create_objects();
158         editmenu->add_item(new TrimSelection(mwindow));
159         editmenu->add_item(new SelectAll(mwindow));
160         editmenu->add_item(new BC_MenuItem("-"));
161         editmenu->add_item(new MenuEditShuffle(mwindow));
162         editmenu->add_item(new MenuEditReverse(mwindow));
163         editmenu->add_item(new MenuEditLength(mwindow));
164         editmenu->add_item(new MenuEditAlign(mwindow));
165         editmenu->add_item(new MenuTransitionLength(mwindow));
166         editmenu->add_item(new DetachTransitions(mwindow));
167         editmenu->add_item(new BC_MenuItem("-"));
168         editmenu->add_item(new CutCommercials(mwindow));
169         editmenu->add_item(new PasteSubttl(mwindow));
170
171         BC_Menu *keyframemenu;
172         add_menu(keyframemenu = new BC_Menu(_("Keyframes")));
173         keyframemenu->add_item(new CutKeyframes(mwindow));
174         keyframemenu->add_item(new CopyKeyframes(mwindow));
175         keyframemenu->add_item(new PasteKeyframes(mwindow));
176         keyframemenu->add_item(new ClearKeyframes(mwindow));
177         keyframemenu->add_item(new StraightenKeyframes(mwindow));
178         keyframemenu->add_item(new BendKeyframes(mwindow));
179         keyframemenu->add_item(keyframe_curve_type = new KeyframeCurveType(mwindow));
180         keyframe_curve_type->create_objects();
181         keyframe_curve_type->update(mwindow->edl->local_session->floatauto_type);
182         keyframemenu->add_item(new BC_MenuItem("-"));
183         keyframemenu->add_item(new CopyDefaultKeyframe(mwindow));
184         keyframemenu->add_item(new PasteDefaultKeyframe(mwindow));
185
186
187
188
189         add_menu(audiomenu = new BC_Menu(_("Audio")));
190         audiomenu->add_item(new AddAudioTrack(mwindow));
191         audiomenu->add_item(new DefaultATransition(mwindow));
192         audiomenu->add_item(new MapAudio1(mwindow));
193         audiomenu->add_item(new MapAudio2(mwindow));
194         audiomenu->add_item(new MenuAttachTransition(mwindow, TRACK_AUDIO));
195         audiomenu->add_item(new MenuAttachEffect(mwindow, TRACK_AUDIO));
196         audiomenu->add_item(aeffects = new MenuAEffects(mwindow));
197
198         add_menu(videomenu = new BC_Menu(_("Video")));
199         videomenu->add_item(new AddVideoTrack(mwindow));
200         videomenu->add_item(new DefaultVTransition(mwindow));
201         videomenu->add_item(new MenuAttachTransition(mwindow, TRACK_VIDEO));
202         videomenu->add_item(new MenuAttachEffect(mwindow, TRACK_VIDEO));
203         videomenu->add_item(veffects = new MenuVEffects(mwindow));
204
205         add_menu(trackmenu = new BC_Menu(_("Tracks")));
206         trackmenu->add_item(new MoveTracksUp(mwindow));
207         trackmenu->add_item(new MoveTracksDown(mwindow));
208         trackmenu->add_item(new DeleteTracks(mwindow));
209         trackmenu->add_item(new DeleteFirstTrack(mwindow));
210         trackmenu->add_item(new DeleteLastTrack(mwindow));
211         trackmenu->add_item(new ConcatenateTracks(mwindow));
212         trackmenu->add_item(new SwapTracksUp(mwindow));
213         trackmenu->add_item(new SwapTracksDown(mwindow));
214         AppendTracks *append_tracks;
215         trackmenu->add_item(append_tracks = new AppendTracks(mwindow));
216         append_tracks->create_objects();
217         trackmenu->add_item(new AddSubttlTrack(mwindow));
218
219         add_menu(settingsmenu = new BC_Menu(_("Settings")));
220
221         settingsmenu->add_item(new SetFormat(mwindow));
222         settingsmenu->add_item(preferences = new PreferencesMenuitem(mwindow));
223         ProxyMenuItem *proxy;
224         settingsmenu->add_item(proxy = new ProxyMenuItem(mwindow));
225         proxy->create_objects();
226         ConvertMenuItem *convert;
227         settingsmenu->add_item(convert = new ConvertMenuItem(mwindow));
228         convert->create_objects();
229         mwindow->preferences_thread = preferences->thread;
230         settingsmenu->add_item(cursor_on_frames = new CursorOnFrames(mwindow));
231         settingsmenu->add_item(labels_follow_edits = new LabelsFollowEdits(mwindow));
232         settingsmenu->add_item(plugins_follow_edits = new PluginsFollowEdits(mwindow));
233         settingsmenu->add_item(keyframes_follow_edits = new KeyframesFollowEdits(mwindow));
234         settingsmenu->add_item(typeless_keyframes = new TypelessKeyframes(mwindow));
235         settingsmenu->add_item(new BC_MenuItem("-"));
236         settingsmenu->add_item(new SaveSettingsNow(mwindow));
237         settingsmenu->add_item(loop_playback = new LoopPlayback(mwindow));
238         settingsmenu->add_item(brender_active = new SetBRenderActive(mwindow));
239 // set scrubbing speed
240 //      ScrubSpeed *scrub_speed;
241 //      settingsmenu->add_item(scrub_speed = new ScrubSpeed(mwindow));
242 //      if(mwindow->edl->session->scrub_speed == .5)
243 //              scrub_speed->set_text(_("Fast Shuttle"));
244
245
246
247
248
249
250         add_menu(viewmenu = new BC_Menu(_("View")));
251         viewmenu->add_item(show_assets = new ShowAssets(mwindow, "0"));
252         viewmenu->add_item(show_titles = new ShowTitles(mwindow, "1"));
253         viewmenu->add_item(show_transitions = new ShowTransitions(mwindow, "2"));
254         viewmenu->add_item(fade_automation = new ShowAutomation(mwindow, _("Fade"), "3", AUTOMATION_FADE));
255         viewmenu->add_item(mute_automation = new ShowAutomation(mwindow, _("Mute"), "4", AUTOMATION_MUTE));
256         viewmenu->add_item(mode_automation = new ShowAutomation(mwindow, _("Overlay mode"), "5", AUTOMATION_MODE));
257         viewmenu->add_item(pan_automation = new ShowAutomation(mwindow, _("Pan"), "6", AUTOMATION_PAN));
258         viewmenu->add_item(plugin_automation = new PluginAutomation(mwindow, "7"));
259         viewmenu->add_item(mask_automation = new ShowAutomation(mwindow, _("Mask"), "8", AUTOMATION_MASK));
260         viewmenu->add_item(speed_automation = new ShowAutomation(mwindow, _("Speed"), "9", AUTOMATION_SPEED));
261
262         camera_x = new ShowAutomation(mwindow, _("Camera X"), "Ctrl-Shift-X", AUTOMATION_CAMERA_X);
263         camera_x->set_ctrl();  camera_x->set_shift();   viewmenu->add_item(camera_x);
264         camera_y = new ShowAutomation(mwindow, _("Camera Y"), "Ctrl-Shift-Y", AUTOMATION_CAMERA_Y);
265         camera_y->set_ctrl();  camera_y->set_shift();   viewmenu->add_item(camera_y);
266         camera_z = new ShowAutomation(mwindow, _("Camera Z"), "Ctrl-Shift-Z", AUTOMATION_CAMERA_Z);
267         camera_z->set_ctrl();  camera_z->set_shift();  viewmenu->add_item(camera_z);
268         project_x = new ShowAutomation(mwindow, _("Projector X"), "Alt-Shift-X", AUTOMATION_PROJECTOR_X);
269         project_x->set_alt();  project_x->set_shift();  viewmenu->add_item(project_x);
270         project_y = new ShowAutomation(mwindow, _("Projector Y"), "Alt-Shift-Y", AUTOMATION_PROJECTOR_Y);
271         project_y->set_alt();  project_y->set_shift();  viewmenu->add_item(project_y);
272         project_z = new ShowAutomation(mwindow, _("Projector Z"), "Alt-Shift-Z", AUTOMATION_PROJECTOR_Z);
273         project_z->set_alt();  project_z->set_shift();  viewmenu->add_item(project_z);
274
275         add_menu(windowmenu = new BC_Menu(_("Window")));
276         windowmenu->add_item(show_vwindow = new ShowVWindow(mwindow));
277         windowmenu->add_item(show_awindow = new ShowAWindow(mwindow));
278         windowmenu->add_item(show_cwindow = new ShowCWindow(mwindow));
279         windowmenu->add_item(show_gwindow = new ShowGWindow(mwindow));
280         windowmenu->add_item(show_lwindow = new ShowLWindow(mwindow));
281         windowmenu->add_item(new BC_MenuItem("-"));
282         windowmenu->add_item(split_x = new SplitX(mwindow));
283         windowmenu->add_item(split_y = new SplitY(mwindow));
284         windowmenu->add_item(mixer_items = new MixerItems(mwindow));
285         windowmenu->add_item(align_timecodes = new AlignTimecodes(mwindow));
286         mixer_items->create_objects();
287         windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0));
288         windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1));
289         windowmenu->add_item(new BC_MenuItem("-"));
290
291         windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl-P"),'p'));
292         windowmenu->add_item(load_layout = new LoadLayout(mwindow, _("Load layout..."),LAYOUT_LOAD));
293         load_layout->create_objects();
294         windowmenu->add_item(save_layout = new LoadLayout(mwindow, _("Save layout..."),LAYOUT_SAVE));
295         save_layout->create_objects();
296 }
297
298 int MainMenu::load_defaults(BC_Hash *defaults)
299 {
300         init_loads(defaults);
301         init_aeffects(defaults);
302         init_veffects(defaults);
303         return 0;
304 }
305
306 void MainMenu::update_toggles(int use_lock)
307 {
308         if(use_lock) lock_window("MainMenu::update_toggles");
309         labels_follow_edits->set_checked(mwindow->edl->session->labels_follow_edits);
310         plugins_follow_edits->set_checked(mwindow->edl->session->plugins_follow_edits);
311         keyframes_follow_edits->set_checked(mwindow->edl->session->autos_follow_edits);
312         typeless_keyframes->set_checked(mwindow->edl->session->typeless_keyframes);
313         cursor_on_frames->set_checked(mwindow->edl->session->cursor_on_frames);
314         loop_playback->set_checked(mwindow->edl->local_session->loop_playback);
315
316         show_assets->set_checked(mwindow->edl->session->show_assets);
317         show_titles->set_checked(mwindow->edl->session->show_titles);
318         show_transitions->set_checked(mwindow->edl->session->auto_conf->transitions);
319         fade_automation->update_toggle();
320         mute_automation->update_toggle();
321         pan_automation->update_toggle();
322         camera_x->update_toggle();
323         camera_y->update_toggle();
324         camera_z->update_toggle();
325         project_x->update_toggle();
326         project_y->update_toggle();
327         project_z->update_toggle();
328         plugin_automation->set_checked(mwindow->edl->session->auto_conf->plugins);
329         mode_automation->update_toggle();
330         mask_automation->update_toggle();
331         speed_automation->update_toggle();
332         split_x->set_checked(mwindow->gui->pane[TOP_RIGHT_PANE] != 0);
333         split_y->set_checked(mwindow->gui->pane[BOTTOM_LEFT_PANE] != 0);
334
335         if(use_lock) mwindow->gui->unlock_window();
336 }
337
338 int MainMenu::save_defaults(BC_Hash *defaults)
339 {
340         save_loads(defaults);
341         save_aeffects(defaults);
342         save_veffects(defaults);
343         return 0;
344 }
345
346
347
348
349
350 int MainMenu::quit()
351 {
352         quit_program->handle_event();
353         return 0;
354 }
355
356
357
358
359
360 // ================================== load most recent
361
362 int MainMenu::init_aeffects(BC_Hash *defaults)
363 {
364         total_aeffects = defaults->get((char*)"TOTAL_AEFFECTS", 0);
365
366         char string[BCTEXTLEN], title[BCTEXTLEN];
367         if(total_aeffects) audiomenu->add_item(new BC_MenuItem("-"));
368
369         for(int i = 0; i < total_aeffects; i++)
370         {
371                 sprintf(string, "AEFFECTRECENT%d", i);
372                 defaults->get(string, title);
373                 audiomenu->add_item(aeffect[i] = new MenuAEffectItem(aeffects, title));
374         }
375         return 0;
376 }
377
378 int MainMenu::init_veffects(BC_Hash *defaults)
379 {
380         total_veffects = defaults->get((char*)"TOTAL_VEFFECTS", 0);
381
382         char string[BCTEXTLEN], title[BCTEXTLEN];
383         if(total_veffects) videomenu->add_item(new BC_MenuItem("-"));
384
385         for(int i = 0; i < total_veffects; i++)
386         {
387                 sprintf(string, "VEFFECTRECENT%d", i);
388                 defaults->get(string, title);
389                 videomenu->add_item(veffect[i] = new MenuVEffectItem(veffects, title));
390         }
391         return 0;
392 }
393
394 void MainMenu::init_loads(BC_Hash *defaults)
395 {
396 // total_loads for legacy xml
397         int total_loads = defaults->get((char*)"TOTAL_LOADS", 0);
398         int loads_total = defaults->get((char*)"LOADS_TOTAL", 0);
399         if( loads_total < total_loads ) loads_total = total_loads;
400
401         char string[BCTEXTLEN], path[BCTEXTLEN];
402         FileSystem dir;
403 //printf("MainMenu::init_loads 2\n");
404
405         for( int i=0; i<loads_total; ++i ) {
406                 sprintf(string, "LOADPREVIOUS%d", i);
407 //printf("MainMenu::init_loads 3\n");
408                 defaults->get(string, path);
409                 if( load.size() < TOTAL_LOADS )
410                         load.append(new LoadRecentItem(path));
411         }
412 }
413
414 // ============================ save most recent
415
416 int MainMenu::save_aeffects(BC_Hash *defaults)
417 {
418         defaults->update((char*)"TOTAL_AEFFECTS", total_aeffects);
419         char string[BCTEXTLEN];
420         for(int i = 0; i < total_aeffects; i++)
421         {
422                 sprintf(string, "AEFFECTRECENT%d", i);
423                 defaults->update(string, aeffect[i]->get_text());
424         }
425         return 0;
426 }
427
428 int MainMenu::save_veffects(BC_Hash *defaults)
429 {
430         defaults->update((char*)"TOTAL_VEFFECTS", total_veffects);
431         char string[BCTEXTLEN];
432         for(int i = 0; i < total_veffects; i++)
433         {
434                 sprintf(string, "VEFFECTRECENT%d", i);
435                 defaults->update(string, veffect[i]->get_text());
436         }
437         return 0;
438 }
439
440 int MainMenu::save_loads(BC_Hash *defaults)
441 {
442 // legacy to prevent segv, older code cant tolerate total_loads>10
443         int loads_total = load.size();
444         int total_loads = MIN(10, loads_total);
445         defaults->update((char*)"LOADS_TOTAL", loads_total);
446         defaults->update((char*)"TOTAL_LOADS", total_loads);
447         char string[BCTEXTLEN];
448         for( int i=0; i<loads_total; ++i ) {
449                 sprintf(string, "LOADPREVIOUS%d", i);
450                 defaults->update(string, load[i]->path);
451         }
452         return 0;
453 }
454
455 // =================================== add most recent
456
457 int MainMenu::add_aeffect(char *title)
458 {
459 // add bar for first effect
460         if(total_aeffects == 0)
461         {
462                 audiomenu->add_item(new BC_MenuItem("-"));
463         }
464
465 // test for existing copy of effect
466         for(int i = 0; i < total_aeffects; i++)
467         {
468                 if(!strcmp(aeffect[i]->get_text(), title))     // already exists
469                 {                                // swap for top effect
470                         for(int j = i; j > 0; j--)   // move preceeding effects down
471                         {
472                                 aeffect[j]->set_text(aeffect[j - 1]->get_text());
473                         }
474                         aeffect[0]->set_text(title);
475                         return 1;
476                 }
477         }
478
479 // add another blank effect
480         if(total_aeffects < TOTAL_EFFECTS)
481         {
482                 audiomenu->add_item(
483                         aeffect[total_aeffects] = new MenuAEffectItem(aeffects, (char*)""));
484                 total_aeffects++;
485         }
486
487 // cycle effect down
488         for(int i = total_aeffects - 1; i > 0; i--)
489         {
490         // set menu item text
491                 aeffect[i]->set_text(aeffect[i - 1]->get_text());
492         }
493
494 // set up the new effect
495         aeffect[0]->set_text(title);
496         return 0;
497 }
498
499 int MainMenu::add_veffect(char *title)
500 {
501 // add bar for first effect
502         if(total_veffects == 0)
503         {
504                 videomenu->add_item(new BC_MenuItem("-"));
505         }
506
507 // test for existing copy of effect
508         for(int i = 0; i < total_veffects; i++)
509         {
510                 if(!strcmp(veffect[i]->get_text(), title))     // already exists
511                 {                                // swap for top effect
512                         for(int j = i; j > 0; j--)   // move preceeding effects down
513                         {
514                                 veffect[j]->set_text(veffect[j - 1]->get_text());
515                         }
516                         veffect[0]->set_text(title);
517                         return 1;
518                 }
519         }
520
521 // add another blank effect
522         if(total_veffects < TOTAL_EFFECTS)
523         {
524                 videomenu->add_item(veffect[total_veffects] =
525                         new MenuVEffectItem(veffects, (char*)""));
526                 total_veffects++;
527         }
528
529 // cycle effect down
530         for(int i = total_veffects - 1; i > 0; i--)
531         {
532 // set menu item text
533                 veffect[i]->set_text(veffect[i - 1]->get_text());
534         }
535
536 // set up the new effect
537         veffect[0]->set_text(title);
538         return 0;
539 }
540
541 int MainMenu::add_load(char *path)
542 {
543         return load.add_load(path);
544 }
545
546
547
548 // ================================== menu items
549
550 MainDumpsSubMenu::MainDumpsSubMenu(BC_MenuItem *menu_item)
551  : BC_SubMenu()
552 {
553         this->menu_item = menu_item;
554 }
555 MainDumpsSubMenu::~MainDumpsSubMenu()
556 {
557 }
558
559
560 MainDumpsMenu::MainDumpsMenu(MWindow *mwindow)
561  : BC_MenuItem(_("Dumps..."))
562 {
563         this->mwindow = mwindow;
564         this->dumps_menu = 0;
565 }
566 MainDumpsMenu::~MainDumpsMenu()
567 {
568 }
569
570 void MainDumpsMenu::create_objects()
571 {
572         add_submenu(dumps_menu = new MainDumpsSubMenu(this));
573 //      dumps_menu->add_item(new DumpCICache(mwindow));
574         dumps_menu->add_item(new DumpEDL(mwindow));
575         dumps_menu->add_item(new DumpPlugins(mwindow));
576         dumps_menu->add_item(new DumpAssets(mwindow));
577         dumps_menu->add_item(new DumpUndo(mwindow));
578 };
579
580
581 DumpCICache::DumpCICache(MWindow *mwindow)
582  : BC_MenuItem(_("Dump CICache"))
583 { this->mwindow = mwindow; }
584
585 int DumpCICache::handle_event()
586 {
587 //      mwindow->cache->dump();
588         return 1;
589 }
590
591 DumpEDL::DumpEDL(MWindow *mwindow)
592  : BC_MenuItem(_("Dump EDL"))
593 {
594         this->mwindow = mwindow;
595 }
596
597 int DumpEDL::handle_event()
598 {
599         mwindow->dump_edl();
600         return 1;
601 }
602
603 DumpPlugins::DumpPlugins(MWindow *mwindow)
604  : BC_MenuItem(_("Dump Plugins"))
605 {
606         this->mwindow = mwindow;
607 }
608
609 int DumpPlugins::handle_event()
610 {
611         mwindow->dump_plugins();
612         return 1;
613 }
614
615 DumpAssets::DumpAssets(MWindow *mwindow)
616  : BC_MenuItem(_("Dump Assets"))
617 { this->mwindow = mwindow; }
618
619 int DumpAssets::handle_event()
620 {
621         mwindow->edl->assets->dump();
622         return 1;
623 }
624
625 DumpUndo::DumpUndo(MWindow *mwindow)
626  : BC_MenuItem(_("Dump Undo"))
627 {
628         this->mwindow = mwindow;
629 }
630
631 int DumpUndo::handle_event()
632 {
633         mwindow->dump_undo();
634         return 1;
635 }
636
637 // ================================================= edit
638
639 Undo::Undo(MWindow *mwindow) : BC_MenuItem(_("Undo"), "z", 'z')
640 {
641         this->mwindow = mwindow;
642 }
643 int Undo::handle_event()
644 {
645         if( mwindow->session->current_operation == NO_OPERATION )
646                 mwindow->undo_entry(mwindow->gui);
647         return 1;
648 }
649 int Undo::update_caption(const char *new_caption)
650 {
651         char string[BCTEXTLEN];
652         sprintf(string, _("Undo %s"), new_caption);
653         set_text(string);
654         return 0;
655 }
656
657
658 Redo::Redo(MWindow *mwindow) : BC_MenuItem(_("Redo"), _("Shift-Z"), 'Z')
659 {
660         set_shift(1);
661         this->mwindow = mwindow;
662 }
663
664 int Redo::handle_event()
665 {
666         if( mwindow->session->current_operation == NO_OPERATION )
667                 mwindow->redo_entry(mwindow->gui);
668         return 1;
669 }
670 int Redo::update_caption(const char *new_caption)
671 {
672         char string[BCTEXTLEN];
673         sprintf(string, _("Redo %s"), new_caption);
674         set_text(string);
675         return 0;
676 }
677
678 CutKeyframes::CutKeyframes(MWindow *mwindow)
679  : BC_MenuItem(_("Cut keyframes"), _("Shift-X"), 'X')
680 {
681         set_shift();
682         this->mwindow = mwindow;
683 }
684
685 int CutKeyframes::handle_event()
686 {
687         if( mwindow->session->current_operation == NO_OPERATION )
688                 mwindow->cut_automation();
689         return 1;
690 }
691
692 CopyKeyframes::CopyKeyframes(MWindow *mwindow)
693  : BC_MenuItem(_("Copy keyframes"), _("Shift-C"), 'C')
694 {
695         set_shift();
696         this->mwindow = mwindow;
697 }
698
699 int CopyKeyframes::handle_event()
700 {
701         if( mwindow->session->current_operation == NO_OPERATION )
702                 mwindow->copy_automation();
703         return 1;
704 }
705
706 PasteKeyframes::PasteKeyframes(MWindow *mwindow)
707  : BC_MenuItem(_("Paste keyframes"), _("Shift-V"), 'V')
708 {
709         set_shift();
710         this->mwindow = mwindow;
711 }
712
713 int PasteKeyframes::handle_event()
714 {
715         if( mwindow->session->current_operation == NO_OPERATION )
716                 mwindow->paste_automation();
717         return 1;
718 }
719
720 ClearKeyframes::ClearKeyframes(MWindow *mwindow)
721  : BC_MenuItem(_("Clear keyframes"), _("Shift-Del"), DELETE)
722 {
723         set_shift();
724         this->mwindow = mwindow;
725 }
726
727 int ClearKeyframes::handle_event()
728 {
729         if( mwindow->session->current_operation == NO_OPERATION )
730                 mwindow->clear_automation();
731         return 1;
732 }
733
734
735
736 StraightenKeyframes::StraightenKeyframes(MWindow *mwindow)
737  : BC_MenuItem(_("Change to linear"))
738 {
739         this->mwindow = mwindow;
740 }
741
742 int StraightenKeyframes::handle_event()
743 {
744         mwindow->set_automation_mode(FloatAuto::LINEAR);
745         return 1;
746 }
747
748
749
750
751 BendKeyframes::BendKeyframes(MWindow *mwindow)
752  : BC_MenuItem(_("Change to smooth"))
753 {
754         this->mwindow = mwindow;
755 }
756
757 int BendKeyframes::handle_event()
758 {
759         mwindow->set_automation_mode(FloatAuto::SMOOTH);
760         return 1;
761 }
762
763
764
765 KeyframeCurveType::KeyframeCurveType(MWindow *mwindow)
766  : BC_MenuItem(_("Create curve type..."))
767 {
768         this->mwindow = mwindow;
769         this->curve_menu = 0;
770 }
771 KeyframeCurveType::~KeyframeCurveType()
772 {
773 }
774
775 void KeyframeCurveType::create_objects()
776 {
777         add_submenu(curve_menu = new KeyframeCurveTypeMenu(this));
778         for( int i=FloatAuto::SMOOTH; i<=FloatAuto::FREE; ++i ) {
779                 KeyframeCurveTypeItem *curve_type_item = new KeyframeCurveTypeItem(i, this);
780                 curve_menu->add_submenuitem(curve_type_item);
781         }
782 }
783
784 void KeyframeCurveType::update(int curve_type)
785 {
786         for( int i=0; i<curve_menu->total_items(); ++i ) {
787                 KeyframeCurveTypeItem *curve_type_item = (KeyframeCurveTypeItem *)curve_menu->get_item(i);
788                 curve_type_item->set_checked(curve_type_item->type == curve_type);
789         }
790 }
791
792 int KeyframeCurveType::handle_event()
793 {
794         return 1;
795 }
796
797 KeyframeCurveTypeMenu::KeyframeCurveTypeMenu(KeyframeCurveType *menu_item)
798  : BC_SubMenu()
799 {
800         this->menu_item = menu_item;
801 }
802 KeyframeCurveTypeMenu::~KeyframeCurveTypeMenu()
803 {
804 }
805
806 KeyframeCurveTypeItem::KeyframeCurveTypeItem(int type, KeyframeCurveType *main_item)
807  : BC_MenuItem(FloatAuto::curve_name(type))
808 {
809         this->type = type;
810         this->main_item = main_item;
811 }
812 KeyframeCurveTypeItem::~KeyframeCurveTypeItem()
813 {
814 }
815
816 int KeyframeCurveTypeItem::handle_event()
817 {
818         main_item->update(type);
819         main_item->mwindow->set_keyframe_type(type);
820         return 1;
821 }
822
823
824 CutDefaultKeyframe::CutDefaultKeyframe(MWindow *mwindow)
825  : BC_MenuItem(_("Cut default keyframe"), _("Alt-x"), 'x')
826 {
827         set_alt();
828         this->mwindow = mwindow;
829 }
830
831 int CutDefaultKeyframe::handle_event()
832 {
833         if( mwindow->session->current_operation == NO_OPERATION )
834                 mwindow->cut_default_keyframe();
835         return 1;
836 }
837
838 CopyDefaultKeyframe::CopyDefaultKeyframe(MWindow *mwindow)
839  : BC_MenuItem(_("Copy default keyframe"), _("Alt-c"), 'c')
840 {
841         set_alt();
842         this->mwindow = mwindow;
843 }
844
845 int CopyDefaultKeyframe::handle_event()
846 {
847         if( mwindow->session->current_operation == NO_OPERATION )
848                 mwindow->copy_default_keyframe();
849         return 1;
850 }
851
852 PasteDefaultKeyframe::PasteDefaultKeyframe(MWindow *mwindow)
853  : BC_MenuItem(_("Paste default keyframe"), _("Alt-v"), 'v')
854 {
855         set_alt();
856         this->mwindow = mwindow;
857 }
858
859 int PasteDefaultKeyframe::handle_event()
860 {
861         if( mwindow->session->current_operation == NO_OPERATION )
862                 mwindow->paste_default_keyframe();
863         return 1;
864 }
865
866 ClearDefaultKeyframe::ClearDefaultKeyframe(MWindow *mwindow)
867  : BC_MenuItem(_("Clear default keyframe"), _("Alt-Del"), DELETE)
868 {
869         set_alt();
870         this->mwindow = mwindow;
871 }
872
873 int ClearDefaultKeyframe::handle_event()
874 {
875         if( mwindow->session->current_operation == NO_OPERATION )
876                 mwindow->clear_default_keyframe();
877         return 1;
878 }
879
880 Cut::Cut(MWindow *mwindow)
881  : BC_MenuItem(_("Split | Cut"), "x", 'x')
882 {
883         this->mwindow = mwindow;
884 }
885
886 int Cut::handle_event()
887 {
888         if( mwindow->session->current_operation == NO_OPERATION )
889                 mwindow->cut();
890         return 1;
891 }
892
893 Copy::Copy(MWindow *mwindow)
894  : BC_MenuItem(_("Copy"), "c", 'c')
895 {
896         this->mwindow = mwindow;
897 }
898
899 int Copy::handle_event()
900 {
901         if( mwindow->session->current_operation == NO_OPERATION )
902                 mwindow->copy();
903         return 1;
904 }
905
906 Paste::Paste(MWindow *mwindow)
907  : BC_MenuItem(_("Paste"), "v", 'v')
908 {
909         this->mwindow = mwindow;
910 }
911
912 int Paste::handle_event()
913 {
914         if( mwindow->session->current_operation == NO_OPERATION )
915                 mwindow->paste();
916         return 1;
917 }
918
919 EditClearSubMenu::EditClearSubMenu(BC_MenuItem *menu_item)
920  : BC_SubMenu()
921 {
922         this->menu_item = menu_item;
923 }
924 EditClearSubMenu::~EditClearSubMenu()
925 {
926 }
927
928 EditClearMenu::EditClearMenu(MWindow *mwindow)
929  : BC_MenuItem(_("Clear..."))
930 {
931         this->mwindow = mwindow;
932         this->clear_sub_menu = 0;
933 }
934 EditClearMenu::~EditClearMenu()
935 {
936 }
937
938 void EditClearMenu::create_objects()
939 {
940         add_submenu(clear_sub_menu = new EditClearSubMenu(this));
941         clear_sub_menu->add_item(new Clear(mwindow));
942         clear_sub_menu->add_item(new MuteSelection(mwindow));
943         clear_sub_menu->add_item(new ClearSelect(mwindow));
944         clear_sub_menu->add_item(new ClearLabels(mwindow));
945         clear_sub_menu->add_item(new ClearHardEdges(mwindow));
946 };
947
948 Clear::Clear(MWindow *mwindow)
949  : BC_MenuItem(_("Clear"), _("Del"), DELETE)
950 {
951         this->mwindow = mwindow;
952 }
953
954 int Clear::handle_event()
955 {
956         if( mwindow->session->current_operation == NO_OPERATION ) {
957                 mwindow->clear_entry();
958         }
959         return 1;
960 }
961
962 PasteSilence::PasteSilence(MWindow *mwindow)
963  : BC_MenuItem(_("Paste silence"), _("Shift-Space"), ' ')
964 {
965         this->mwindow = mwindow;
966         set_shift();
967 }
968
969 int PasteSilence::handle_event()
970 {
971         if( mwindow->session->current_operation == NO_OPERATION )
972                 mwindow->paste_silence();
973         return 1;
974 }
975
976 SelectAll::SelectAll(MWindow *mwindow)
977  : BC_MenuItem(_("Select All"), "a", 'a')
978 {
979         this->mwindow = mwindow;
980 }
981
982 int SelectAll::handle_event()
983 {
984         if( mwindow->session->current_operation == NO_OPERATION )
985                 mwindow->select_all();
986         return 1;
987 }
988
989 ClearHardEdges::ClearHardEdges(MWindow *mwindow) : BC_MenuItem(_("Clear Hard Edges"))
990 {
991         this->mwindow = mwindow;
992 }
993
994 int ClearHardEdges::handle_event()
995 {
996         mwindow->clear_hard_edges();
997         return 1;
998 }
999
1000 ClearLabels::ClearLabels(MWindow *mwindow) : BC_MenuItem(_("Clear labels"))
1001 {
1002         this->mwindow = mwindow;
1003 }
1004
1005 int ClearLabels::handle_event()
1006 {
1007         mwindow->clear_labels();
1008         return 1;
1009 }
1010
1011 ClearSelect::ClearSelect(MWindow *mwindow) : BC_MenuItem(_("Clear Select"),"Ctrl-Shift-A",'A')
1012 {
1013         set_ctrl(1);
1014         set_shift(1);
1015         this->mwindow = mwindow;
1016 }
1017
1018 int ClearSelect::handle_event()
1019 {
1020         mwindow->clear_select();
1021         return 1;
1022 }
1023
1024 CutCommercials::CutCommercials(MWindow *mwindow) : BC_MenuItem(_("Cut ads"))
1025 {
1026         this->mwindow = mwindow;
1027 }
1028
1029 int CutCommercials::handle_event()
1030 {
1031         mwindow->cut_commercials();
1032         return 1;
1033 }
1034
1035 DetachTransitions::DetachTransitions(MWindow *mwindow)
1036  : BC_MenuItem(_("Detach transitions"))
1037 {
1038         this->mwindow = mwindow;
1039 }
1040
1041 int DetachTransitions::handle_event()
1042 {
1043         mwindow->detach_transitions();
1044         return 1;
1045 }
1046
1047 MuteSelection::MuteSelection(MWindow *mwindow)
1048  : BC_MenuItem(_("Mute Region"), "m", 'm')
1049 {
1050         this->mwindow = mwindow;
1051 }
1052
1053 int MuteSelection::handle_event()
1054 {
1055         if( mwindow->session->current_operation == NO_OPERATION )
1056                 mwindow->mute_selection();
1057         return 1;
1058 }
1059
1060
1061 TrimSelection::TrimSelection(MWindow *mwindow)
1062  : BC_MenuItem(_("Trim Selection"))
1063 {
1064         this->mwindow = mwindow;
1065 }
1066
1067 int TrimSelection::handle_event()
1068 {
1069         mwindow->trim_selection();
1070         return 1;
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 // ============================================= audio
1085
1086 AddAudioTrack::AddAudioTrack(MWindow *mwindow)
1087  : BC_MenuItem(_("Add track"), "t", 't')
1088 {
1089         this->mwindow = mwindow;
1090 }
1091
1092 int AddAudioTrack::handle_event()
1093 {
1094         if( mwindow->session->current_operation == NO_OPERATION )
1095                 mwindow->add_audio_track_entry(0, 0);
1096         return 1;
1097 }
1098
1099 DeleteAudioTrack::DeleteAudioTrack(MWindow *mwindow)
1100  : BC_MenuItem(_("Delete track"))
1101 {
1102         this->mwindow = mwindow;
1103 }
1104
1105 int DeleteAudioTrack::handle_event()
1106 {
1107         return 1;
1108 }
1109
1110 DefaultATransition::DefaultATransition(MWindow *mwindow)
1111  : BC_MenuItem(_("Default Transition"), "u", 'u')
1112 {
1113         this->mwindow = mwindow;
1114 }
1115
1116 int DefaultATransition::handle_event()
1117 {
1118         if( mwindow->session->current_operation == NO_OPERATION )
1119                 mwindow->paste_audio_transition();
1120         return 1;
1121 }
1122
1123
1124 MapAudio1::MapAudio1(MWindow *mwindow)
1125  : BC_MenuItem(_("Map 1:1"))
1126 {
1127         this->mwindow = mwindow;
1128 }
1129
1130 int MapAudio1::handle_event()
1131 {
1132         mwindow->map_audio(MWindow::AUDIO_1_TO_1);
1133         return 1;
1134 }
1135
1136 MapAudio2::MapAudio2(MWindow *mwindow)
1137  : BC_MenuItem(_("Map 5.1:2"))
1138 {
1139         this->mwindow = mwindow;
1140 }
1141
1142 int MapAudio2::handle_event()
1143 {
1144         mwindow->map_audio(MWindow::AUDIO_5_1_TO_2);
1145         return 1;
1146 }
1147
1148
1149
1150
1151 // ============================================= video
1152
1153
1154 AddVideoTrack::AddVideoTrack(MWindow *mwindow)
1155  : BC_MenuItem(_("Add track"), _("Shift-T"), 'T')
1156 {
1157         set_shift();
1158         this->mwindow = mwindow;
1159 }
1160
1161 int AddVideoTrack::handle_event()
1162 {
1163         if( mwindow->session->current_operation == NO_OPERATION )
1164                 mwindow->add_video_track_entry(1, 0);
1165         return 1;
1166 }
1167
1168
1169 DeleteVideoTrack::DeleteVideoTrack(MWindow *mwindow)
1170  : BC_MenuItem(_("Delete track"))
1171 {
1172         this->mwindow = mwindow;
1173 }
1174
1175 int DeleteVideoTrack::handle_event()
1176 {
1177         return 1;
1178 }
1179
1180
1181
1182 ResetTranslation::ResetTranslation(MWindow *mwindow)
1183  : BC_MenuItem(_("Reset Translation"))
1184 {
1185         this->mwindow = mwindow;
1186 }
1187
1188 int ResetTranslation::handle_event()
1189 {
1190         return 1;
1191 }
1192
1193
1194
1195 DefaultVTransition::DefaultVTransition(MWindow *mwindow)
1196  : BC_MenuItem(_("Default Transition"), _("Shift-U"), 'U')
1197 {
1198         set_shift();
1199         this->mwindow = mwindow;
1200 }
1201
1202 int DefaultVTransition::handle_event()
1203 {
1204         if( mwindow->session->current_operation == NO_OPERATION )
1205                 mwindow->paste_video_transition();
1206         return 1;
1207 }
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 // ============================================ settings
1223
1224 DeleteTracks::DeleteTracks(MWindow *mwindow)
1225  : BC_MenuItem(_("Delete tracks"))
1226 {
1227         this->mwindow = mwindow;
1228 }
1229
1230 int DeleteTracks::handle_event()
1231 {
1232         mwindow->delete_tracks();
1233         return 1;
1234 }
1235
1236 DeleteFirstTrack::DeleteFirstTrack(MWindow *mwindow)
1237  : BC_MenuItem(_("Delete first track"), "Shift-D", 'D')
1238 {
1239         set_shift(1);
1240         this->mwindow = mwindow;
1241 }
1242
1243 int DeleteFirstTrack::handle_event()
1244 {
1245         if( mwindow->session->current_operation == NO_OPERATION ) {
1246                 Track *track = mwindow->edl->tracks->first;
1247                 if( track ) mwindow->delete_track(track);
1248         }
1249         return 1;
1250 }
1251
1252 DeleteLastTrack::DeleteLastTrack(MWindow *mwindow)
1253  : BC_MenuItem(_("Delete last track"), "Ctrl-d", 'd')
1254 {
1255         set_ctrl(1);
1256         this->mwindow = mwindow;
1257 }
1258
1259 int DeleteLastTrack::handle_event()
1260 {
1261         if( mwindow->session->current_operation == NO_OPERATION ) {
1262                 Track *track = mwindow->edl->tracks->last;
1263                 if( track ) mwindow->delete_track(track);
1264         }
1265         return 1;
1266 }
1267
1268 MoveTracksUp::MoveTracksUp(MWindow *mwindow)
1269  : BC_MenuItem(_("Move tracks up"), _("Shift-Up"), UP)
1270 {
1271         this->mwindow = mwindow;
1272         set_shift();
1273 }
1274
1275 int MoveTracksUp::handle_event()
1276 {
1277         if( mwindow->session->current_operation == NO_OPERATION )
1278                 mwindow->move_tracks_up();
1279         return 1;
1280 }
1281
1282 MoveTracksDown::MoveTracksDown(MWindow *mwindow)
1283  : BC_MenuItem(_("Move tracks down"), _("Shift-Down"), DOWN)
1284 {
1285         set_shift(); this->mwindow = mwindow;
1286 }
1287
1288 int MoveTracksDown::handle_event()
1289 {
1290         if( mwindow->session->current_operation == NO_OPERATION )
1291                 mwindow->move_tracks_down();
1292         return 1;
1293 }
1294
1295
1296 SwapTracksUp::SwapTracksUp(MWindow *mwindow)
1297  : BC_MenuItem(_("Swap tracks up"), 0, UP)
1298 {
1299         this->mwindow = mwindow;
1300         set_shift();
1301 }
1302
1303 int SwapTracksUp::handle_event()
1304 {
1305         if( mwindow->session->current_operation == NO_OPERATION )
1306                 mwindow->swap_tracks_up();
1307         return 1;
1308 }
1309
1310 SwapTracksDown::SwapTracksDown(MWindow *mwindow)
1311  : BC_MenuItem(_("Swap tracks down"), 0, DOWN)
1312 {
1313         set_shift(); this->mwindow = mwindow;
1314 }
1315
1316 int SwapTracksDown::handle_event()
1317 {
1318         if( mwindow->session->current_operation == NO_OPERATION )
1319                 mwindow->swap_tracks_down();
1320         return 1;
1321 }
1322
1323
1324
1325
1326 ConcatenateTracks::ConcatenateTracks(MWindow *mwindow)
1327  : BC_MenuItem(_("Concatenate tracks"))
1328 {
1329         set_shift();
1330         this->mwindow = mwindow;
1331 }
1332
1333 int ConcatenateTracks::handle_event()
1334 {
1335         mwindow->concatenate_tracks();
1336         return 1;
1337 }
1338
1339
1340
1341
1342
1343 LoopPlayback::LoopPlayback(MWindow *mwindow)
1344  : BC_MenuItem(_("Loop Playback"), _("Shift-L"), 'L')
1345 {
1346         this->mwindow = mwindow;
1347         set_checked(mwindow->edl->local_session->loop_playback);
1348         set_shift();
1349 }
1350
1351 int LoopPlayback::handle_event()
1352 {
1353         if( mwindow->session->current_operation == NO_OPERATION ) {
1354                 mwindow->toggle_loop_playback();
1355                 set_checked(mwindow->edl->local_session->loop_playback);
1356         }
1357         return 1;
1358 }
1359
1360
1361
1362 // ============================================= subtitle
1363
1364
1365 AddSubttlTrack::AddSubttlTrack(MWindow *mwindow)
1366  : BC_MenuItem(_("Add subttl"), _("Shift-Y"), 'Y')
1367 {
1368         set_shift();
1369         this->mwindow = mwindow;
1370 }
1371
1372 int AddSubttlTrack::handle_event()
1373 {
1374         if( mwindow->session->current_operation == NO_OPERATION )
1375                 mwindow->add_subttl_track_entry(1, 0);
1376         return 1;
1377 }
1378
1379 PasteSubttl::PasteSubttl(MWindow *mwindow)
1380  : BC_MenuItem(_("paste subttl"), "y", 'y')
1381 {
1382         this->mwindow = mwindow;
1383 }
1384
1385 int PasteSubttl::handle_event()
1386 {
1387         if( mwindow->session->current_operation == NO_OPERATION )
1388                 mwindow->gui->swindow->paste_subttl();
1389         return 1;
1390 }
1391
1392
1393 SetBRenderActive::SetBRenderActive(MWindow *mwindow)
1394  : BC_MenuItem(_("Toggle background rendering"),_("Shift-G"),'G')
1395 {
1396         this->mwindow = mwindow;
1397         set_shift(1);
1398 }
1399
1400 int SetBRenderActive::handle_event()
1401 {
1402         if( mwindow->session->current_operation == NO_OPERATION ) {
1403                 int v = mwindow->brender_active ? 0 : 1;
1404                 set_checked(v);
1405                 mwindow->set_brender_active(v);
1406         }
1407         return 1;
1408 }
1409
1410
1411 LabelsFollowEdits::LabelsFollowEdits(MWindow *mwindow)
1412  : BC_MenuItem(_("Edit labels"))
1413 {
1414         this->mwindow = mwindow;
1415         set_checked(mwindow->edl->session->labels_follow_edits);
1416 }
1417
1418 int LabelsFollowEdits::handle_event()
1419 {
1420         set_checked(get_checked() ^ 1);
1421         mwindow->set_labels_follow_edits(get_checked());
1422         return 1;
1423 }
1424
1425
1426
1427
1428 PluginsFollowEdits::PluginsFollowEdits(MWindow *mwindow)
1429  : BC_MenuItem(_("Edit effects"))
1430 {
1431         this->mwindow = mwindow;
1432         set_checked(mwindow->edl->session->plugins_follow_edits);
1433 }
1434
1435 int PluginsFollowEdits::handle_event()
1436 {
1437         set_checked(get_checked() ^ 1);
1438         mwindow->edl->session->plugins_follow_edits = get_checked();
1439         return 1;
1440 }
1441
1442
1443
1444
1445 KeyframesFollowEdits::KeyframesFollowEdits(MWindow *mwindow)
1446  : BC_MenuItem(_("Keyframes follow edits"))
1447 {
1448         this->mwindow = mwindow;
1449         set_checked(mwindow->edl->session->autos_follow_edits);
1450 }
1451
1452 int KeyframesFollowEdits::handle_event()
1453 {
1454         mwindow->edl->session->autos_follow_edits ^= 1;
1455         set_checked(!get_checked());
1456         return 1;
1457 }
1458
1459
1460 CursorOnFrames::CursorOnFrames(MWindow *mwindow)
1461  : BC_MenuItem(_("Align cursor on frames"),_("Ctrl-a"),'a')
1462 {
1463         this->mwindow = mwindow;
1464         set_checked(mwindow->edl->session->cursor_on_frames);
1465         set_ctrl(1);
1466 }
1467
1468 int CursorOnFrames::handle_event()
1469 {
1470         mwindow->edl->session->cursor_on_frames = !mwindow->edl->session->cursor_on_frames;
1471         set_checked(mwindow->edl->session->cursor_on_frames);
1472         return 1;
1473 }
1474
1475
1476 TypelessKeyframes::TypelessKeyframes(MWindow *mwindow)
1477  : BC_MenuItem(_("Typeless keyframes"))
1478 {
1479         this->mwindow = mwindow;
1480         set_checked(mwindow->edl->session->typeless_keyframes);
1481 }
1482
1483 int TypelessKeyframes::handle_event()
1484 {
1485         mwindow->edl->session->typeless_keyframes = !mwindow->edl->session->typeless_keyframes;
1486         set_checked(mwindow->edl->session->typeless_keyframes);
1487         return 1;
1488 }
1489
1490
1491 ScrubSpeed::ScrubSpeed(MWindow *mwindow)
1492  : BC_MenuItem(_("Slow Shuttle"))
1493 {
1494         this->mwindow = mwindow;
1495 }
1496
1497 int ScrubSpeed::handle_event()
1498 {
1499         if(mwindow->edl->session->scrub_speed == .5)
1500         {
1501                 mwindow->edl->session->scrub_speed = 2;
1502                 set_text(_("Slow Shuttle"));
1503         }
1504         else
1505         {
1506                 mwindow->edl->session->scrub_speed = .5;
1507                 set_text(_("Fast Shuttle"));
1508         }
1509         return 1;
1510 }
1511
1512 SaveSettingsNow::SaveSettingsNow(MWindow *mwindow)
1513  : BC_MenuItem(_("Save settings now"),_("Ctrl-s"),'s')
1514 {
1515         this->mwindow = mwindow;
1516         set_ctrl(1);
1517 }
1518
1519 int SaveSettingsNow::handle_event()
1520 {
1521         mwindow->save_defaults();
1522         mwindow->save_backup();
1523         mwindow->gui->show_message(_("Saved settings."));
1524         return 1;
1525 }
1526
1527
1528
1529 // ============================================ window
1530
1531
1532
1533
1534
1535 ShowVWindow::ShowVWindow(MWindow *mwindow)
1536  : BC_MenuItem(_("Show Viewer"))
1537 {
1538         this->mwindow = mwindow;
1539         set_checked(mwindow->session->show_vwindow);
1540 }
1541 int ShowVWindow::handle_event()
1542 {
1543         mwindow->gui->unlock_window();
1544         mwindow->show_vwindow();
1545         mwindow->gui->lock_window("ShowVWindow::handle_event");
1546         return 1;
1547 }
1548
1549 ShowAWindow::ShowAWindow(MWindow *mwindow)
1550  : BC_MenuItem(_("Show Resources"))
1551 {
1552         this->mwindow = mwindow;
1553         set_checked(mwindow->session->show_awindow);
1554 }
1555 int ShowAWindow::handle_event()
1556 {
1557         mwindow->gui->unlock_window();
1558         mwindow->show_awindow();
1559         mwindow->gui->lock_window("ShowAWindow::handle_event");
1560         return 1;
1561 }
1562
1563 ShowCWindow::ShowCWindow(MWindow *mwindow)
1564  : BC_MenuItem(_("Show Compositor"))
1565 {
1566         this->mwindow = mwindow;
1567         set_checked(mwindow->session->show_cwindow);
1568 }
1569 int ShowCWindow::handle_event()
1570 {
1571         mwindow->gui->unlock_window();
1572         mwindow->show_cwindow();
1573         mwindow->gui->lock_window("ShowCWindow::handle_event");
1574         return 1;
1575 }
1576
1577
1578 ShowGWindow::ShowGWindow(MWindow *mwindow)
1579  : BC_MenuItem(_("Show Overlays"), _("Ctrl-0"), '0')
1580 {
1581         this->mwindow = mwindow;
1582         set_ctrl(1);
1583         set_checked(mwindow->session->show_gwindow);
1584 }
1585 int ShowGWindow::handle_event()
1586 {
1587         if( mwindow->session->current_operation == NO_OPERATION ) {
1588                 mwindow->gui->unlock_window();
1589                 if( !mwindow->session->show_gwindow )
1590                         mwindow->show_gwindow();
1591                 else
1592                         mwindow->hide_gwindow();
1593                 mwindow->gui->lock_window("ShowGWindow::handle_event");
1594                 set_checked(mwindow->session->show_gwindow);
1595         }
1596         return 1;
1597 }
1598
1599
1600 ShowLWindow::ShowLWindow(MWindow *mwindow)
1601  : BC_MenuItem(_("Show Levels"))
1602 {
1603         this->mwindow = mwindow;
1604         set_checked(mwindow->session->show_lwindow);
1605 }
1606 int ShowLWindow::handle_event()
1607 {
1608         mwindow->gui->unlock_window();
1609         mwindow->show_lwindow();
1610         mwindow->gui->lock_window("ShowLWindow::handle_event");
1611         return 1;
1612 }
1613
1614 TileWindows::TileWindows(MWindow *mwindow, const char *item_title, int config,
1615                 const char *hot_keytext, int hot_key)
1616  : BC_MenuItem(item_title, hot_keytext, hot_key)
1617 {
1618         this->mwindow = mwindow;
1619         this->config = config;
1620         if( hot_key ) set_ctrl(1);
1621 }
1622 int TileWindows::handle_event()
1623 {
1624         if( mwindow->session->current_operation == NO_OPERATION ) {
1625                 int window_config = config >= 0 ? config :
1626                         mwindow->session->window_config;
1627                 if( mwindow->tile_windows(window_config) ) {
1628                         mwindow->restart_status = 1;
1629                         mwindow->gui->set_done(0);
1630                 }
1631         }
1632         return 1;
1633 }
1634
1635 SplitX::SplitX(MWindow *mwindow)
1636  : BC_MenuItem(_("Split X pane"), _("Ctrl-1"), '1')
1637 {
1638         this->mwindow = mwindow;
1639         set_ctrl(1);
1640         set_checked(mwindow->gui->pane[TOP_RIGHT_PANE] != 0);
1641 }
1642 int SplitX::handle_event()
1643 {
1644         if( mwindow->session->current_operation == NO_OPERATION )
1645                 mwindow->split_x();
1646         return 1;
1647 }
1648
1649 SplitY::SplitY(MWindow *mwindow)
1650  : BC_MenuItem(_("Split Y pane"), _("Ctrl-2"), '2')
1651 {
1652         this->mwindow = mwindow;
1653         set_ctrl(1);
1654         set_checked(mwindow->gui->pane[BOTTOM_LEFT_PANE] != 0);
1655 }
1656 int SplitY::handle_event()
1657 {
1658         if( mwindow->session->current_operation == NO_OPERATION )
1659                 mwindow->split_y();
1660         return 1;
1661 }
1662
1663
1664 MixerItems::MixerItems(MWindow *mwindow)
1665  : BC_MenuItem(_("Mixers..."))
1666 {
1667         this->mwindow = mwindow;
1668 }
1669
1670 void MixerItems::create_objects()
1671 {
1672         BC_SubMenu *mixer_submenu = new BC_SubMenu();
1673         add_submenu(mixer_submenu);
1674         mixer_submenu->add_submenuitem(new MixerViewer(this));
1675         mixer_submenu->add_submenuitem(new TileMixers(this));
1676         mixer_submenu->add_submenuitem(new AlignMixers(this));
1677 }
1678
1679 int MixerItems::activate_submenu()
1680 {
1681         BC_SubMenu *mixer_submenu = (BC_SubMenu *)get_submenu();
1682         int k = mixer_submenu->total_items();
1683         while( --k >= 0 ) {
1684                 MixerItem *mixer_item = (MixerItem *)mixer_submenu->get_item(k);
1685                 if( mixer_item->idx < 0 ) continue;
1686                 mixer_submenu->del_item(mixer_item);
1687         }
1688         int n = mwindow->edl->mixers.size();
1689         for( int i=0; i<n; ++i ) {
1690                 Mixer *mixer = mwindow->edl->mixers[i];
1691                 if( !mixer ) continue;
1692                 MixerItem *mixer_item = new MixerItem(this, mixer->title, mixer->idx);
1693                 mixer_submenu->add_submenuitem(mixer_item);
1694         }
1695         return BC_MenuItem::activate_submenu();
1696 }
1697
1698 MixerItem::MixerItem(MixerItems *mixer_items, const char *text, int idx)
1699  : BC_MenuItem(text)
1700 {
1701         this->mixer_items = mixer_items;
1702         this->idx = idx;
1703 }
1704
1705 MixerItem::MixerItem(MixerItems *mixer_items, const char *text, const char *hotkey_text, int hotkey)
1706  : BC_MenuItem(text, hotkey_text, hotkey)
1707 {
1708         this->mixer_items = mixer_items;
1709         this->idx = -1;
1710 }
1711
1712 int MixerItem::handle_event()
1713 {
1714         if( idx < 0 ) return 0;
1715         MWindow *mwindow = mixer_items->mwindow;
1716         Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
1717         if( !mixer ) return 0;
1718         ZWindow *zwindow = mwindow->get_mixer(idx);
1719         if( !zwindow )
1720                 zwindow = mwindow->get_mixer(mixer);
1721         if( !zwindow->zgui ) {
1722                 zwindow->set_title(mixer->title);
1723                 zwindow->start();
1724         }
1725         zwindow->zgui->lock_window("MixerItem::handle_event");
1726         zwindow->zgui->raise_window();
1727         zwindow->zgui->unlock_window();
1728         mwindow->refresh_mixers();
1729         return 1;
1730 }
1731
1732 MixerViewer::MixerViewer(MixerItems *mixer_items)
1733  : MixerItem(mixer_items, _("Mixer Viewer"), _("Shift-M"), 'M')
1734 {
1735         set_shift(1);
1736 }
1737
1738 int MixerViewer::handle_event()
1739 {
1740         MWindow *mwindow = mixer_items->mwindow;
1741         mwindow->start_mixer();
1742         return 1;
1743 }
1744
1745 TileMixers::TileMixers(MixerItems *mixer_items)
1746  : MixerItem(mixer_items, _("Tile mixers"), "Alt-t", 't')
1747 {
1748         set_alt();
1749 }
1750
1751 int TileMixers::handle_event()
1752 {
1753         MWindow *mwindow = mixer_items->mwindow;
1754         mwindow->tile_mixers();
1755         return 1;
1756 }
1757
1758 AlignMixers::AlignMixers(MixerItems *mixer_items)
1759  : MixerItem(mixer_items, _("Align mixers"), "", 0)
1760 {
1761 }
1762
1763 int AlignMixers::handle_event()
1764 {
1765         MWindow *mwindow = mixer_items->mwindow;
1766         int wx, wy;
1767         mwindow->gui->get_abs_cursor(wx, wy);
1768         mwindow->mixers_align->start_dialog(wx, wy);
1769         return 1;
1770 }
1771
1772
1773 AlignTimecodes::AlignTimecodes(MWindow *mwindow)
1774  : BC_MenuItem(_("Align Timecodes"))
1775 {
1776         this->mwindow = mwindow;
1777 }
1778
1779 int AlignTimecodes::handle_event()
1780 {
1781         mwindow->align_timecodes();
1782         return 1;
1783 }
1784
1785
1786 LoadLayoutItem::LoadLayoutItem(LoadLayout *load_layout, const char *text, int idx, int hotkey)
1787  : BC_MenuItem(text, "", hotkey)
1788 {
1789         this->idx = idx;
1790         this->load_layout = load_layout;
1791         if( hotkey ) {
1792                 char hot_txt[BCSTRLEN];
1793                 sprintf(hot_txt, _("Ctrl-Shift+F%d"), hotkey-KEY_F1+1);
1794                 set_ctrl();  set_shift();
1795                 set_hotkey_text(hot_txt);
1796         }
1797 }
1798
1799
1800 int LoadLayoutItem::handle_event()
1801 {
1802 // key_press hotkey skips over activate_submenu
1803         load_layout->update();
1804         MWindow *mwindow = load_layout->mwindow;
1805         switch( load_layout->action ) {
1806         case LAYOUT_LOAD:
1807                 mwindow->load_layout(layout_file);
1808                 break;
1809         case LAYOUT_SAVE: {
1810                 int wx = 0, wy = 0;
1811                 mwindow->gui->get_abs_cursor(wx, wy);
1812                 load_layout->layout_dialog->start_confirm_dialog(wx, wy, idx);
1813                 break; }
1814         }
1815         return 1;
1816 }
1817
1818 LoadLayout::LoadLayout(MWindow *mwindow, const char *text, int action)
1819  : BC_MenuItem(text)
1820 {
1821         this->mwindow = mwindow;
1822         this->action = action;
1823         this->layout_dialog = new LoadLayoutDialog(this);
1824 }
1825
1826 LoadLayout::~LoadLayout()
1827 {
1828         delete layout_dialog;
1829 }
1830
1831 void LoadLayout::create_objects()
1832 {
1833         BC_SubMenu *layout_submenu = new BC_SubMenu();
1834         add_submenu(layout_submenu);
1835
1836         for( int i=0; i<LAYOUTS_MAX; ++i ) {
1837                 char text[BCSTRLEN];
1838                 sprintf(text, _("Layout %d"), i+1);
1839                 LoadLayoutItem *item = new LoadLayoutItem(this, text, i,
1840                                 action==LAYOUT_LOAD ? KEY_F1+i : 0);
1841                 layout_submenu->add_submenuitem(item);
1842         }
1843 }
1844
1845 int LoadLayout::activate_submenu()
1846 {
1847         update();
1848         return BC_MenuItem::activate_submenu();
1849 }
1850
1851 void LoadLayout::update()
1852 {
1853         FileSystem fs;
1854         fs.set_filter("layout*_rc");
1855         int ret = fs.update(File::get_config_path());
1856         int sz = !ret ? fs.dir_list.size() : 0;
1857         BC_SubMenu *layout_submenu = get_submenu();
1858
1859         for( int i=0; i<LAYOUTS_MAX; ++i ) {
1860                 LoadLayoutItem* item = (LoadLayoutItem *)
1861                         layout_submenu->get_item(i);
1862                 char layout_text[BCSTRLEN];  layout_text[0] = 0;
1863                 int n = sz, id = i+1;
1864                 while( --n >= 0 ) {
1865                         char *np = fs.dir_list[n]->name;
1866                         char *cp = strrchr(np, '_'), *bp = 0;
1867                         int no = strtol(np+6, &bp, 10);
1868                         if( no != id || !bp ) continue;
1869                         if( bp == cp ) {  n = -1;  break; }
1870                         if( *bp++ == '_' && bp < cp && !strcmp(cp, "_rc") ) {
1871                                 int k = cp - bp;  char *tp = layout_text;
1872                                 if( k > LAYOUT_NAME_LEN ) k = LAYOUT_NAME_LEN;
1873                                 while( --k >= 0 ) *tp++ = *bp++;
1874                                 *tp = 0;
1875                                 break;
1876                         }
1877                 }
1878                 strcpy(item->layout_text, layout_text);
1879                 char *lp = item->layout_file;
1880                 int k = sprintf(lp, LAYOUT_FILE, id);
1881                 if( n >= 0 && layout_text[0] )
1882                         sprintf(lp + k-2, "%s_rc", layout_text);
1883                 else
1884                         sprintf(layout_text, _("Layout %d"), id);
1885                 item->set_text(layout_text);
1886         }
1887 }
1888
1889 LoadLayoutDialog::LoadLayoutDialog(LoadLayout *load_layout)
1890 {
1891         this->load_layout = load_layout;
1892         wx = 0;  wy = 0;
1893         idx = -1;
1894         lgui = 0;
1895 }
1896
1897 LoadLayoutDialog::~LoadLayoutDialog()
1898 {
1899         close_window();
1900 }
1901
1902 void LoadLayoutDialog::handle_done_event(int result)
1903 {
1904         if( result ) return;
1905         char layout_file[BCSTRLEN];
1906         BC_SubMenu *layout_submenu = load_layout->get_submenu();
1907         LoadLayoutItem* item =
1908                 (LoadLayoutItem *) layout_submenu->get_item(idx);
1909         snprintf(layout_file, sizeof(layout_file), "%s", item->layout_file);
1910         load_layout->mwindow->delete_layout(layout_file);
1911         int k = sprintf(layout_file, LAYOUT_FILE, idx+1);
1912         const char *text = lgui->name_text->get_text();
1913         if( text[0] )
1914                 snprintf(layout_file + k-2, sizeof(layout_file)-k+2, "%s_rc", text);
1915         load_layout->mwindow->save_layout(layout_file);
1916 }
1917
1918 void LoadLayoutDialog::handle_close_event(int result)
1919 {
1920         lgui = 0;
1921 }
1922
1923 BC_Window *LoadLayoutDialog::new_gui()
1924 {
1925         lgui = new LoadLayoutConfirm(this, wx, wy);
1926         lgui->create_objects();
1927         return lgui;
1928 }
1929
1930 void LoadLayoutDialog::start_confirm_dialog(int wx, int wy, int idx)
1931 {
1932         close_window();
1933         this->wx = wx;  this->wy = wy;
1934         this->idx = idx;
1935         start();
1936 }
1937
1938 LoadLayoutNameText::LoadLayoutNameText(LoadLayoutConfirm *confirm,
1939                 int x, int y, int w, const char *text)
1940  : BC_TextBox(x, y, w, 1, text)
1941 {
1942         this->confirm = confirm;
1943 }
1944
1945 LoadLayoutNameText::~LoadLayoutNameText()
1946 {
1947 }
1948
1949 int LoadLayoutNameText::handle_event()
1950 {
1951         const char *text = get_text();
1952         int len = strlen(text), k = 0;
1953         char new_text[BCTEXTLEN];
1954         for( int i=0; i<len; ++i ) {
1955                 int ch = text[i];
1956                 if( (ch>='A' && ch<='Z') || (ch>='a' && ch<='z') ||
1957                     (ch>='0' && ch<='9') || ch=='_' )
1958                         new_text[k++] = ch;
1959         }
1960         new_text[k] = 0;  len = k;
1961         int i = len - LAYOUT_NAME_LEN;
1962         if( i >= 0 ) {
1963                 k = 0;
1964                 while( i < len ) new_text[k++] = new_text[i++];
1965                 new_text[k] = 0;
1966         }
1967         update(new_text);
1968         return 1;
1969 }
1970
1971 LoadLayoutConfirm::LoadLayoutConfirm(LoadLayoutDialog *layout_dialog, int x, int y)
1972  : BC_Window(_(PROGRAM_NAME ": Layout"), x, y, xS(300),yS(140), xS(300),yS(140), 0)
1973 {
1974         this->layout_dialog = layout_dialog;
1975 }
1976
1977 LoadLayoutConfirm::~LoadLayoutConfirm()
1978 {
1979 }
1980
1981 void LoadLayoutConfirm::create_objects()
1982 {
1983         int xs10 = xS(10), xs20 = xS(20);
1984         int ys10 = yS(10);
1985         lock_window("LoadLayoutConfirm::create_objects");
1986         int x = xs10, y = ys10;
1987         BC_SubMenu *layout_submenu = layout_dialog->load_layout->get_submenu();
1988         LoadLayoutItem *item = (LoadLayoutItem *)
1989                 layout_submenu->get_item(layout_dialog->idx);
1990         BC_Title *title;
1991         add_subwindow(title = new BC_Title(x, y, _("Layout Name:")));
1992         int x1 = x + title->get_w() + xs10;
1993         add_subwindow(title = new BC_Title(x1, y, item->get_text()));
1994         y += title->get_h() + ys10;
1995         add_subwindow(name_text = new LoadLayoutNameText(this,
1996                 x, y, get_w()-x-xs20, item->layout_text));
1997         y += name_text->get_h();
1998         x1 = x + xS(80);
1999         char legend[BCTEXTLEN];
2000         sprintf(legend, _("a-z,A-Z,0-9_ only, %dch max"), LAYOUT_NAME_LEN);
2001         add_subwindow(title = new BC_Title(x1, y, legend));
2002         add_subwindow(new BC_OKButton(this));
2003         add_subwindow(new BC_CancelButton(this));
2004         unlock_window();
2005 }
2006
2007
2008 LoadRecentItem::LoadRecentItem(const char *path)
2009 {
2010         this->path = cstrdup(path);
2011 }
2012
2013 LoadRecentItem::~LoadRecentItem()
2014 {
2015         delete [] path;
2016 }
2017
2018 int LoadRecentItems::add_load(char *path)
2019 {
2020 // test for existing copy
2021         FileSystem fs;
2022         char name[BCTEXTLEN], text[BCTEXTLEN];
2023         fs.extract_name(name, path);
2024         int loads_total = size();
2025         int ret = 0, k = loads_total;
2026         LoadRecentItem *load_item = 0;
2027
2028         for( int i=0; !ret && i<loads_total; ++i ) {
2029                 load_item = get(i);
2030                 fs.extract_name(text, load_item->path);
2031                 if( strcmp(name, text) ) continue;
2032                 k = i;  ret = 1; // already exists, move to top
2033         }
2034         if( !ret ) { // adding a new one
2035                 while( loads_total >= TOTAL_LOADS )
2036                         remove_object_number(--loads_total);
2037                 insert(new LoadRecentItem(path), 0);
2038         }
2039         else if( k > 0 ) { // cycle loads
2040                 while( --k >= 0 ) set(k+1, get(k));
2041                 set(0, load_item);
2042         }
2043         return ret;
2044 }
2045
2046 LoadRecentItems::LoadRecentItems()
2047 {
2048 }
2049
2050 LoadRecentItems::~LoadRecentItems()
2051 {
2052         remove_all_objects();
2053 }
2054
2055 LoadRecent::LoadRecent(MWindow *mwindow, MainMenu *main_menu)
2056  : BC_MenuItem(_("Load Recent..."))
2057 {
2058         this->mwindow = mwindow;
2059         this->main_menu = main_menu;
2060         total_items = 0;
2061 }
2062 LoadRecent::~LoadRecent()
2063 {
2064 }
2065
2066 void LoadRecent::create_objects()
2067 {
2068         add_submenu(submenu = new LoadRecentSubMenu(this));
2069 }
2070
2071 LoadPrevious *LoadRecent::get_next_item()
2072 {
2073         int k = total_items++;
2074         if( k < submenu->total_items() )
2075                 return (LoadPrevious *)submenu->get_item(k);
2076         LoadPrevious *load_prev = new LoadPrevious(mwindow, main_menu->load_file);
2077         submenu->add_item(load_prev);
2078         return load_prev;
2079 }
2080
2081 int LoadRecent::activate_submenu()
2082 {
2083         total_items = 0;
2084         scan_items(1);
2085         if( total_items > 0 ) {
2086                 LoadPrevious *load_prev = get_next_item();
2087                 load_prev->set_text("-");
2088                 load_prev->set_path("");
2089         }
2090         scan_items(0);
2091         while( total_items < submenu->total_items() )
2092                 submenu->del_item(0);
2093         return BC_MenuItem::activate_submenu();
2094 }
2095
2096 void LoadRecent::scan_items(int use_xml)
2097 {
2098         FileSystem fs;
2099         int loads_total = main_menu->load.size();
2100         for( int i=0; i<loads_total; ++i ) {
2101                 LoadRecentItem *recent = main_menu->load[i];
2102                 char name[BCTEXTLEN];
2103                 fs.extract_name(name, recent->path);
2104                 const char *cp = strrchr(name, '.');
2105                 if( !cp || strcasecmp(cp+1,"xml") ? use_xml : !use_xml ) continue;
2106                 LoadPrevious *load_prev = get_next_item();
2107                 load_prev->set_text(name);
2108                 load_prev->set_path(recent->path);
2109         }
2110 }
2111
2112 LoadRecentSubMenu::LoadRecentSubMenu(LoadRecent *load_recent)
2113  : BC_SubMenu()
2114 {
2115         this->load_recent = load_recent;
2116 }
2117
2118 LoadRecentSubMenu::~LoadRecentSubMenu()
2119 {
2120 }
2121