1
// Copyright (c) 2005, Rodrigo Braz Monteiro
2
// All rights reserved.
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
7
// * Redistributions of source code must retain the above copyright notice,
8
// this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright notice,
10
// this list of conditions and the following disclaimer in the documentation
11
// and/or other materials provided with the distribution.
12
// * Neither the name of the Aegisub Group nor the names of its contributors
13
// may be used to endorse or promote products derived from this software
14
// without specific prior written permission.
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
// POSSIBILITY OF SUCH DAMAGE.
28
// -----------------------------------------------------------------------------
32
// Website: http://aegisub.cellosoft.com
33
// Contact: mailto:zeratul@cellosoft.com
41
#include <wx/wxprec.h>
42
#include <wx/mimetype.h>
43
#include <wx/filename.h>
44
#include <wx/tglbtn.h>
45
#include <wx/rawbmp.h>
46
#include <wx/stdpaths.h>
47
#include <wx/sysopt.h>
48
#include "subs_grid.h"
49
#include "frame_main.h"
50
#include "video_display.h"
51
#include "video_slider.h"
52
#include "video_box.h"
54
#include "ass_dialogue.h"
55
#include "dialog_style_manager.h"
56
#include "dialog_translation.h"
57
#include "dialog_jumpto.h"
58
#include "dialog_shift_times.h"
59
#include "dialog_search_replace.h"
61
#include "subs_edit_box.h"
63
#include "dialog_properties.h"
64
#include "dialog_attachments.h"
66
#include "dialog_fonts_collector.h"
67
#include "dialog_about.h"
68
#include "dialog_export.h"
69
#include "audio_box.h"
70
#include "dialog_selection.h"
71
#include "dialog_styling_assistant.h"
72
#include "dialog_resample.h"
73
#include "dialog_kanji_timer.h"
74
#include "audio_display.h"
75
#include "toggle_bitmap.h"
76
#include "dialog_timing_processor.h"
77
#include "dialog_progress.h"
78
#include "dialog_options.h"
80
#ifdef WITH_AUTOMATION
81
#include "auto4_base.h"
83
#include "dialog_automation.h"
84
#include "dialog_version_check.h"
85
#include "dialog_dummy_video.h"
86
#include "dialog_spellchecker.h"
87
#include "dialog_associations.h"
88
#include "standard_paths.h"
89
#include "dialog_video_details.h"
94
#include "libosxutil/libosxutil.h"
100
BEGIN_EVENT_TABLE(FrameMain, wxFrame)
101
EVT_TIMER(AutoSave_Timer, FrameMain::OnAutoSave)
102
EVT_TIMER(StatusClear_Timer, FrameMain::OnStatusClear)
104
EVT_CLOSE(FrameMain::OnCloseWindow)
106
EVT_KEY_DOWN(FrameMain::OnKeyDown)
108
EVT_MENU_OPEN(FrameMain::OnMenuOpen)
109
EVT_MENU_RANGE(Menu_File_Recent,Menu_File_Recent+99, FrameMain::OnOpenRecentSubs)
110
EVT_MENU_RANGE(Menu_Video_Recent,Menu_Video_Recent+99, FrameMain::OnOpenRecentVideo)
111
EVT_MENU_RANGE(Menu_Audio_Recent,Menu_Audio_Recent+99, FrameMain::OnOpenRecentAudio)
112
EVT_MENU_RANGE(Menu_Timecodes_Recent,Menu_Timecodes_Recent+99, FrameMain::OnOpenRecentTimecodes)
113
EVT_MENU_RANGE(Menu_Keyframes_Recent,Menu_Keyframes_Recent+99, FrameMain::OnOpenRecentKeyframes)
114
EVT_MENU_RANGE(Menu_Automation_Macro,Menu_Automation_Macro+99, FrameMain::OnAutomationMacro)
116
EVT_MENU_RANGE(MENU_GRID_START+1,MENU_GRID_END-1,FrameMain::OnGridEvent)
117
EVT_MENU(Menu_File_New_Window, FrameMain::OnNewWindow)
118
EVT_MENU(Menu_File_Exit, FrameMain::OnExit)
119
EVT_MENU(Menu_File_Open_Video, FrameMain::OnOpenVideo)
120
EVT_MENU(Menu_File_Close_Video, FrameMain::OnCloseVideo)
121
EVT_MENU(Menu_File_Open_Subtitles, FrameMain::OnOpenSubtitles)
122
EVT_MENU(Menu_File_Open_Subtitles_Charset, FrameMain::OnOpenSubtitlesCharset)
123
EVT_MENU(Menu_File_New_Subtitles, FrameMain::OnNewSubtitles)
124
EVT_MENU(Menu_File_Save_Subtitles, FrameMain::OnSaveSubtitles)
125
EVT_MENU(Menu_File_Save_Subtitles_As, FrameMain::OnSaveSubtitlesAs)
126
EVT_MENU(Menu_File_Save_Subtitles_With_Charset, FrameMain::OnSaveSubtitlesCharset)
127
EVT_MENU(Menu_File_Export_Subtitles, FrameMain::OnExportSubtitles)
128
EVT_MENU(Menu_File_Open_VFR, FrameMain::OnOpenVFR)
129
EVT_MENU(Menu_File_Save_VFR, FrameMain::OnSaveVFR)
130
EVT_MENU(Menu_File_Close_VFR, FrameMain::OnCloseVFR)
131
EVT_MENU(Menu_Video_Load_Keyframes, FrameMain::OnOpenKeyframes)
132
EVT_MENU(Menu_Video_Save_Keyframes, FrameMain::OnSaveKeyframes)
133
EVT_MENU(Menu_Video_Close_Keyframes, FrameMain::OnCloseKeyframes)
135
EVT_MENU(Menu_View_Zoom_50, FrameMain::OnSetZoom50)
136
EVT_MENU(Menu_View_Zoom_100, FrameMain::OnSetZoom100)
137
EVT_MENU(Menu_View_Zoom_200, FrameMain::OnSetZoom200)
138
EVT_COMBOBOX(Toolbar_Zoom_Dropdown, FrameMain::OnSetZoom)
139
EVT_MENU(Video_Frame_Play, FrameMain::OnVideoPlay)
140
EVT_MENU(Menu_Video_Zoom_In, FrameMain::OnZoomIn)
141
EVT_MENU(Menu_Video_Zoom_Out, FrameMain::OnZoomOut)
142
EVT_MENU(Menu_Video_AR_Default, FrameMain::OnSetARDefault)
143
EVT_MENU(Menu_Video_AR_Full, FrameMain::OnSetARFull)
144
EVT_MENU(Menu_Video_AR_Wide, FrameMain::OnSetARWide)
145
EVT_MENU(Menu_Video_AR_235, FrameMain::OnSetAR235)
146
EVT_MENU(Menu_Video_AR_Custom, FrameMain::OnSetARCustom)
147
EVT_MENU(Menu_Video_JumpTo, FrameMain::OnJumpTo)
148
EVT_MENU(Menu_Video_Select_Visible, FrameMain::OnSelectVisible)
149
EVT_MENU(Menu_Video_Detach, FrameMain::OnDetachVideo)
150
EVT_MENU(Menu_Video_Dummy, FrameMain::OnDummyVideo)
151
EVT_MENU(Menu_Video_Overscan, FrameMain::OnOverscan)
152
EVT_MENU(Menu_Video_Details, FrameMain::OnOpenVideoDetails)
154
EVT_MENU(Menu_Audio_Open_File, FrameMain::OnOpenAudio)
155
EVT_MENU(Menu_Audio_Open_From_Video, FrameMain::OnOpenAudioFromVideo)
156
EVT_MENU(Menu_Audio_Close, FrameMain::OnCloseAudio)
158
EVT_MENU(Menu_Audio_Open_Dummy, FrameMain::OnOpenDummyAudio)
159
EVT_MENU(Menu_Audio_Open_Dummy_Noise, FrameMain::OnOpenDummyNoiseAudio)
162
EVT_MENU(Menu_Edit_Undo, FrameMain::OnUndo)
163
EVT_MENU(Menu_Edit_Redo, FrameMain::OnRedo)
164
EVT_MENU(Menu_Edit_Cut, FrameMain::OnCut)
165
EVT_MENU(Menu_Edit_Copy, FrameMain::OnCopy)
166
EVT_MENU(Menu_Edit_Paste, FrameMain::OnPaste)
167
EVT_MENU(Menu_Edit_Paste_Over, FrameMain::OnPasteOver)
168
EVT_MENU(Menu_Edit_Find, FrameMain::OnFind)
169
EVT_MENU(Menu_Edit_Find_Next, FrameMain::OnFindNext)
170
EVT_MENU(Menu_Edit_Replace, FrameMain::OnReplace)
171
EVT_MENU(Menu_Edit_Shift, FrameMain::OnShift)
172
EVT_MENU(Menu_Edit_Select, FrameMain::OnSelect)
173
EVT_MENU(Menu_Edit_Sort, FrameMain::OnSort)
175
EVT_MENU(Menu_Tools_Properties, FrameMain::OnOpenProperties)
176
EVT_MENU(Menu_Tools_Styles_Manager, FrameMain::OnOpenStylesManager)
177
EVT_MENU(Menu_Tools_Attachments, FrameMain::OnOpenAttachments)
178
EVT_MENU(Menu_Tools_Translation, FrameMain::OnOpenTranslation)
179
EVT_MENU(Menu_Tools_SpellCheck, FrameMain::OnOpenSpellCheck)
180
EVT_MENU(Menu_Tools_Fonts_Collector, FrameMain::OnOpenFontsCollector)
181
EVT_MENU(Menu_Tools_Automation, FrameMain::OnOpenAutomation)
182
EVT_MENU(Menu_Tools_Styling, FrameMain::OnOpenStylingAssistant)
183
EVT_MENU(Menu_Tools_Resample, FrameMain::OnOpenResample)
184
EVT_MENU(Menu_Tools_Timing_Processor, FrameMain::OnOpenTimingProcessor)
185
EVT_MENU(Menu_Tools_Kanji_Timer, FrameMain::OnOpenKanjiTimer)
186
EVT_MENU(Menu_Tools_Options, FrameMain::OnOpenOptions)
187
EVT_MENU(Menu_Tools_Log, FrameMain::OnOpenLog)
188
EVT_MENU(Menu_Tools_ASSDraw, FrameMain::OnOpenASSDraw)
190
EVT_MENU(Menu_Subs_Snap_Start_To_Video, FrameMain::OnSnapSubsStartToVid)
191
EVT_MENU(Menu_Subs_Snap_End_To_Video, FrameMain::OnSnapSubsEndToVid)
192
EVT_MENU(Menu_Subs_Snap_Video_To_Start, FrameMain::OnSnapVidToSubsStart)
193
EVT_MENU(Menu_Subs_Snap_Video_To_End, FrameMain::OnSnapVidToSubsEnd)
194
EVT_MENU(Menu_Video_Snap_To_Scene, FrameMain::OnSnapToScene)
195
EVT_MENU(Menu_Video_Shift_To_Frame, FrameMain::OnShiftToFrame)
197
EVT_MENU(Menu_Help_Contents, FrameMain::OnContents)
198
EVT_MENU(Menu_Help_Files, FrameMain::OnFiles)
199
EVT_MENU(Menu_Help_Website, FrameMain::OnWebsite)
200
EVT_MENU(Menu_Help_Forums, FrameMain::OnForums)
201
EVT_MENU(Menu_Help_BugTracker, FrameMain::OnBugTracker)
202
EVT_MENU(Menu_Help_IRCChannel, FrameMain::OnIRCChannel)
203
EVT_MENU(Menu_Help_Check_Updates, FrameMain::OnCheckUpdates)
204
EVT_MENU(Menu_Help_About, FrameMain::OnAbout)
206
EVT_MENU(Menu_View_Language, FrameMain::OnChooseLanguage)
207
EVT_MENU(Menu_View_Associations, FrameMain::OnPickAssociations)
208
EVT_MENU(Menu_View_Standard, FrameMain::OnViewStandard)
209
EVT_MENU(Menu_View_Audio, FrameMain::OnViewAudio)
210
EVT_MENU(Menu_View_Video, FrameMain::OnViewVideo)
211
EVT_MENU(Menu_View_Subs, FrameMain::OnViewSubs)
213
EVT_MENU(Video_Prev_Frame,FrameMain::OnPrevFrame)
214
EVT_MENU(Video_Next_Frame,FrameMain::OnNextFrame)
215
EVT_MENU(Video_Focus_Seek,FrameMain::OnFocusSeek)
216
EVT_MENU(Grid_Next_Line,FrameMain::OnNextLine)
217
EVT_MENU(Grid_Prev_Line,FrameMain::OnPrevLine)
218
EVT_MENU(Grid_Toggle_Tags,FrameMain::OnToggleTags)
219
EVT_MENU(Edit_Box_Commit,FrameMain::OnEditBoxCommit)
221
EVT_MENU(Medusa_Play, FrameMain::OnMedusaPlay)
222
EVT_MENU(Medusa_Stop, FrameMain::OnMedusaStop)
223
EVT_MENU(Medusa_Play_After, FrameMain::OnMedusaPlayAfter)
224
EVT_MENU(Medusa_Play_Before, FrameMain::OnMedusaPlayBefore)
225
EVT_MENU(Medusa_Next, FrameMain::OnMedusaNext)
226
EVT_MENU(Medusa_Prev, FrameMain::OnMedusaPrev)
227
EVT_MENU(Medusa_Shift_Start_Forward, FrameMain::OnMedusaShiftStartForward)
228
EVT_MENU(Medusa_Shift_Start_Back, FrameMain::OnMedusaShiftStartBack)
229
EVT_MENU(Medusa_Shift_End_Forward, FrameMain::OnMedusaShiftEndForward)
230
EVT_MENU(Medusa_Shift_End_Back, FrameMain::OnMedusaShiftEndBack)
231
EVT_MENU(Medusa_Enter, FrameMain::OnMedusaEnter)
234
EVT_MENU(wxID_ABOUT, FrameMain::OnAbout)
235
EVT_MENU(wxID_EXIT, FrameMain::OnExit)
240
////////////////////////////////
241
// Redirect grid events to grid
242
void FrameMain::OnGridEvent (wxCommandEvent &event) {
243
#if wxCHECK_VERSION(2,9,0)
244
SubsBox->GetEventHandler()->ProcessEvent(event);
246
SubsBox->AddPendingEvent(event);
251
///////////////////////
252
// Rebuild recent list
253
void FrameMain::RebuildRecentList(wxString listName,wxMenu *menu,int startID) {
254
// Wipe previous list
255
int count = (int)menu->GetMenuItemCount();
256
for (int i=count;--i>=0;) {
257
menu->Destroy(menu->FindItemByPosition(i));
263
wxArrayString entries = Options.GetRecentList(listName);
264
for (size_t i=0;i<entries.Count();i++) {
265
n = wxString::Format(_T("%i"),(int)i+1);
266
if (i < 9) n = _T("&") + n;
267
wxFileName shortname(entries[i]);
268
wxString filename = shortname.GetFullName();
269
menu->Append(startID+i,n + _T(" ") + filename);
273
// Nothing added, add an empty placeholder
274
if (added == 0) menu->Append(startID,_("Empty"))->Enable(false);
278
////////////////////////
279
// Menu is being opened
280
void FrameMain::OnMenuOpen (wxMenuEvent &event) {
283
wxMenu *curMenu = event.GetMenu();
286
if (curMenu == fileMenu) {
288
RebuildRecentList(_T("Recent sub"),RecentSubs,Menu_File_Recent);
292
else if (curMenu == viewMenu) {
294
bool aud = audioBox->audioDisplay->loaded;
295
bool vid = VideoContext::Get()->IsLoaded();
298
MenuBar->Enable(Menu_View_Audio,aud);
299
MenuBar->Enable(Menu_View_Video,vid);
300
MenuBar->Enable(Menu_View_Standard,aud && vid);
303
if (!showVideo && !showAudio) MenuBar->Check(Menu_View_Subs,true);
304
else if (showVideo && !showAudio) MenuBar->Check(Menu_View_Video,true);
305
else if (showAudio && showVideo) MenuBar->Check(Menu_View_Standard,true);
306
else MenuBar->Check(Menu_View_Audio,true);
310
else if (curMenu == videoMenu) {
311
bool state = VideoContext::Get()->IsLoaded();
314
MenuBar->Enable(Menu_Video_JumpTo,state);
315
MenuBar->Enable(Menu_Subs_Snap_Video_To_Start,state);
316
MenuBar->Enable(Menu_Subs_Snap_Video_To_End,state);
317
MenuBar->Enable(Menu_View_Zoom,state);
318
MenuBar->Enable(Menu_View_Zoom_50,state);
319
MenuBar->Enable(Menu_View_Zoom_100,state);
320
MenuBar->Enable(Menu_View_Zoom_200,state);
321
MenuBar->Enable(Menu_File_Close_Video,state);
322
MenuBar->Enable(Menu_Video_AR,state);
323
MenuBar->Enable(Menu_Video_AR_Default,state);
324
MenuBar->Enable(Menu_Video_AR_Full,state);
325
MenuBar->Enable(Menu_Video_AR_Wide,state);
326
MenuBar->Enable(Menu_Video_AR_235,state);
327
MenuBar->Enable(Menu_Video_AR_Custom,state);
328
MenuBar->Enable(Menu_Video_Detach,state && !detachedVideo);
329
MenuBar->Enable(Menu_File_Save_VFR,VFR_Output.GetFrameRateType() == VFR);
330
MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.GetFrameRateType() == VFR);
331
MenuBar->Enable(Menu_Video_Close_Keyframes,VideoContext::Get()->OverKeyFramesLoaded());
332
MenuBar->Enable(Menu_Video_Save_Keyframes,VideoContext::Get()->KeyFramesLoaded());
333
MenuBar->Enable(Menu_Video_Details,state);
334
MenuBar->Enable(Menu_Video_Overscan,state);
337
int arType = VideoContext::Get()->GetAspectRatioType();
338
MenuBar->Check(Menu_Video_AR_Default,false);
339
MenuBar->Check(Menu_Video_AR_Full,false);
340
MenuBar->Check(Menu_Video_AR_Wide,false);
341
MenuBar->Check(Menu_Video_AR_235,false);
342
MenuBar->Check(Menu_Video_AR_Custom,false);
344
case 0: MenuBar->Check(Menu_Video_AR_Default,true); break;
345
case 1: MenuBar->Check(Menu_Video_AR_Full,true); break;
346
case 2: MenuBar->Check(Menu_Video_AR_Wide,true); break;
347
case 3: MenuBar->Check(Menu_Video_AR_235,true); break;
348
case 4: MenuBar->Check(Menu_Video_AR_Custom,true); break;
352
MenuBar->Check(Menu_Video_Overscan,Options.AsBool(_T("Show Overscan Mask")));
354
// Rebuild recent lists
355
RebuildRecentList(_T("Recent vid"),RecentVids,Menu_Video_Recent);
356
RebuildRecentList(_T("Recent timecodes"),RecentTimecodes,Menu_Timecodes_Recent);
357
RebuildRecentList(_T("Recent Keyframes"),RecentKeyframes,Menu_Keyframes_Recent);
361
else if (curMenu == audioMenu) {
362
bool state = audioBox->loaded;
363
bool vidstate = VideoContext::Get()->IsLoaded();
365
MenuBar->Enable(Menu_Audio_Open_From_Video,vidstate);
366
MenuBar->Enable(Menu_Audio_Close,state);
369
RebuildRecentList(_T("Recent aud"),RecentAuds,Menu_Audio_Recent);
373
else if (curMenu == subtitlesMenu) {
376
wxArrayInt sels = SubsBox->GetSelection(&continuous);
377
int count = sels.Count();
382
MenuBar->Enable(MENU_INSERT_BEFORE,state);
383
MenuBar->Enable(MENU_INSERT_AFTER,state);
384
MenuBar->Enable(MENU_SPLIT_BY_KARAOKE,state);
385
MenuBar->Enable(MENU_DELETE,state);
386
state2 = count > 0 && VideoContext::Get()->IsLoaded();
387
MenuBar->Enable(MENU_INSERT_BEFORE_VIDEO,state2);
388
MenuBar->Enable(MENU_INSERT_AFTER_VIDEO,state2);
389
MenuBar->Enable(Menu_Subtitles_Insert,state);
390
state = count > 0 && continuous;
391
MenuBar->Enable(MENU_DUPLICATE,state);
392
state = count > 0 && continuous && VFR_Output.IsLoaded();
393
MenuBar->Enable(MENU_DUPLICATE_NEXT_FRAME,state);
395
MenuBar->Enable(MENU_SWAP,state);
396
state = count >= 2 && continuous;
397
MenuBar->Enable(MENU_JOIN_CONCAT,state);
398
MenuBar->Enable(MENU_JOIN_REPLACE,state);
399
MenuBar->Enable(MENU_JOIN_AS_KARAOKE,state);
400
MenuBar->Enable(Menu_Subtitles_Join,state);
401
state = (count == 2 || count == 3) && continuous;
402
MenuBar->Enable(MENU_RECOMBINE,state);
406
else if (curMenu == timingMenu) {
409
wxArrayInt sels = SubsBox->GetSelection(&continuous);
410
int count = sels.Count();
413
bool state = VideoContext::Get()->IsLoaded();
414
MenuBar->Enable(Menu_Subs_Snap_Start_To_Video,state);
415
MenuBar->Enable(Menu_Subs_Snap_End_To_Video,state);
416
MenuBar->Enable(Menu_Video_Snap_To_Scene,state);
417
MenuBar->Enable(Menu_Video_Shift_To_Frame,state);
420
state = count >= 2 && continuous;
421
MenuBar->Enable(MENU_ADJOIN,state);
422
MenuBar->Enable(MENU_ADJOIN2,state);
426
else if (curMenu == editMenu) {
429
wxString undo_text = _("&Undo") + wxString(_T(" ")) + AssFile::GetUndoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Undo"));
430
item = editMenu->FindItem(Menu_Edit_Undo);
431
item->SetItemLabel(undo_text);
432
item->Enable(!AssFile::IsUndoStackEmpty());
435
wxString redo_text = _("&Redo") + wxString(_T(" ")) + AssFile::GetRedoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Redo"));
436
item = editMenu->FindItem(Menu_Edit_Redo);
437
item->SetItemLabel(redo_text);
438
item->Enable(!AssFile::IsRedoStackEmpty());
441
wxArrayInt sels = SubsBox->GetSelection();
442
bool can_copy = (sels.Count() > 0);
444
bool can_paste = true;
445
if (wxTheClipboard->Open()) {
446
can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
447
wxTheClipboard->Close();
450
MenuBar->Enable(Menu_Edit_Cut,can_copy);
451
MenuBar->Enable(Menu_Edit_Copy,can_copy);
452
MenuBar->Enable(Menu_Edit_Paste,can_paste);
453
MenuBar->Enable(Menu_Edit_Paste_Over,can_copy&&can_paste);
457
#ifdef WITH_AUTOMATION
458
else if (curMenu == automationMenu) {
459
// Remove old macro items
460
for (unsigned int i = 0; i < activeMacroItems.size(); i++) {
462
wxMenuItem *it = MenuBar->FindItem(Menu_Automation_Macro + i, &p);
466
activeMacroItems.clear();
470
added += AddMacroMenuItems(automationMenu, wxGetApp().global_scripts->GetMacros());
471
added += AddMacroMenuItems(automationMenu, local_scripts->GetMacros());
473
// If none were added, show a ghosted notice
475
automationMenu->Append(Menu_Automation_Macro, _("No Automation macros loaded"))->Enable(false);
476
activeMacroItems.push_back(0);
482
else if (curMenu == helpMenu) {
483
bool isCheckingUpdates = VersionCheckLock.TryLock() != wxMUTEX_NO_ERROR;
484
if (!isCheckingUpdates) VersionCheckLock.Unlock();
485
MenuBar->Enable(Menu_Help_Check_Updates, !isCheckingUpdates);
492
//////////////////////////////
493
// Macro menu creation helper
494
int FrameMain::AddMacroMenuItems(wxMenu *menu, const std::vector<Automation4::FeatureMacro*> ¯os) {
495
#ifdef WITH_AUTOMATION
496
if (macros.empty()) {
500
int id = activeMacroItems.size();;
501
for (std::vector<Automation4::FeatureMacro*>::const_iterator i = macros.begin(); i != macros.end(); ++i) {
502
wxMenuItem * m = menu->Append(Menu_Automation_Macro + id, (*i)->GetName(), (*i)->GetDescription());
503
m->Enable((*i)->Validate(SubsBox->ass, SubsBox->GetAbsoluteSelection(), SubsBox->GetFirstSelRow()));
504
activeMacroItems.push_back(*i);
508
return macros.size();
515
///////////////////////////////
516
// Open recent subs menu entry
517
void FrameMain::OnOpenRecentSubs(wxCommandEvent &event) {
518
int number = event.GetId()-Menu_File_Recent;
519
wxString key = _T("Recent sub #") + wxString::Format(_T("%i"),number+1);
520
LoadSubtitles(Options.AsText(key));
524
////////////////////////////////
525
// Open recent video menu entry
526
void FrameMain::OnOpenRecentVideo(wxCommandEvent &event) {
527
int number = event.GetId()-Menu_Video_Recent;
528
wxString key = _T("Recent vid #") + wxString::Format(_T("%i"),number+1);
529
LoadVideo(Options.AsText(key));
533
////////////////////////////////
534
// Open recent timecodes entry
535
void FrameMain::OnOpenRecentTimecodes(wxCommandEvent &event) {
536
int number = event.GetId()-Menu_Timecodes_Recent;
537
wxString key = _T("Recent timecodes #") + wxString::Format(_T("%i"),number+1);
538
LoadVFR(Options.AsText(key));
542
////////////////////////////////
543
// Open recent Keyframes entry
544
void FrameMain::OnOpenRecentKeyframes(wxCommandEvent &event) {
545
int number = event.GetId()-Menu_Keyframes_Recent;
546
wxString key = _T("Recent Keyframes #") + wxString::Format(_T("%i"),number+1);
547
KeyFrameFile::Load(Options.AsText(key));
548
videoBox->videoSlider->Refresh();
549
audioBox->audioDisplay->Update();
554
////////////////////////////////
555
// Open recent audio menu entry
556
void FrameMain::OnOpenRecentAudio(wxCommandEvent &event) {
557
int number = event.GetId()-Menu_Audio_Recent;
558
wxString key = _T("Recent aud #") + wxString::Format(_T("%i"),number+1);
559
LoadAudio(Options.AsText(key));
565
void FrameMain::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
567
//wxStandardPaths stand;
568
//wxExecute(stand.GetExecutablePath());
574
void FrameMain::OnExit(wxCommandEvent& WXUNUSED(event)) {
581
void FrameMain::OnAbout(wxCommandEvent &event) {
582
AboutScreen About(this);
587
//////////////////////
588
// Open check updates
589
void FrameMain::OnCheckUpdates(wxCommandEvent &event) {
590
PerformVersionCheck(true);
596
void FrameMain::OnContents(wxCommandEvent& WXUNUSED(event)) {
600
/// @brief Open help files on OSX.
603
void FrameMain::OnFiles(wxCommandEvent& WXUNUSED(event)) {
605
char *shared_path = OSX_GetBundleSharedSupportDirectory();
606
wxString help_path = wxString::Format(_T("%s/doc"), wxString(shared_path, wxConvUTF8).c_str());
607
OSX_OpenLocation(help_path.c_str());
613
/// @brief Open website
616
void FrameMain::OnWebsite(wxCommandEvent& WXUNUSED(event)) {
617
AegisubApp::OpenURL(_T("http://www.aegisub.org/"));
623
void FrameMain::OnForums(wxCommandEvent& WXUNUSED(event)) {
624
AegisubApp::OpenURL(_T("http://forum.aegisub.org/"));
630
void FrameMain::OnBugTracker(wxCommandEvent& WXUNUSED(event)) {
631
if (wxGetMouseState().CmdDown()) {
632
if (wxGetMouseState().ShiftDown()) {
633
wxMessageBox(_T("Now crashing with an access violation..."));
634
for (char *foo = (char*)0;;) *foo++ = 42;
637
wxMessageBox(_T("Now crashing with an unhandled exception..."));
642
AegisubApp::OpenURL(_T("http://devel.aegisub.org/"));
648
void FrameMain::OnIRCChannel(wxCommandEvent& WXUNUSED(event)) {
649
AegisubApp::OpenURL(_T("irc://irc.rizon.net/aegisub"));
655
void FrameMain::OnVideoPlay(wxCommandEvent &event) {
656
VideoContext::Get()->Play();
663
void FrameMain::OnOpenVideo(wxCommandEvent& WXUNUSED(event)) {
664
wxString path = Options.AsText(_T("Last open video path"));
665
wxString str = wxString(_("Video Formats")) + _T(" (*.avi,*.mkv,*.mp4,*.avs,*.d2v,*.ogm,*.mpeg,*.mpg,*.vob)|*.avi;*.avs;*.d2v;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg;*.vob|")
666
+ _("All Files") + _T(" (*.*)|*.*");
667
wxString filename = wxFileSelector(_("Open video file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
668
if (!filename.empty()) {
670
wxFileName filepath(filename);
671
Options.SetText(_T("Last open video path"), filepath.GetPath());
679
void FrameMain::OnCloseVideo(wxCommandEvent& WXUNUSED(event)) {
686
void FrameMain::OnOpenAudio (wxCommandEvent& WXUNUSED(event)) {
687
wxString path = Options.AsText(_T("Last open audio path"));
688
wxString str = wxString(_("Audio Formats")) + _T(" (*.wav,*.mp3,*.ogg,*.flac,*.mp4,*.ac3,*.aac,*.mka,*.m4a,*.w64)|*.wav;*.mp3;*.ogg;*.flac;*.mp4;*.ac3;*.aac;*.mka;*.m4a;*.w64|")
689
+ _("Video Formats") + _T(" (*.avi,*.mkv,*.ogm,*.mpg,*.mpeg)|*.avi;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg|")
690
+ _("All files") + _T(" (*.*)|*.*");
691
wxString filename = wxFileSelector(_("Open audio file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
692
if (!filename.empty()) {
694
wxFileName filepath(filename);
695
Options.SetText(_T("Last open audio path"), filepath.GetPath());
701
void FrameMain::OnOpenAudioFromVideo (wxCommandEvent& WXUNUSED(event)) {
702
LoadAudio(_T(""),true);
706
void FrameMain::OnCloseAudio (wxCommandEvent& WXUNUSED(event)) {
711
void FrameMain::OnOpenDummyAudio (wxCommandEvent& WXUNUSED(event)) {
712
LoadAudio(_T("?dummy"));
714
void FrameMain::OnOpenDummyNoiseAudio (wxCommandEvent& WXUNUSED(event)) {
715
LoadAudio(_T("?noise"));
722
void FrameMain::OnOpenSubtitles(wxCommandEvent& WXUNUSED(event)) {
723
wxString path = Options.AsText(_T("Last open subtitles path"));
724
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
725
if (!filename.empty()) {
726
LoadSubtitles(filename);
727
wxFileName filepath(filename);
728
Options.SetText(_T("Last open subtitles path"), filepath.GetPath());
734
////////////////////////////////////////
735
// Open subtitles with specific charset
736
void FrameMain::OnOpenSubtitlesCharset(wxCommandEvent& WXUNUSED(event)) {
737
// Initialize charsets
738
wxArrayString choices = GetEncodings();
739
wxString path = Options.AsText(_T("Last open subtitles path"));
741
// Get options and load
742
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
743
if (!filename.empty()) {
744
wxString charset = wxGetSingleChoice(_("Choose charset code:"), _("Charset"),choices,this,-1, -1,true,250,200);
745
if (!charset.empty()) {
746
LoadSubtitles(filename,charset);
748
wxFileName filepath(filename);
749
Options.SetText(_T("Last open subtitles path"), filepath.GetPath());
755
/////////////////////
757
void FrameMain::OnSaveSubtitlesAs(wxCommandEvent& WXUNUSED(event)) {
764
void FrameMain::OnSaveSubtitles(wxCommandEvent& WXUNUSED(event)) {
765
SaveSubtitles(false);
769
////////////////////////////////////////
770
// Save subtitles with specific charset
771
void FrameMain::OnSaveSubtitlesCharset(wxCommandEvent& WXUNUSED(event)) {
772
SaveSubtitles(true,true);
778
void FrameMain::OnNewSubtitles(wxCommandEvent& WXUNUSED(event)) {
779
LoadSubtitles(_T(""));
785
void FrameMain::OnExportSubtitles(wxCommandEvent & WXUNUSED(event)) {
786
#ifdef WITH_AUTOMATION
787
int autoreload = Options.AsInt(_T("Automation Autoreload Mode"));
788
if (autoreload & 1) {
790
const std::vector<Automation4::Script*> scripts = local_scripts->GetScripts();
791
for (size_t i = 0; i < scripts.size(); ++i) {
793
scripts[i]->Reload();
795
catch (const wchar_t *e) {
796
wxLogError(_T("Error while reloading Automation scripts before export: %s"), e);
799
wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
803
if (autoreload & 2) {
805
wxGetApp().global_scripts->Reload();
809
DialogExport exporter(this);
810
exporter.ShowModal();
816
void FrameMain::OnOpenVFR(wxCommandEvent &event) {
817
wxString path = Options.AsText(_T("Last open timecodes path"));
818
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|")
819
+ _("All Files") + _T(" (*.*)|*.*");
820
wxString filename = wxFileSelector(_("Open timecodes file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
821
if (!filename.empty()) {
823
wxFileName filepath(filename);
824
Options.SetText(_T("Last open timecodes path"), filepath.GetPath());
832
void FrameMain::OnSaveVFR(wxCommandEvent &event) {
833
wxString path = Options.AsText(_T("Last open timecodes path"));
834
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|")
835
+ _("All Files") + _T(" (*.*)|*.*");
836
wxString filename = wxFileSelector(_("Save timecodes file"),path,_T(""),_T(""),str,wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
837
if (!filename.empty()) {
839
wxFileName filepath(filename);
840
Options.SetText(_T("Last open timecodes path"), filepath.GetPath());
849
void FrameMain::OnCloseVFR(wxCommandEvent &event) {
856
void FrameMain::OnOpenKeyframes (wxCommandEvent &event) {
858
wxString path = Options.AsText(_T("Last open keyframes path"));
859
wxString filename = wxFileSelector(_T("Select the keyframes file to open"),path,_T(""),_T(".txt"),_T("All supported formats (*.txt, *.pass, *.stats, *.log)|*.txt;*.pass;*.stats;*.log|All files (*.*)|*.*"),wxFD_FILE_MUST_EXIST | wxFD_OPEN);
860
if (filename.IsEmpty()) return;
861
wxFileName filepath(filename);
862
Options.SetText(_T("Last open keyframes path"),filepath.GetPath());
866
KeyFrameFile::Load(filename);
867
videoBox->videoSlider->Refresh();
868
audioBox->audioDisplay->Update();
875
void FrameMain::OnCloseKeyframes (wxCommandEvent &event) {
876
VideoContext::Get()->CloseOverKeyFrames();
877
videoBox->videoSlider->Refresh();
878
audioBox->audioDisplay->Update();
885
void FrameMain::OnSaveKeyframes (wxCommandEvent &event) {
887
wxString path = Options.AsText(_T("Last open keyframes path"));
888
wxString filename = wxFileSelector(_T("Select the Keyframes file to open"),path,_T(""),_T("*.key.txt"),_T("Text files (*.txt)|*.txt"),wxFD_OVERWRITE_PROMPT | wxFD_SAVE);
889
if (filename.IsEmpty()) return;
890
wxFileName filepath(filename);
891
Options.SetText(_T("Last open keyframes path"),filepath.GetPath());
895
KeyFrameFile::Save(filename);
901
void FrameMain::OnSetZoom50(wxCommandEvent& WXUNUSED(event)) {
902
VideoContext::Get()->Stop();
903
videoBox->videoDisplay->zoomBox->SetSelection(3);
904
videoBox->videoDisplay->SetZoomPos(3);
907
void FrameMain::OnSetZoom100(wxCommandEvent& WXUNUSED(event)) {
908
VideoContext::Get()->Stop();
909
videoBox->videoDisplay->zoomBox->SetSelection(7);
910
videoBox->videoDisplay->SetZoomPos(7);
913
void FrameMain::OnSetZoom200(wxCommandEvent& WXUNUSED(event)) {
914
VideoContext::Get()->Stop();
915
videoBox->videoDisplay->zoomBox->SetSelection(15);
916
videoBox->videoDisplay->SetZoomPos(15);
919
void FrameMain::OnZoomIn (wxCommandEvent &event) {
920
VideoContext::Get()->Stop();
921
videoBox->videoDisplay->zoomBox->SetSelection(videoBox->videoDisplay->zoomBox->GetSelection()+1);
922
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
925
void FrameMain::OnZoomOut (wxCommandEvent &event) {
926
VideoContext::Get()->Stop();
927
int selTo = videoBox->videoDisplay->zoomBox->GetSelection()-1;
928
if (selTo < 0) selTo = 0;
929
videoBox->videoDisplay->zoomBox->SetSelection(selTo);
930
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
933
void FrameMain::OnSetZoom(wxCommandEvent &event) {
934
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
940
void FrameMain::OnDetachVideo(wxCommandEvent &event) {
947
void FrameMain::OnDummyVideo (wxCommandEvent &event) {
949
if (DialogDummyVideo::CreateDummyVideo(this, fn)) {
957
void FrameMain::OnOverscan (wxCommandEvent &event) {
958
Options.SetBool(_T("Show overscan mask"),event.IsChecked());
960
VideoContext::Get()->Stop();
961
videoBox->videoDisplay->Render();
965
//////////////////////
966
// Show video details
967
void FrameMain::OnOpenVideoDetails (wxCommandEvent &event) {
968
VideoContext::Get()->Stop();
969
DialogVideoDetails videodetails(this);
970
videodetails.ShowModal();
974
///////////////////////
975
// Open jump to dialog
976
void FrameMain::OnJumpTo(wxCommandEvent& WXUNUSED(event)) {
977
VideoContext::Get()->Stop();
978
if (VideoContext::Get()->IsLoaded()) {
979
DialogJumpTo JumpTo(this);
981
videoBox->videoSlider->SetFocus();
986
/////////////////////
988
void FrameMain::OnShift(wxCommandEvent& WXUNUSED(event)) {
989
VideoContext::Get()->Stop();
990
DialogShiftTimes Shift(this,SubsBox);
997
void FrameMain::OnOpenProperties (wxCommandEvent &event) {
998
VideoContext::Get()->Stop();
999
DialogProperties Properties(this);
1000
int res = Properties.ShowModal();
1002
SubsBox->CommitChanges();
1007
///////////////////////
1008
// Open styles manager
1009
void FrameMain::OnOpenStylesManager(wxCommandEvent& WXUNUSED(event)) {
1010
VideoContext::Get()->Stop();
1011
DialogStyleManager StyleManager(this,SubsBox);
1012
StyleManager.ShowModal();
1013
EditBox->UpdateGlobals();
1014
SubsBox->CommitChanges();
1018
////////////////////
1020
void FrameMain::OnOpenAttachments(wxCommandEvent& WXUNUSED(event)) {
1021
VideoContext::Get()->Stop();
1022
DialogAttachments attachments(this);
1023
attachments.ShowModal();
1027
//////////////////////////////
1028
// Open translation assistant
1029
void FrameMain::OnOpenTranslation(wxCommandEvent& WXUNUSED(event)) {
1030
VideoContext::Get()->Stop();
1031
int start = SubsBox->GetFirstSelRow();
1032
if (start == -1) start = 0;
1033
DialogTranslation Trans(this,AssFile::top,SubsBox,start,true);
1038
//////////////////////
1039
// Open Spell Checker
1040
void FrameMain::OnOpenSpellCheck (wxCommandEvent &event) {
1041
VideoContext::Get()->Stop();
1042
new DialogSpellChecker(this);
1043
//DialogSpellChecker *spell =
1044
//spell->ShowModal();
1048
////////////////////////
1049
// Open Fonts Collector
1050
void FrameMain::OnOpenFontsCollector (wxCommandEvent &event) {
1051
VideoContext::Get()->Stop();
1052
DialogFontsCollector Collector(this);
1053
Collector.ShowModal();
1057
/////////////////////////////
1058
// Open Resolution Resampler
1059
void FrameMain::OnOpenResample (wxCommandEvent &event) {
1060
VideoContext::Get()->Stop();
1061
DialogResample diag(this, SubsBox);
1066
/////////////////////////////////////
1067
// Open Timing post-processor dialog
1068
void FrameMain::OnOpenTimingProcessor (wxCommandEvent &event) {
1069
DialogTimingProcessor timing(this,SubsBox);
1072
/////////////////////////////////////
1073
// Open Kanji Timer dialog
1074
void FrameMain::OnOpenKanjiTimer (wxCommandEvent &event) {
1075
DialogKanjiTimer kanjitimer(this,SubsBox);
1076
kanjitimer.ShowModal();
1080
///////////////////////
1081
// Open Options dialog
1082
void FrameMain::OnOpenOptions (wxCommandEvent &event) {
1084
DialogOptions options(this);
1085
options.ShowModal();
1087
catch (const wxChar *e) {
1095
void FrameMain::OnOpenLog (wxCommandEvent &event) {
1096
LogWindow->Show(true);
1102
void FrameMain::OnOpenASSDraw (wxCommandEvent &event) {
1103
wxExecute(_T("\"") + StandardPaths::DecodePath(_T("?data/ASSDraw3.exe")) + _T("\""));
1109
void FrameMain::OnOpenAutomation (wxCommandEvent &event) {
1110
#ifdef WITH_AUTOMATION
1112
if (wxGetMouseState().CmdDown()) {
1114
if (wxGetMouseState().ControlDown()) {
1116
wxGetApp().global_scripts->Reload();
1117
if (wxGetMouseState().ShiftDown()) {
1118
const std::vector<Automation4::Script*> scripts = local_scripts->GetScripts();
1119
for (size_t i = 0; i < scripts.size(); ++i) {
1121
scripts[i]->Reload();
1123
catch (const wchar_t *e) {
1127
wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
1131
StatusTimeout(_("Reloaded all Automation scripts"));
1134
StatusTimeout(_("Reloaded autoload Automation scripts"));
1138
VideoContext::Get()->Stop();
1139
DialogAutomation dlg(this, local_scripts);
1146
///////////////////////////////////////////////////////////
1147
// General handler for all Automation-generated menu items
1148
void FrameMain::OnAutomationMacro (wxCommandEvent &event) {
1149
#ifdef WITH_AUTOMATION
1150
SubsBox->BeginBatch();
1151
// First get selection data
1152
// This much be done before clearing the maps, since selection data are lost during that
1153
std::vector<int> selected_lines = SubsBox->GetAbsoluteSelection();
1154
int first_sel = SubsBox->GetFirstSelRow();
1155
// Clear all maps from the subs grid before running the macro
1156
// The stuff done by the macro might invalidate some of the iterators held by the grid, which will cause great crashing
1159
activeMacroItems[event.GetId()-Menu_Automation_Macro]->Process(SubsBox->ass, selected_lines, first_sel, this);
1160
// Have the grid update its maps, this properly refreshes it to reflect the changed subs
1161
SubsBox->UpdateMaps();
1162
SubsBox->SetSelectionFromAbsolute(selected_lines);
1163
SubsBox->CommitChanges(true, false);
1164
SubsBox->AdjustScrollbar();
1165
SubsBox->EndBatch();
1170
//////////////////////
1171
// Snap subs to video
1172
void FrameMain::OnSnapSubsStartToVid (wxCommandEvent &event) {
1173
if (VideoContext::Get()->IsLoaded()) {
1174
wxArrayInt sel = SubsBox->GetSelection();
1175
if (sel.Count() > 0) {
1176
wxCommandEvent dummy;
1177
SubsBox->SetSubsToVideo(true);
1182
void FrameMain::OnSnapSubsEndToVid (wxCommandEvent &event) {
1183
if (VideoContext::Get()->IsLoaded()) {
1184
wxArrayInt sel = SubsBox->GetSelection();
1185
if (sel.Count() > 0) {
1186
wxCommandEvent dummy;
1187
SubsBox->SetSubsToVideo(false);
1193
//////////////////////
1194
// Jump video to subs
1195
void FrameMain::OnSnapVidToSubsStart (wxCommandEvent &event) {
1196
if (VideoContext::Get()->IsLoaded()) {
1197
wxArrayInt sel = SubsBox->GetSelection();
1198
if (sel.Count() > 0) {
1199
wxCommandEvent dummy;
1200
SubsBox->SetVideoToSubs(true);
1205
void FrameMain::OnSnapVidToSubsEnd (wxCommandEvent &event) {
1206
if (VideoContext::Get()->IsLoaded()) {
1207
wxArrayInt sel = SubsBox->GetSelection();
1208
if (sel.Count() > 0) {
1209
wxCommandEvent dummy;
1210
SubsBox->SetVideoToSubs(false);
1218
void FrameMain::OnSnapToScene (wxCommandEvent &event) {
1219
if (VideoContext::Get()->IsLoaded()) {
1221
wxArrayInt sel = SubsBox->GetSelection();
1222
int curFrame = VideoContext::Get()->GetFrameN();
1226
wxArrayInt keyframes = VideoContext::Get()->GetKeyFrames();
1227
size_t n = keyframes.Count();
1229
for (size_t i=0;i<n;i++) {
1230
frame = keyframes[i];
1232
if (frame == curFrame) {
1234
if (i < n-1) next = keyframes[i+1];
1235
else next = VideoContext::Get()->GetLength();
1240
if (frame > curFrame) {
1241
if (i != 0) prev = keyframes[i-1];
1251
if (n > 0) prev = keyframes[n-1];
1253
next = VideoContext::Get()->GetLength();
1257
int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
1258
int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
1262
for (size_t i=0;i<sel.Count();i++) {
1263
cur = SubsBox->GetDialogue(sel[i]);
1264
cur->Start.SetMS(start_ms);
1265
cur->End.SetMS(end_ms);
1270
SubsBox->editBox->Update(true);
1271
SubsBox->ass->FlagAsModified(_("snap to scene"));
1272
SubsBox->CommitChanges();
1279
void FrameMain::OnShiftToFrame (wxCommandEvent &event) {
1280
if (VideoContext::Get()->IsLoaded()) {
1282
wxArrayInt sels = SubsBox->GetSelection();
1283
size_t n=sels.Count();
1286
// Get shifting in ms
1287
AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
1289
int shiftBy = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true) - cur->Start.GetMS();
1292
for (size_t i=0;i<n;i++) {
1293
cur = SubsBox->GetDialogue(sels[i]);
1295
cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
1296
cur->End.SetMS(cur->End.GetMS()+shiftBy);
1302
SubsBox->ass->FlagAsModified(_("shift to frame"));
1303
SubsBox->CommitChanges();
1304
SubsBox->editBox->Update(true,false);
1311
void FrameMain::OnUndo(wxCommandEvent& WXUNUSED(event)) {
1312
// Block if it's on a editbox
1313
//wxWindow *focused = wxWindow::FindFocus();
1314
//if (focused && focused->IsKindOf(CLASSINFO(wxTextCtrl))) return;
1316
VideoContext::Get()->Stop();
1317
AssFile::StackPop();
1318
SubsBox->LoadFromAss(AssFile::top,true);
1319
AssFile::Popping = false;
1325
void FrameMain::OnRedo(wxCommandEvent& WXUNUSED(event)) {
1326
VideoContext::Get()->Stop();
1327
AssFile::StackRedo();
1328
SubsBox->LoadFromAss(AssFile::top,true);
1329
AssFile::Popping = false;
1335
void FrameMain::OnFind(wxCommandEvent &event) {
1336
VideoContext::Get()->Stop();
1337
Search.OpenDialog(false);
1343
void FrameMain::OnFindNext(wxCommandEvent &event) {
1344
VideoContext::Get()->Stop();
1351
void FrameMain::OnReplace(wxCommandEvent &event) {
1352
VideoContext::Get()->Stop();
1353
Search.OpenDialog(true);
1357
//////////////////////////////////
1358
// Change aspect ratio to default
1359
void FrameMain::OnSetARDefault (wxCommandEvent &event) {
1360
VideoContext::Get()->Stop();
1361
VideoContext::Get()->SetAspectRatio(0);
1362
SetDisplayMode(-1,-2);
1366
/////////////////////////////////////
1367
// Change aspect ratio to fullscreen
1368
void FrameMain::OnSetARFull (wxCommandEvent &event) {
1369
VideoContext::Get()->Stop();
1370
VideoContext::Get()->SetAspectRatio(1);
1371
SetDisplayMode(-1,-2);
1375
/////////////////////////////////////
1376
// Change aspect ratio to widescreen
1377
void FrameMain::OnSetARWide (wxCommandEvent &event) {
1378
VideoContext::Get()->Stop();
1379
VideoContext::Get()->SetAspectRatio(2);
1380
SetDisplayMode(-1,-2);
1384
///////////////////////////////
1385
// Change aspect ratio to 2:35
1386
void FrameMain::OnSetAR235 (wxCommandEvent &event) {
1387
VideoContext::Get()->Stop();
1388
VideoContext::Get()->SetAspectRatio(3);
1389
SetDisplayMode(-1,-2);
1393
/////////////////////////////////////////
1394
// Change aspect ratio to a custom value
1395
void FrameMain::OnSetARCustom (wxCommandEvent &event) {
1397
VideoContext::Get()->Stop();
1399
wxString value = wxGetTextFromUser(_("Enter aspect ratio in either decimal (e.g. 2.35) or fractional (e.g. 16:9) form. Enter a value like 853x480 to set a specific resolution."),_("Enter aspect ratio"),AegiFloatToString(VideoContext::Get()->GetAspectRatioValue()));
1400
if (value.IsEmpty()) return;
1406
if (value.ToDouble(&numval)) {
1407
//Nothing to see here, move along
1414
//Why bloat using Contains when we can just check the output of Find?
1415
pos = value.Find(':');
1416
if (pos==wxNOT_FOUND) pos = value.Find('/');
1417
if (pos==wxNOT_FOUND&&value.Contains(_T('x'))) {
1418
pos = value.Find('x');
1423
wxString num = value.Left(pos);
1424
wxString denum = value.Mid(pos+1);
1425
if (num.ToDouble(&a) && denum.ToDouble(&b) && b!=0) {
1427
if (scale) videoBox->videoDisplay->SetZoom(b / VideoContext::Get()->GetHeight());
1434
if (numval < 0.5 || numval > 5.0) wxMessageBox(_("Invalid value! Aspect ratio must be between 0.5 and 5.0."),_("Invalid Aspect Ratio"),wxICON_ERROR);
1438
VideoContext::Get()->SetAspectRatio(4,numval);
1439
SetDisplayMode(-1,-1);
1444
////////////////////////////////////
1445
// Window is attempted to be closed
1446
void FrameMain::OnCloseWindow (wxCloseEvent &event) {
1447
// Stop audio and video
1448
VideoContext::Get()->Stop();
1449
audioBox->audioDisplay->Stop();
1451
// Ask user if he wants to save first
1452
bool canVeto = event.CanVeto();
1453
int result = TryToCloseSubs(canVeto);
1455
// Store maximization state
1456
Options.SetBool(_T("Maximized"),IsMaximized());
1461
if (result == wxCANCEL) event.Veto();
1470
void FrameMain::OnCut (wxCommandEvent &event) {
1471
if (FindFocus() == EditBox->TextEdit) {
1472
EditBox->TextEdit->Cut();
1475
SubsBox->CutLines(SubsBox->GetSelection());
1478
void FrameMain::OnCopy (wxCommandEvent &event) {
1479
if (FindFocus() == EditBox->TextEdit) {
1480
EditBox->TextEdit->Copy();
1483
SubsBox->CopyLines(SubsBox->GetSelection());
1486
void FrameMain::OnPaste (wxCommandEvent &event) {
1487
if (FindFocus() == EditBox->TextEdit) {
1488
EditBox->TextEdit->Paste();
1491
SubsBox->PasteLines(SubsBox->GetFirstSelRow());
1497
void FrameMain::OnPasteOver (wxCommandEvent &event) {
1498
SubsBox->PasteLines(SubsBox->GetFirstSelRow(),true);
1502
////////////////////////
1503
// Select visible lines
1504
void FrameMain::OnSelectVisible (wxCommandEvent &event) {
1505
VideoContext::Get()->Stop();
1506
SubsBox->SelectVisible();
1510
//////////////////////
1511
// Open select dialog
1512
void FrameMain::OnSelect (wxCommandEvent &event) {
1513
VideoContext::Get()->Stop();
1514
DialogSelection select(this, SubsBox);
1521
void FrameMain::OnSort (wxCommandEvent &event) {
1522
// Ensure that StartMS is set properly
1524
AssDialogue *curDiag;
1526
for (std::list<AssEntry*>::iterator cur = AssFile::top->Line.begin(); cur != AssFile::top->Line.end(); cur++) {
1528
curDiag = AssEntry::GetAsDialogue(curEntry);
1529
if (curDiag) startMS = curDiag->GetStartMS();
1530
curEntry->SetStartMS(startMS);
1534
AssFile::top->Line.sort(LessByPointedToValue<AssEntry>());
1535
AssFile::top->FlagAsModified(_("sort"));
1536
SubsBox->UpdateMaps();
1537
SubsBox->CommitChanges();
1541
//////////////////////////
1542
// Open styling assistant
1543
void FrameMain::OnOpenStylingAssistant (wxCommandEvent &event) {
1544
VideoContext::Get()->Stop();
1545
if (!stylingAssistant) stylingAssistant = new DialogStyling(this,SubsBox);
1546
stylingAssistant->Show(true);
1552
void FrameMain::OnAutoSave(wxTimerEvent &event) {
1555
if (AssFile::top->loaded) {
1557
wxFileName origfile(AssFile::top->filename);
1558
wxString path = Options.AsText(_T("Auto save path"));
1559
if (path.IsEmpty()) path = origfile.GetPath();
1560
wxFileName dstpath(path);
1561
if (!dstpath.IsAbsolute()) path = StandardPaths::DecodePathMaybeRelative(path, _T("?user/"));
1563
dstpath.Assign(path);
1564
if (!dstpath.DirExists()) wxMkdir(path);
1567
wxString name = origfile.GetName();
1568
wxString backup = path;
1569
if (name.IsEmpty()) backup += _T("Untitled.AUTOSAVE.ass");
1570
else backup += origfile.GetName() + _T(".AUTOSAVE.ass");
1571
AssFile::top->Save(backup,false,false);
1574
StatusTimeout(_("File backup saved as \"") + backup + _T("\"."));
1577
catch (wxString err) {
1578
StatusTimeout(_T("Exception when attempting to autosave file: ") + err);
1580
catch (const wchar_t *err) {
1581
StatusTimeout(_T("Exception when attempting to autosave file: ") + wxString(err));
1584
StatusTimeout(_T("Unhandled exception when attempting to autosave file."));
1591
void FrameMain::OnStatusClear(wxTimerEvent &event) {
1592
SetStatusText(_T(""),1);
1598
void FrameMain::OnKeyDown(wxKeyEvent &event) {
1599
audioBox->audioDisplay->AddPendingEvent(event);
1604
/////////////////////
1605
// Next frame hotkey
1606
void FrameMain::OnNextFrame(wxCommandEvent &event) {
1607
videoBox->videoSlider->NextFrame();
1611
/////////////////////////
1612
// Previous frame hotkey
1613
void FrameMain::OnPrevFrame(wxCommandEvent &event) {
1614
videoBox->videoSlider->PrevFrame();
1618
///////////////////////////////////////////////////
1619
// Toggle focus between seek bar and whatever else
1620
void FrameMain::OnFocusSeek(wxCommandEvent &event) {
1621
wxWindow *curFocus = wxWindow::FindFocus();
1622
if (curFocus == videoBox->videoSlider) {
1623
if (PreviousFocus) PreviousFocus->SetFocus();
1626
PreviousFocus = curFocus;
1627
videoBox->videoSlider->SetFocus();
1632
////////////////////////
1633
// Previous line hotkey
1634
void FrameMain::OnPrevLine(wxCommandEvent &event) {
1635
int next = EditBox->linen-1;
1636
if (next < 0) return;
1637
SubsBox->SelectRow(next);
1638
SubsBox->MakeCellVisible(next,0);
1639
EditBox->SetToLine(next);
1643
////////////////////
1645
void FrameMain::OnNextLine(wxCommandEvent &event) {
1646
int nrows = SubsBox->GetRows();
1647
int next = EditBox->linen+1;
1648
if (next >= nrows) return;
1649
SubsBox->SelectRow(next);
1650
SubsBox->MakeCellVisible(next,0);
1651
EditBox->SetToLine(next);
1655
//////////////////////////////////
1656
// Cycle through tag hiding modes
1657
void FrameMain::OnToggleTags(wxCommandEvent &event) {
1659
int tagMode = Options.AsInt(_T("Grid hide overrides"));
1662
if (tagMode < 0 || tagMode > 2) tagMode = 1;
1664
tagMode = (tagMode+1)%3;
1667
// Show on status bar
1668
wxString message = _("ASS Override Tag mode set to ");
1669
if (tagMode == 0) message += _("show full tags.");
1670
if (tagMode == 1) message += _("simplify tags.");
1671
if (tagMode == 2) message += _("hide tags.");
1672
StatusTimeout(message,10000);
1675
Options.SetInt(_T("Grid hide overrides"),tagMode);
1679
SubsBox->Refresh(false);
1683
/////////////////////////////
1684
// Commit Edit Box's changes
1685
void FrameMain::OnEditBoxCommit(wxCommandEvent &event) {
1687
wxWindow *focus = FindFocus();
1691
if (focus == EditBox->TextEdit) {
1692
EditBox->Commit(true);
1693
EditBox->Update(true);
1698
//wxKeyEvent keyevent;
1699
//keyevent.m_keyCode = WXK_RETURN;
1700
//keyevent.m_controlDown = true;
1701
//keyevent.SetEventType(wxEVT_KEY_DOWN);
1702
wxCommandEvent keyevent(wxEVT_COMMAND_TEXT_ENTER,focus->GetId());
1703
focus->GetEventHandler()->AddPendingEvent(keyevent);
1708
///////////////////////////////
1709
// Choose a different language
1710
void FrameMain::OnChooseLanguage (wxCommandEvent &event) {
1712
AegisubApp *app = (AegisubApp*) wxTheApp;
1713
int old = app->locale.curCode;
1714
int newCode = app->locale.PickLanguage();
1717
if (newCode != -1) {
1719
Options.SetInt(_T("Locale Code"),newCode);
1722
// Language actually changed?
1723
if (newCode != old) {
1724
// Ask to restart program
1725
int result = wxMessageBox(_T("Aegisub needs to be restarted so that the new language can be applied. Restart now?"),_T("Restart Aegisub?"),wxICON_QUESTION | wxYES_NO);
1726
if (result == wxYES) {
1730
//wxStandardPaths stand;
1731
//wxExecute(_T("\"") + stand.GetExecutablePath() + _T("\""));
1739
/////////////////////
1740
// Pick associations
1741
void FrameMain::OnPickAssociations(wxCommandEvent &event) {
1742
ShowAssociationsDialog(this);
1748
void FrameMain::OnViewStandard (wxCommandEvent &event) {
1749
if (!audioBox->audioDisplay->loaded || !VideoContext::Get()->IsLoaded()) return;
1750
SetDisplayMode(1,1);
1756
void FrameMain::OnViewVideo (wxCommandEvent &event) {
1757
if (!VideoContext::Get()->IsLoaded()) return;
1758
SetDisplayMode(1,0);
1764
void FrameMain::OnViewAudio (wxCommandEvent &event) {
1765
if (!audioBox->audioDisplay->loaded) return;
1766
SetDisplayMode(0,1);
1772
void FrameMain::OnViewSubs (wxCommandEvent &event) {
1773
SetDisplayMode(0,0);
1777
////////////////////
1779
void FrameMain::OnMedusaPlay(wxCommandEvent &event) {
1781
audioBox->audioDisplay->GetTimesSelection(start,end);
1782
audioBox->audioDisplay->Play(start,end);
1784
void FrameMain::OnMedusaStop(wxCommandEvent &event) {
1786
if (audioBox->audioDisplay->player->IsPlaying()) {
1787
audioBox->audioDisplay->Stop();
1788
audioBox->audioDisplay->Refresh();
1791
// Otherwise, play the last 500 ms
1794
audioBox->audioDisplay->GetTimesSelection(start,end);
1795
audioBox->audioDisplay->Play(end-500,end);
1798
void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &event) {
1799
audioBox->audioDisplay->curStartMS += 10;
1800
audioBox->audioDisplay->Update();
1801
audioBox->audioDisplay->wxWindow::Update();
1802
audioBox->audioDisplay->UpdateTimeEditCtrls();
1804
void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &event) {
1805
audioBox->audioDisplay->curStartMS -= 10;
1806
audioBox->audioDisplay->Update();
1807
audioBox->audioDisplay->wxWindow::Update();
1808
audioBox->audioDisplay->UpdateTimeEditCtrls();
1810
void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &event) {
1811
audioBox->audioDisplay->curEndMS += 10;
1812
audioBox->audioDisplay->Update();
1813
audioBox->audioDisplay->wxWindow::Update();
1814
audioBox->audioDisplay->UpdateTimeEditCtrls();
1816
void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &event) {
1817
audioBox->audioDisplay->curEndMS -= 10;
1818
audioBox->audioDisplay->Update();
1819
audioBox->audioDisplay->wxWindow::Update();
1820
audioBox->audioDisplay->UpdateTimeEditCtrls();
1822
void FrameMain::OnMedusaPlayBefore(wxCommandEvent &event) {
1824
audioBox->audioDisplay->GetTimesSelection(start,end);
1825
audioBox->audioDisplay->Play(start-500,start);
1827
void FrameMain::OnMedusaPlayAfter(wxCommandEvent &event) {
1829
audioBox->audioDisplay->GetTimesSelection(start,end);
1830
audioBox->audioDisplay->Play(end,end+500);
1832
void FrameMain::OnMedusaNext(wxCommandEvent &event) {
1833
audioBox->audioDisplay->Next(false);
1835
void FrameMain::OnMedusaPrev(wxCommandEvent &event) {
1836
audioBox->audioDisplay->Prev(false);
1838
void FrameMain::OnMedusaEnter(wxCommandEvent &event) {
1839
audioBox->audioDisplay->CommitChanges(true);