~ubuntu-branches/ubuntu/trusty/aegisub/trusty

« back to all changes in this revision

Viewing changes to src/frame_main_events.cpp

  • Committer: Package Import Robot
  • Author(s): Sebastian Reichel
  • Date: 2012-03-16 22:58:00 UTC
  • Revision ID: package-import@ubuntu.com-20120316225800-yfb8h9e5n04rk46a
Tags: upstream-2.1.9
ImportĀ upstreamĀ versionĀ 2.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2005, Rodrigo Braz Monteiro
 
2
// All rights reserved.
 
3
//
 
4
// Redistribution and use in source and binary forms, with or without
 
5
// modification, are permitted provided that the following conditions are met:
 
6
//
 
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.
 
15
//
 
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.
 
27
//
 
28
// -----------------------------------------------------------------------------
 
29
//
 
30
// AEGISUB
 
31
//
 
32
// Website: http://aegisub.cellosoft.com
 
33
// Contact: mailto:zeratul@cellosoft.com
 
34
//
 
35
 
 
36
 
 
37
///////////////////
 
38
// Include headers
 
39
#include "config.h"
 
40
 
 
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"
 
53
#include "ass_file.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"
 
60
#include "vfr.h"
 
61
#include "subs_edit_box.h"
 
62
#include "options.h"
 
63
#include "dialog_properties.h"
 
64
#include "dialog_attachments.h"
 
65
#include "main.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"
 
79
#include "utils.h"
 
80
#ifdef WITH_AUTOMATION
 
81
#include "auto4_base.h"
 
82
#endif
 
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"
 
90
#include "keyframe.h"
 
91
 
 
92
#ifdef __APPLE__
 
93
extern "C" {
 
94
#include "libosxutil/libosxutil.h"
 
95
}
 
96
#endif
 
97
 
 
98
////////////////////
 
99
// Menu event table
 
100
BEGIN_EVENT_TABLE(FrameMain, wxFrame)
 
101
        EVT_TIMER(AutoSave_Timer, FrameMain::OnAutoSave)
 
102
        EVT_TIMER(StatusClear_Timer, FrameMain::OnStatusClear)
 
103
 
 
104
        EVT_CLOSE(FrameMain::OnCloseWindow)
 
105
 
 
106
        EVT_KEY_DOWN(FrameMain::OnKeyDown)
 
107
 
 
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)
 
115
 
 
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)
 
134
 
 
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)
 
153
 
 
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)     
 
157
#ifdef _DEBUG
 
158
        EVT_MENU(Menu_Audio_Open_Dummy, FrameMain::OnOpenDummyAudio)
 
159
        EVT_MENU(Menu_Audio_Open_Dummy_Noise, FrameMain::OnOpenDummyNoiseAudio)
 
160
#endif
 
161
 
 
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)
 
174
 
 
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)
 
189
        
 
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)
 
196
 
 
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)
 
205
 
 
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)
 
212
 
 
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)
 
220
 
 
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)
 
232
 
 
233
#ifdef __WXMAC__
 
234
   EVT_MENU(wxID_ABOUT, FrameMain::OnAbout)
 
235
   EVT_MENU(wxID_EXIT, FrameMain::OnExit)
 
236
#endif
 
237
END_EVENT_TABLE()
 
238
 
 
239
 
 
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);
 
245
#else
 
246
        SubsBox->AddPendingEvent(event);
 
247
#endif
 
248
}
 
249
 
 
250
 
 
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));
 
258
        }
 
259
 
 
260
        // Rebuild
 
261
        int added = 0;
 
262
        wxString n;
 
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);
 
270
                added++;
 
271
        }
 
272
 
 
273
        // Nothing added, add an empty placeholder
 
274
        if (added == 0) menu->Append(startID,_("Empty"))->Enable(false);
 
275
}
 
276
 
 
277
 
 
278
////////////////////////
 
279
// Menu is being opened
 
280
void FrameMain::OnMenuOpen (wxMenuEvent &event) {
 
281
        // Get menu
 
282
        MenuBar->Freeze();
 
283
        wxMenu *curMenu = event.GetMenu();
 
284
 
 
285
        // File menu
 
286
        if (curMenu == fileMenu) {
 
287
                // Rebuild recent
 
288
                RebuildRecentList(_T("Recent sub"),RecentSubs,Menu_File_Recent);
 
289
        }
 
290
 
 
291
        // View menu
 
292
        else if (curMenu == viewMenu) {
 
293
                // Flags
 
294
                bool aud = audioBox->audioDisplay->loaded;
 
295
                bool vid = VideoContext::Get()->IsLoaded();
 
296
 
 
297
                // Set states
 
298
                MenuBar->Enable(Menu_View_Audio,aud);
 
299
                MenuBar->Enable(Menu_View_Video,vid);
 
300
                MenuBar->Enable(Menu_View_Standard,aud && vid);
 
301
 
 
302
                // Select option
 
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);
 
307
        }
 
308
 
 
309
        // Video menu
 
310
        else if (curMenu == videoMenu) {
 
311
                bool state = VideoContext::Get()->IsLoaded();
 
312
 
 
313
                // Set states
 
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);
 
335
 
 
336
                // Set AR radio
 
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);
 
343
                switch (arType) {
 
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;
 
349
                }
 
350
 
 
351
                // Set overscan mask
 
352
                MenuBar->Check(Menu_Video_Overscan,Options.AsBool(_T("Show Overscan Mask")));
 
353
 
 
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);
 
358
        }
 
359
 
 
360
        // Audio menu
 
361
        else if (curMenu == audioMenu) {
 
362
                bool state = audioBox->loaded;
 
363
                bool vidstate = VideoContext::Get()->IsLoaded();
 
364
 
 
365
                MenuBar->Enable(Menu_Audio_Open_From_Video,vidstate);
 
366
                MenuBar->Enable(Menu_Audio_Close,state);
 
367
 
 
368
                // Rebuild recent
 
369
                RebuildRecentList(_T("Recent aud"),RecentAuds,Menu_Audio_Recent);
 
370
        }
 
371
 
 
372
        // Subtitles menu
 
373
        else if (curMenu == subtitlesMenu) {
 
374
                // Variables
 
375
                bool continuous;
 
376
                wxArrayInt sels = SubsBox->GetSelection(&continuous);
 
377
                int count = sels.Count();
 
378
                bool state,state2;
 
379
 
 
380
                // Entries
 
381
                state = count > 0;
 
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);
 
394
                state = count == 2;
 
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);
 
403
        }
 
404
 
 
405
        // Timing menu
 
406
        else if (curMenu == timingMenu) {
 
407
                // Variables
 
408
                bool continuous;
 
409
                wxArrayInt sels = SubsBox->GetSelection(&continuous);
 
410
                int count = sels.Count();
 
411
 
 
412
                // Video related
 
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);
 
418
 
 
419
                // Other
 
420
                state = count >= 2 && continuous;
 
421
                MenuBar->Enable(MENU_ADJOIN,state);
 
422
                MenuBar->Enable(MENU_ADJOIN2,state);
 
423
        }
 
424
 
 
425
        // Edit menu
 
426
        else if (curMenu == editMenu) {
 
427
                // Undo state
 
428
                wxMenuItem *item;
 
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());
 
433
 
 
434
                // Redo state
 
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());
 
439
 
 
440
                // Copy/cut/paste
 
441
                wxArrayInt sels = SubsBox->GetSelection();
 
442
                bool can_copy = (sels.Count() > 0);
 
443
 
 
444
                bool can_paste = true;
 
445
                if (wxTheClipboard->Open()) {
 
446
                        can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
 
447
                        wxTheClipboard->Close();
 
448
                }
 
449
 
 
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);
 
454
        }
 
455
 
 
456
        // Automation menu
 
457
#ifdef WITH_AUTOMATION
 
458
        else if (curMenu == automationMenu) {
 
459
                // Remove old macro items
 
460
                for (unsigned int i = 0; i < activeMacroItems.size(); i++) {
 
461
                        wxMenu *p = 0;
 
462
                        wxMenuItem *it = MenuBar->FindItem(Menu_Automation_Macro + i, &p);
 
463
                        if (it)
 
464
                                p->Delete(it);
 
465
                }
 
466
                activeMacroItems.clear();
 
467
 
 
468
                // Add new ones
 
469
                int added = 0;
 
470
                added += AddMacroMenuItems(automationMenu, wxGetApp().global_scripts->GetMacros());
 
471
                added += AddMacroMenuItems(automationMenu, local_scripts->GetMacros());
 
472
 
 
473
                // If none were added, show a ghosted notice
 
474
                if (added == 0) {
 
475
                        automationMenu->Append(Menu_Automation_Macro, _("No Automation macros loaded"))->Enable(false);
 
476
                        activeMacroItems.push_back(0);
 
477
                }
 
478
        }
 
479
#endif
 
480
 
 
481
        // Help menu
 
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);
 
486
        }
 
487
 
 
488
        MenuBar->Thaw();
 
489
}
 
490
 
 
491
 
 
492
//////////////////////////////
 
493
// Macro menu creation helper
 
494
int FrameMain::AddMacroMenuItems(wxMenu *menu, const std::vector<Automation4::FeatureMacro*> &macros) {
 
495
#ifdef WITH_AUTOMATION
 
496
        if (macros.empty()) {
 
497
                return 0;
 
498
        }
 
499
 
 
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);
 
505
                id++;
 
506
        }
 
507
 
 
508
        return macros.size();
 
509
#else
 
510
        return 0;
 
511
#endif
 
512
}
 
513
 
 
514
 
 
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));
 
521
}
 
522
 
 
523
 
 
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));
 
530
}
 
531
 
 
532
 
 
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));
 
539
}
 
540
 
 
541
 
 
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();
 
550
        Refresh();
 
551
}
 
552
 
 
553
 
 
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));
 
560
}
 
561
 
 
562
 
 
563
///////////////////
 
564
// Open new Window
 
565
void FrameMain::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
 
566
        RestartAegisub();
 
567
        //wxStandardPaths stand;
 
568
        //wxExecute(stand.GetExecutablePath());
 
569
}
 
570
 
 
571
 
 
572
////////
 
573
// Exit
 
574
void FrameMain::OnExit(wxCommandEvent& WXUNUSED(event)) {
 
575
        Close();
 
576
}
 
577
 
 
578
 
 
579
//////////////////
 
580
// Open about box
 
581
void FrameMain::OnAbout(wxCommandEvent &event) {
 
582
        AboutScreen About(this);
 
583
        About.ShowModal();
 
584
}
 
585
 
 
586
 
 
587
//////////////////////
 
588
// Open check updates
 
589
void FrameMain::OnCheckUpdates(wxCommandEvent &event) {
 
590
        PerformVersionCheck(true);
 
591
}
 
592
 
 
593
 
 
594
////////////////////
 
595
// Open help topics
 
596
void FrameMain::OnContents(wxCommandEvent& WXUNUSED(event)) {
 
597
        OpenHelp(_T(""));
 
598
}
 
599
 
 
600
/// @brief Open help files on OSX.
 
601
/// @param event
 
602
///
 
603
void FrameMain::OnFiles(wxCommandEvent& WXUNUSED(event)) {
 
604
#ifdef __WXMAC__
 
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());
 
608
#endif
 
609
}
 
610
 
 
611
////////////////
 
612
// Open website
 
613
/// @brief Open website 
 
614
/// @param event 
 
615
///
 
616
void FrameMain::OnWebsite(wxCommandEvent& WXUNUSED(event)) {
 
617
        AegisubApp::OpenURL(_T("http://www.aegisub.org/"));
 
618
}
 
619
 
 
620
 
 
621
///////////////
 
622
// Open forums
 
623
void FrameMain::OnForums(wxCommandEvent& WXUNUSED(event)) {
 
624
        AegisubApp::OpenURL(_T("http://forum.aegisub.org/"));
 
625
}
 
626
 
 
627
 
 
628
///////////////////
 
629
// Open bugtracker
 
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;
 
635
                }
 
636
                else {
 
637
                        wxMessageBox(_T("Now crashing with an unhandled exception..."));
 
638
                        throw this;
 
639
                }
 
640
        }
 
641
 
 
642
        AegisubApp::OpenURL(_T("http://devel.aegisub.org/"));
 
643
}
 
644
 
 
645
 
 
646
////////////////////
 
647
// Open IRC channel
 
648
void FrameMain::OnIRCChannel(wxCommandEvent& WXUNUSED(event)) {
 
649
        AegisubApp::OpenURL(_T("irc://irc.rizon.net/aegisub"));
 
650
}
 
651
 
 
652
 
 
653
//////////////
 
654
// Play video
 
655
void FrameMain::OnVideoPlay(wxCommandEvent &event) {
 
656
        VideoContext::Get()->Play();
 
657
}
 
658
 
 
659
 
 
660
 
 
661
//////////////
 
662
// Open video
 
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()) {
 
669
                LoadVideo(filename);
 
670
                wxFileName filepath(filename);
 
671
                Options.SetText(_T("Last open video path"), filepath.GetPath());
 
672
                Options.Save();
 
673
        }
 
674
}
 
675
 
 
676
 
 
677
///////////////
 
678
// Close video
 
679
void FrameMain::OnCloseVideo(wxCommandEvent& WXUNUSED(event)) {
 
680
        LoadVideo(_T(""));
 
681
}
 
682
 
 
683
 
 
684
//////////////
 
685
// Open Audio
 
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()) {
 
693
                LoadAudio(filename);
 
694
                wxFileName filepath(filename);
 
695
                Options.SetText(_T("Last open audio path"), filepath.GetPath());
 
696
                Options.Save();
 
697
        }
 
698
}
 
699
 
 
700
 
 
701
void FrameMain::OnOpenAudioFromVideo (wxCommandEvent& WXUNUSED(event)) {
 
702
        LoadAudio(_T(""),true);
 
703
}
 
704
 
 
705
 
 
706
void FrameMain::OnCloseAudio (wxCommandEvent& WXUNUSED(event)) {
 
707
        LoadAudio(_T(""));
 
708
}
 
709
 
 
710
#ifdef _DEBUG
 
711
void FrameMain::OnOpenDummyAudio (wxCommandEvent& WXUNUSED(event)) {
 
712
        LoadAudio(_T("?dummy"));
 
713
}
 
714
void FrameMain::OnOpenDummyNoiseAudio (wxCommandEvent& WXUNUSED(event)) {
 
715
        LoadAudio(_T("?noise"));
 
716
}
 
717
#endif
 
718
 
 
719
 
 
720
//////////////////
 
721
// Open subtitles
 
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());
 
729
                Options.Save();
 
730
        }
 
731
}
 
732
 
 
733
 
 
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"));
 
740
 
 
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);
 
747
                }
 
748
                wxFileName filepath(filename);
 
749
                Options.SetText(_T("Last open subtitles path"), filepath.GetPath());
 
750
                Options.Save();
 
751
        }
 
752
}
 
753
 
 
754
 
 
755
/////////////////////
 
756
// Save subtitles as
 
757
void FrameMain::OnSaveSubtitlesAs(wxCommandEvent& WXUNUSED(event)) {
 
758
        SaveSubtitles(true);
 
759
}
 
760
 
 
761
 
 
762
//////////////////
 
763
// Save subtitles
 
764
void FrameMain::OnSaveSubtitles(wxCommandEvent& WXUNUSED(event)) {
 
765
        SaveSubtitles(false);
 
766
}
 
767
 
 
768
 
 
769
////////////////////////////////////////
 
770
// Save subtitles with specific charset
 
771
void FrameMain::OnSaveSubtitlesCharset(wxCommandEvent& WXUNUSED(event)) {
 
772
        SaveSubtitles(true,true);
 
773
}
 
774
 
 
775
 
 
776
///////////////////
 
777
// Close subtitles
 
778
void FrameMain::OnNewSubtitles(wxCommandEvent& WXUNUSED(event)) {
 
779
        LoadSubtitles(_T(""));
 
780
}
 
781
 
 
782
 
 
783
////////////////////
 
784
// Export subtitles
 
785
void FrameMain::OnExportSubtitles(wxCommandEvent & WXUNUSED(event)) {
 
786
#ifdef WITH_AUTOMATION
 
787
        int autoreload = Options.AsInt(_T("Automation Autoreload Mode"));
 
788
        if (autoreload & 1) {
 
789
                // Local scripts
 
790
                const std::vector<Automation4::Script*> scripts = local_scripts->GetScripts();
 
791
                for (size_t i = 0; i < scripts.size(); ++i) {
 
792
                        try {
 
793
                                scripts[i]->Reload();
 
794
                        }
 
795
                        catch (const wchar_t *e) {
 
796
                                wxLogError(_T("Error while reloading Automation scripts before export: %s"), e);
 
797
                        }
 
798
                        catch (...) {
 
799
                                wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
 
800
                        }
 
801
                }
 
802
        }
 
803
        if (autoreload & 2) {
 
804
                // Global scripts
 
805
                wxGetApp().global_scripts->Reload();
 
806
        }
 
807
#endif
 
808
 
 
809
        DialogExport exporter(this);
 
810
        exporter.ShowModal();
 
811
}
 
812
 
 
813
 
 
814
/////////////////
 
815
// Open VFR tags
 
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()) {
 
822
                LoadVFR(filename);
 
823
                wxFileName filepath(filename);
 
824
                Options.SetText(_T("Last open timecodes path"), filepath.GetPath());
 
825
                Options.Save();
 
826
        }
 
827
}
 
828
 
 
829
 
 
830
/////////////////
 
831
// Save VFR tags
 
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()) {
 
838
                SaveVFR(filename);
 
839
                wxFileName filepath(filename);
 
840
                Options.SetText(_T("Last open timecodes path"), filepath.GetPath());
 
841
                Options.Save();
 
842
        }
 
843
}
 
844
 
 
845
 
 
846
 
 
847
//////////////////
 
848
// Close VFR tags
 
849
void FrameMain::OnCloseVFR(wxCommandEvent &event) {
 
850
        LoadVFR(_T(""));
 
851
}
 
852
 
 
853
 
 
854
//////////////////
 
855
// Open keyframes
 
856
void FrameMain::OnOpenKeyframes (wxCommandEvent &event) {
 
857
        // Pick file
 
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());
 
863
        Options.Save();
 
864
 
 
865
        // Load
 
866
        KeyFrameFile::Load(filename);
 
867
        videoBox->videoSlider->Refresh();
 
868
        audioBox->audioDisplay->Update();
 
869
        Refresh();
 
870
}
 
871
 
 
872
 
 
873
///////////////////
 
874
// Close keyframes
 
875
void FrameMain::OnCloseKeyframes (wxCommandEvent &event) {
 
876
        VideoContext::Get()->CloseOverKeyFrames();
 
877
        videoBox->videoSlider->Refresh();
 
878
        audioBox->audioDisplay->Update();
 
879
        Refresh();
 
880
}
 
881
 
 
882
 
 
883
//////////////////
 
884
// Save keyframes
 
885
void FrameMain::OnSaveKeyframes (wxCommandEvent &event) {
 
886
        // Pick file
 
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());
 
892
        Options.Save();
 
893
 
 
894
        // Save
 
895
        KeyFrameFile::Save(filename);
 
896
}
 
897
 
 
898
 
 
899
///////////////
 
900
// Zoom levels
 
901
void FrameMain::OnSetZoom50(wxCommandEvent& WXUNUSED(event)) {
 
902
        VideoContext::Get()->Stop();
 
903
        videoBox->videoDisplay->zoomBox->SetSelection(3);
 
904
        videoBox->videoDisplay->SetZoomPos(3);
 
905
}
 
906
 
 
907
void FrameMain::OnSetZoom100(wxCommandEvent& WXUNUSED(event)) {
 
908
        VideoContext::Get()->Stop();
 
909
        videoBox->videoDisplay->zoomBox->SetSelection(7);
 
910
        videoBox->videoDisplay->SetZoomPos(7);
 
911
}
 
912
 
 
913
void FrameMain::OnSetZoom200(wxCommandEvent& WXUNUSED(event)) {
 
914
        VideoContext::Get()->Stop();
 
915
        videoBox->videoDisplay->zoomBox->SetSelection(15);
 
916
        videoBox->videoDisplay->SetZoomPos(15);
 
917
}
 
918
 
 
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());
 
923
}
 
924
 
 
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());
 
931
}
 
932
 
 
933
void FrameMain::OnSetZoom(wxCommandEvent &event) {
 
934
        videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
 
935
}
 
936
 
 
937
 
 
938
////////////////
 
939
// Detach video
 
940
void FrameMain::OnDetachVideo(wxCommandEvent &event) {
 
941
        DetachVideo();
 
942
}
 
943
 
 
944
 
 
945
///////////////////
 
946
// Use dummy video
 
947
void FrameMain::OnDummyVideo (wxCommandEvent &event) {
 
948
        wxString fn;
 
949
        if (DialogDummyVideo::CreateDummyVideo(this, fn)) {
 
950
                LoadVideo(fn);
 
951
        }
 
952
}
 
953
 
 
954
 
 
955
///////////////////
 
956
// Overscan toggle
 
957
void FrameMain::OnOverscan (wxCommandEvent &event) {
 
958
        Options.SetBool(_T("Show overscan mask"),event.IsChecked());
 
959
        Options.Save();
 
960
        VideoContext::Get()->Stop();
 
961
        videoBox->videoDisplay->Render();
 
962
}
 
963
 
 
964
 
 
965
//////////////////////
 
966
// Show video details
 
967
void FrameMain::OnOpenVideoDetails (wxCommandEvent &event) {
 
968
        VideoContext::Get()->Stop();
 
969
        DialogVideoDetails videodetails(this);
 
970
        videodetails.ShowModal();       
 
971
}
 
972
 
 
973
 
 
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);
 
980
                JumpTo.ShowModal();
 
981
                videoBox->videoSlider->SetFocus();
 
982
        }
 
983
}
 
984
 
 
985
 
 
986
/////////////////////
 
987
// Open shift dialog
 
988
void FrameMain::OnShift(wxCommandEvent& WXUNUSED(event)) {
 
989
        VideoContext::Get()->Stop();
 
990
        DialogShiftTimes Shift(this,SubsBox);
 
991
        Shift.ShowModal();
 
992
}
 
993
 
 
994
 
 
995
///////////////////
 
996
// Open properties
 
997
void FrameMain::OnOpenProperties (wxCommandEvent &event) {
 
998
        VideoContext::Get()->Stop();
 
999
        DialogProperties Properties(this);
 
1000
        int res = Properties.ShowModal();
 
1001
        if (res) {
 
1002
                SubsBox->CommitChanges();
 
1003
        }
 
1004
}
 
1005
 
 
1006
 
 
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();
 
1015
}
 
1016
 
 
1017
 
 
1018
////////////////////
 
1019
// Open attachments
 
1020
void FrameMain::OnOpenAttachments(wxCommandEvent& WXUNUSED(event)) {
 
1021
        VideoContext::Get()->Stop();
 
1022
        DialogAttachments attachments(this);
 
1023
        attachments.ShowModal();
 
1024
}
 
1025
 
 
1026
 
 
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);
 
1034
        Trans.ShowModal();
 
1035
}
 
1036
 
 
1037
 
 
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();
 
1045
}
 
1046
 
 
1047
 
 
1048
////////////////////////
 
1049
// Open Fonts Collector
 
1050
void FrameMain::OnOpenFontsCollector (wxCommandEvent &event) {
 
1051
        VideoContext::Get()->Stop();
 
1052
        DialogFontsCollector Collector(this);
 
1053
        Collector.ShowModal();
 
1054
}
 
1055
 
 
1056
 
 
1057
/////////////////////////////
 
1058
// Open Resolution Resampler
 
1059
void FrameMain::OnOpenResample (wxCommandEvent &event) {
 
1060
        VideoContext::Get()->Stop();
 
1061
        DialogResample diag(this, SubsBox);
 
1062
        diag.ShowModal();
 
1063
}
 
1064
 
 
1065
 
 
1066
/////////////////////////////////////
 
1067
// Open Timing post-processor dialog
 
1068
void FrameMain::OnOpenTimingProcessor (wxCommandEvent &event) {
 
1069
        DialogTimingProcessor timing(this,SubsBox);
 
1070
        timing.ShowModal();
 
1071
}
 
1072
/////////////////////////////////////
 
1073
// Open Kanji Timer dialog
 
1074
void FrameMain::OnOpenKanjiTimer (wxCommandEvent &event) {
 
1075
        DialogKanjiTimer kanjitimer(this,SubsBox);
 
1076
        kanjitimer.ShowModal();
 
1077
}
 
1078
 
 
1079
 
 
1080
///////////////////////
 
1081
// Open Options dialog
 
1082
void FrameMain::OnOpenOptions (wxCommandEvent &event) {
 
1083
        try {
 
1084
                DialogOptions options(this);
 
1085
                options.ShowModal();
 
1086
        }
 
1087
        catch (const wxChar *e) {
 
1088
                wxLogError(e);
 
1089
        }
 
1090
}
 
1091
 
 
1092
 
 
1093
//////////////////
 
1094
// Open log window
 
1095
void FrameMain::OnOpenLog (wxCommandEvent &event) {
 
1096
        LogWindow->Show(true);
 
1097
}
 
1098
 
 
1099
 
 
1100
//////////////////
 
1101
// Launch ASSDraw
 
1102
void FrameMain::OnOpenASSDraw (wxCommandEvent &event) {
 
1103
        wxExecute(_T("\"") + StandardPaths::DecodePath(_T("?data/ASSDraw3.exe")) + _T("\""));
 
1104
}
 
1105
 
 
1106
 
 
1107
///////////////////
 
1108
// Open Automation
 
1109
void FrameMain::OnOpenAutomation (wxCommandEvent &event) {
 
1110
#ifdef WITH_AUTOMATION
 
1111
#ifdef __APPLE__
 
1112
        if (wxGetMouseState().CmdDown()) {
 
1113
#else
 
1114
        if (wxGetMouseState().ControlDown()) {
 
1115
#endif
 
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) {
 
1120
                                try {
 
1121
                                        scripts[i]->Reload();
 
1122
                                }
 
1123
                                catch (const wchar_t *e) {
 
1124
                                        wxLogError(e);
 
1125
                                }
 
1126
                                catch (...) {
 
1127
                                        wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
 
1128
                                }
 
1129
                        }
 
1130
 
 
1131
                        StatusTimeout(_("Reloaded all Automation scripts"));
 
1132
                }
 
1133
                else {
 
1134
                        StatusTimeout(_("Reloaded autoload Automation scripts"));
 
1135
                }
 
1136
        }
 
1137
        else {
 
1138
                VideoContext::Get()->Stop();
 
1139
                DialogAutomation dlg(this, local_scripts);
 
1140
                dlg.ShowModal();
 
1141
        }
 
1142
#endif
 
1143
}
 
1144
 
 
1145
 
 
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
 
1157
        SubsBox->Clear();
 
1158
        // Run the macro...
 
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();
 
1166
#endif
 
1167
}
 
1168
 
 
1169
 
 
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);
 
1178
                }
 
1179
        }
 
1180
}
 
1181
 
 
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);
 
1188
                }
 
1189
        }
 
1190
}
 
1191
 
 
1192
 
 
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);
 
1201
                }
 
1202
        }
 
1203
}
 
1204
 
 
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);
 
1211
                }
 
1212
        }
 
1213
}
 
1214
 
 
1215
 
 
1216
/////////////////
 
1217
// Snap to scene
 
1218
void FrameMain::OnSnapToScene (wxCommandEvent &event) {
 
1219
        if (VideoContext::Get()->IsLoaded()) {
 
1220
                // Get frames
 
1221
                wxArrayInt sel = SubsBox->GetSelection();
 
1222
                int curFrame = VideoContext::Get()->GetFrameN();
 
1223
                int prev = 0;
 
1224
                int next = 0;
 
1225
                int frame = 0;
 
1226
                wxArrayInt keyframes = VideoContext::Get()->GetKeyFrames();
 
1227
                size_t n = keyframes.Count();
 
1228
                bool found = false;
 
1229
                for (size_t i=0;i<n;i++) {
 
1230
                        frame = keyframes[i];
 
1231
 
 
1232
                        if (frame == curFrame) {
 
1233
                                prev = frame;
 
1234
                                if (i < n-1) next = keyframes[i+1];
 
1235
                                else next = VideoContext::Get()->GetLength();
 
1236
                                found = true;
 
1237
                                break;
 
1238
                        }
 
1239
 
 
1240
                        if (frame > curFrame) {
 
1241
                                if (i != 0) prev = keyframes[i-1];
 
1242
                                else prev = 0;
 
1243
                                next = frame;
 
1244
                                found = true;
 
1245
                                break;
 
1246
                        }
 
1247
                }
 
1248
 
 
1249
                // Last section?
 
1250
                if (!found) {
 
1251
                        if (n > 0) prev = keyframes[n-1];
 
1252
                        else prev = 0;
 
1253
                        next = VideoContext::Get()->GetLength();
 
1254
                }
 
1255
 
 
1256
                // Get times
 
1257
                int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
 
1258
                int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
 
1259
                AssDialogue *cur;
 
1260
 
 
1261
                // Update rows
 
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);
 
1266
                        cur->UpdateData();
 
1267
                }
 
1268
 
 
1269
                // Commit
 
1270
                SubsBox->editBox->Update(true);
 
1271
                SubsBox->ass->FlagAsModified(_("snap to scene"));
 
1272
                SubsBox->CommitChanges();
 
1273
        }
 
1274
}
 
1275
 
 
1276
 
 
1277
//////////////////
 
1278
// Shift to frame
 
1279
void FrameMain::OnShiftToFrame (wxCommandEvent &event) {
 
1280
        if (VideoContext::Get()->IsLoaded()) {
 
1281
                // Get selection
 
1282
                wxArrayInt sels = SubsBox->GetSelection();
 
1283
                size_t n=sels.Count();
 
1284
                if (n == 0) return;
 
1285
 
 
1286
                // Get shifting in ms
 
1287
                AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
 
1288
                if (!cur) return;
 
1289
                int shiftBy = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true) - cur->Start.GetMS();
 
1290
 
 
1291
                // Update
 
1292
                for (size_t i=0;i<n;i++) {
 
1293
                        cur = SubsBox->GetDialogue(sels[i]);
 
1294
                        if (cur) {
 
1295
                                cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
 
1296
                                cur->End.SetMS(cur->End.GetMS()+shiftBy);
 
1297
                                cur->UpdateData();
 
1298
                        }
 
1299
                }
 
1300
 
 
1301
                // Commit
 
1302
                SubsBox->ass->FlagAsModified(_("shift to frame"));
 
1303
                SubsBox->CommitChanges();
 
1304
                SubsBox->editBox->Update(true,false);
 
1305
        }
 
1306
}
 
1307
 
 
1308
 
 
1309
////////
 
1310
// Undo
 
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;
 
1315
 
 
1316
        VideoContext::Get()->Stop();
 
1317
        AssFile::StackPop();
 
1318
        SubsBox->LoadFromAss(AssFile::top,true);
 
1319
        AssFile::Popping = false;
 
1320
}
 
1321
 
 
1322
 
 
1323
////////
 
1324
// Redo
 
1325
void FrameMain::OnRedo(wxCommandEvent& WXUNUSED(event)) {
 
1326
        VideoContext::Get()->Stop();
 
1327
        AssFile::StackRedo();
 
1328
        SubsBox->LoadFromAss(AssFile::top,true);
 
1329
        AssFile::Popping = false;
 
1330
}
 
1331
 
 
1332
 
 
1333
////////
 
1334
// Find
 
1335
void FrameMain::OnFind(wxCommandEvent &event) {
 
1336
        VideoContext::Get()->Stop();
 
1337
        Search.OpenDialog(false);
 
1338
}
 
1339
 
 
1340
 
 
1341
/////////////
 
1342
// Find next
 
1343
void FrameMain::OnFindNext(wxCommandEvent &event) {
 
1344
        VideoContext::Get()->Stop();
 
1345
        Search.FindNext();
 
1346
}
 
1347
 
 
1348
 
 
1349
//////////////////
 
1350
// Find & replace
 
1351
void FrameMain::OnReplace(wxCommandEvent &event) {
 
1352
        VideoContext::Get()->Stop();
 
1353
        Search.OpenDialog(true);
 
1354
}
 
1355
 
 
1356
 
 
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);
 
1363
}
 
1364
 
 
1365
 
 
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);
 
1372
}
 
1373
 
 
1374
 
 
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);
 
1381
}
 
1382
 
 
1383
 
 
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);
 
1390
}
 
1391
 
 
1392
 
 
1393
/////////////////////////////////////////
 
1394
// Change aspect ratio to a custom value
 
1395
void FrameMain::OnSetARCustom (wxCommandEvent &event) {
 
1396
        // Get text
 
1397
        VideoContext::Get()->Stop();
 
1398
        
 
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;
 
1401
 
 
1402
        value.MakeLower();
 
1403
 
 
1404
        // Process text
 
1405
        double numval;
 
1406
        if (value.ToDouble(&numval)) {
 
1407
                //Nothing to see here, move along
 
1408
        }
 
1409
        else {
 
1410
                double a,b;
 
1411
                int pos=0;
 
1412
                bool scale=false;
 
1413
                
 
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');
 
1419
                        scale=true;
 
1420
                }
 
1421
 
 
1422
                if (pos>0) {
 
1423
                        wxString num = value.Left(pos);
 
1424
                        wxString denum = value.Mid(pos+1);
 
1425
                        if (num.ToDouble(&a) && denum.ToDouble(&b) && b!=0) {
 
1426
                                numval = a/b;
 
1427
                                if (scale) videoBox->videoDisplay->SetZoom(b / VideoContext::Get()->GetHeight());
 
1428
                        }
 
1429
                }
 
1430
                else numval = 0.0;
 
1431
        }
 
1432
 
 
1433
        // Sanity check
 
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);
 
1435
 
 
1436
        // Set value
 
1437
        else {
 
1438
                VideoContext::Get()->SetAspectRatio(4,numval);
 
1439
                SetDisplayMode(-1,-1);
 
1440
        }
 
1441
}
 
1442
 
 
1443
 
 
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();
 
1450
 
 
1451
        // Ask user if he wants to save first
 
1452
        bool canVeto = event.CanVeto();
 
1453
        int result = TryToCloseSubs(canVeto);
 
1454
 
 
1455
        // Store maximization state
 
1456
        Options.SetBool(_T("Maximized"),IsMaximized());
 
1457
        Options.Save();
 
1458
 
 
1459
        // Abort/destroy
 
1460
        if (canVeto) {
 
1461
                if (result == wxCANCEL) event.Veto();
 
1462
                else Destroy();
 
1463
        }
 
1464
        else Destroy();
 
1465
}
 
1466
 
 
1467
 
 
1468
//////////////////
 
1469
// Cut/copy/paste
 
1470
void FrameMain::OnCut (wxCommandEvent &event) {
 
1471
        if (FindFocus() == EditBox->TextEdit) {
 
1472
                EditBox->TextEdit->Cut();
 
1473
                return;
 
1474
        }
 
1475
        SubsBox->CutLines(SubsBox->GetSelection());
 
1476
}
 
1477
 
 
1478
void FrameMain::OnCopy (wxCommandEvent &event) {
 
1479
        if (FindFocus() == EditBox->TextEdit) {
 
1480
                EditBox->TextEdit->Copy();
 
1481
                return;
 
1482
        }
 
1483
        SubsBox->CopyLines(SubsBox->GetSelection());
 
1484
}
 
1485
 
 
1486
void FrameMain::OnPaste (wxCommandEvent &event) {
 
1487
        if (FindFocus() == EditBox->TextEdit) {
 
1488
                EditBox->TextEdit->Paste();
 
1489
                return;
 
1490
        }
 
1491
        SubsBox->PasteLines(SubsBox->GetFirstSelRow());
 
1492
}
 
1493
 
 
1494
 
 
1495
//////////////
 
1496
// Paste over
 
1497
void FrameMain::OnPasteOver (wxCommandEvent &event) {
 
1498
        SubsBox->PasteLines(SubsBox->GetFirstSelRow(),true);
 
1499
}
 
1500
 
 
1501
 
 
1502
////////////////////////
 
1503
// Select visible lines
 
1504
void FrameMain::OnSelectVisible (wxCommandEvent &event) {
 
1505
        VideoContext::Get()->Stop();
 
1506
        SubsBox->SelectVisible();
 
1507
}
 
1508
 
 
1509
 
 
1510
//////////////////////
 
1511
// Open select dialog
 
1512
void FrameMain::OnSelect (wxCommandEvent &event) {
 
1513
        VideoContext::Get()->Stop();
 
1514
        DialogSelection select(this, SubsBox);
 
1515
        select.ShowModal();
 
1516
}
 
1517
 
 
1518
 
 
1519
//////////////////
 
1520
// Sort subtitles
 
1521
void FrameMain::OnSort (wxCommandEvent &event) {
 
1522
        // Ensure that StartMS is set properly
 
1523
        AssEntry *curEntry;
 
1524
        AssDialogue *curDiag;
 
1525
        int startMS = -1;
 
1526
        for (std::list<AssEntry*>::iterator cur = AssFile::top->Line.begin(); cur != AssFile::top->Line.end(); cur++) {
 
1527
                curEntry = *cur;
 
1528
                curDiag = AssEntry::GetAsDialogue(curEntry);
 
1529
                if (curDiag) startMS = curDiag->GetStartMS();
 
1530
                curEntry->SetStartMS(startMS);
 
1531
        }
 
1532
 
 
1533
        // Sort
 
1534
        AssFile::top->Line.sort(LessByPointedToValue<AssEntry>());
 
1535
        AssFile::top->FlagAsModified(_("sort"));
 
1536
        SubsBox->UpdateMaps();
 
1537
        SubsBox->CommitChanges();
 
1538
}
 
1539
 
 
1540
 
 
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);
 
1547
}
 
1548
 
 
1549
 
 
1550
///////////////
 
1551
// Auto backup
 
1552
void FrameMain::OnAutoSave(wxTimerEvent &event) {
 
1553
        // Auto Save
 
1554
        try {
 
1555
                if (AssFile::top->loaded) {
 
1556
                        // Set path
 
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/"));
 
1562
                        path += _T("/");
 
1563
                        dstpath.Assign(path);
 
1564
                        if (!dstpath.DirExists()) wxMkdir(path);
 
1565
 
 
1566
                        // Save
 
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);
 
1572
 
 
1573
                        // Set status bar
 
1574
                        StatusTimeout(_("File backup saved as \"") + backup + _T("\"."));
 
1575
                }
 
1576
        }
 
1577
        catch (wxString err) {
 
1578
                StatusTimeout(_T("Exception when attempting to autosave file: ") + err);
 
1579
        }
 
1580
        catch (const wchar_t *err) {
 
1581
                StatusTimeout(_T("Exception when attempting to autosave file: ") + wxString(err));
 
1582
        }
 
1583
        catch (...) {
 
1584
                StatusTimeout(_T("Unhandled exception when attempting to autosave file."));
 
1585
        }
 
1586
}
 
1587
 
 
1588
 
 
1589
///////////////////
 
1590
// Clear statusbar
 
1591
void FrameMain::OnStatusClear(wxTimerEvent &event) {
 
1592
        SetStatusText(_T(""),1);
 
1593
}
 
1594
 
 
1595
 
 
1596
////////////
 
1597
// Key down
 
1598
void FrameMain::OnKeyDown(wxKeyEvent &event) {
 
1599
        audioBox->audioDisplay->AddPendingEvent(event);
 
1600
        event.Skip();
 
1601
}
 
1602
 
 
1603
 
 
1604
/////////////////////
 
1605
// Next frame hotkey
 
1606
void FrameMain::OnNextFrame(wxCommandEvent &event) {
 
1607
        videoBox->videoSlider->NextFrame();
 
1608
}
 
1609
 
 
1610
 
 
1611
/////////////////////////
 
1612
// Previous frame hotkey
 
1613
void FrameMain::OnPrevFrame(wxCommandEvent &event) {
 
1614
        videoBox->videoSlider->PrevFrame();
 
1615
}
 
1616
 
 
1617
 
 
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();
 
1624
        }
 
1625
        else {
 
1626
                PreviousFocus = curFocus;
 
1627
                videoBox->videoSlider->SetFocus();
 
1628
        }
 
1629
}
 
1630
 
 
1631
 
 
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);
 
1640
}
 
1641
 
 
1642
 
 
1643
////////////////////
 
1644
// Next line hotkey
 
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);
 
1652
}
 
1653
 
 
1654
 
 
1655
//////////////////////////////////
 
1656
// Cycle through tag hiding modes
 
1657
void FrameMain::OnToggleTags(wxCommandEvent &event) {
 
1658
        // Read value
 
1659
        int tagMode = Options.AsInt(_T("Grid hide overrides"));
 
1660
 
 
1661
        // Cycle to next
 
1662
        if (tagMode < 0 || tagMode > 2) tagMode = 1;
 
1663
        else {
 
1664
                tagMode = (tagMode+1)%3;
 
1665
        }
 
1666
 
 
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);
 
1673
 
 
1674
        // Set option
 
1675
        Options.SetInt(_T("Grid hide overrides"),tagMode);
 
1676
        Options.Save();
 
1677
 
 
1678
        // Refresh grid
 
1679
        SubsBox->Refresh(false);
 
1680
}
 
1681
 
 
1682
 
 
1683
/////////////////////////////
 
1684
// Commit Edit Box's changes
 
1685
void FrameMain::OnEditBoxCommit(wxCommandEvent &event) {
 
1686
        // Find focus
 
1687
        wxWindow *focus = FindFocus();
 
1688
        if (!focus) return;
 
1689
 
 
1690
        // Is the text edit
 
1691
        if (focus == EditBox->TextEdit) {
 
1692
                EditBox->Commit(true);
 
1693
                EditBox->Update(true);
 
1694
        }
 
1695
 
 
1696
        // Other window
 
1697
        else {
 
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);
 
1704
        }
 
1705
}
 
1706
 
 
1707
 
 
1708
///////////////////////////////
 
1709
// Choose a different language
 
1710
void FrameMain::OnChooseLanguage (wxCommandEvent &event) {
 
1711
        // Get language
 
1712
        AegisubApp *app = (AegisubApp*) wxTheApp;
 
1713
        int old = app->locale.curCode;
 
1714
        int newCode = app->locale.PickLanguage();
 
1715
 
 
1716
        // Is OK?
 
1717
        if (newCode != -1) {
 
1718
                // Set code
 
1719
                Options.SetInt(_T("Locale Code"),newCode);
 
1720
                Options.Save();
 
1721
 
 
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) {
 
1727
                                // Restart Aegisub
 
1728
                                if (Close()) {
 
1729
                                        RestartAegisub();
 
1730
                                        //wxStandardPaths stand;
 
1731
                                        //wxExecute(_T("\"") + stand.GetExecutablePath() + _T("\""));
 
1732
                                }
 
1733
                        }
 
1734
                }
 
1735
        }
 
1736
}
 
1737
 
 
1738
 
 
1739
/////////////////////
 
1740
// Pick associations
 
1741
void FrameMain::OnPickAssociations(wxCommandEvent &event) {
 
1742
        ShowAssociationsDialog(this);
 
1743
}
 
1744
 
 
1745
 
 
1746
/////////////////
 
1747
// View standard
 
1748
void FrameMain::OnViewStandard (wxCommandEvent &event) {
 
1749
        if (!audioBox->audioDisplay->loaded || !VideoContext::Get()->IsLoaded()) return;
 
1750
        SetDisplayMode(1,1);
 
1751
}
 
1752
 
 
1753
 
 
1754
//////////////
 
1755
// View video
 
1756
void FrameMain::OnViewVideo (wxCommandEvent &event) {
 
1757
        if (!VideoContext::Get()->IsLoaded()) return;
 
1758
        SetDisplayMode(1,0);
 
1759
}
 
1760
 
 
1761
 
 
1762
//////////////
 
1763
// View audio
 
1764
void FrameMain::OnViewAudio (wxCommandEvent &event) {
 
1765
        if (!audioBox->audioDisplay->loaded) return;
 
1766
        SetDisplayMode(0,1);
 
1767
}
 
1768
 
 
1769
 
 
1770
/////////////
 
1771
// View subs
 
1772
void FrameMain::OnViewSubs (wxCommandEvent &event) {
 
1773
        SetDisplayMode(0,0);
 
1774
}
 
1775
 
 
1776
 
 
1777
////////////////////
 
1778
// Medusa shortcuts
 
1779
void FrameMain::OnMedusaPlay(wxCommandEvent &event) {
 
1780
        int start=0,end=0;
 
1781
        audioBox->audioDisplay->GetTimesSelection(start,end);
 
1782
        audioBox->audioDisplay->Play(start,end);
 
1783
}
 
1784
void FrameMain::OnMedusaStop(wxCommandEvent &event) {
 
1785
        // Playing, stop
 
1786
        if (audioBox->audioDisplay->player->IsPlaying()) {
 
1787
                audioBox->audioDisplay->Stop();
 
1788
                audioBox->audioDisplay->Refresh();
 
1789
        }
 
1790
 
 
1791
        // Otherwise, play the last 500 ms
 
1792
        else {
 
1793
                int     start=0,end=0;
 
1794
                audioBox->audioDisplay->GetTimesSelection(start,end);
 
1795
                audioBox->audioDisplay->Play(end-500,end);
 
1796
        }
 
1797
}
 
1798
void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &event) {
 
1799
        audioBox->audioDisplay->curStartMS += 10;
 
1800
        audioBox->audioDisplay->Update();
 
1801
        audioBox->audioDisplay->wxWindow::Update();
 
1802
        audioBox->audioDisplay->UpdateTimeEditCtrls();
 
1803
}
 
1804
void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &event) {
 
1805
        audioBox->audioDisplay->curStartMS -= 10;
 
1806
        audioBox->audioDisplay->Update();
 
1807
        audioBox->audioDisplay->wxWindow::Update();
 
1808
        audioBox->audioDisplay->UpdateTimeEditCtrls();
 
1809
}
 
1810
void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &event) {
 
1811
        audioBox->audioDisplay->curEndMS += 10;
 
1812
        audioBox->audioDisplay->Update();
 
1813
        audioBox->audioDisplay->wxWindow::Update();
 
1814
        audioBox->audioDisplay->UpdateTimeEditCtrls();
 
1815
}
 
1816
void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &event) {
 
1817
        audioBox->audioDisplay->curEndMS -= 10;
 
1818
        audioBox->audioDisplay->Update();
 
1819
        audioBox->audioDisplay->wxWindow::Update();
 
1820
        audioBox->audioDisplay->UpdateTimeEditCtrls();
 
1821
}
 
1822
void FrameMain::OnMedusaPlayBefore(wxCommandEvent &event) {
 
1823
        int start=0,end=0;
 
1824
        audioBox->audioDisplay->GetTimesSelection(start,end);
 
1825
        audioBox->audioDisplay->Play(start-500,start);
 
1826
}
 
1827
void FrameMain::OnMedusaPlayAfter(wxCommandEvent &event) {
 
1828
        int start=0,end=0;
 
1829
        audioBox->audioDisplay->GetTimesSelection(start,end);
 
1830
        audioBox->audioDisplay->Play(end,end+500);
 
1831
}
 
1832
void FrameMain::OnMedusaNext(wxCommandEvent &event) {
 
1833
        audioBox->audioDisplay->Next(false);
 
1834
}
 
1835
void FrameMain::OnMedusaPrev(wxCommandEvent &event) {
 
1836
        audioBox->audioDisplay->Prev(false);
 
1837
}
 
1838
void FrameMain::OnMedusaEnter(wxCommandEvent &event) {
 
1839
        audioBox->audioDisplay->CommitChanges(true);
 
1840
}