6ee2f98349
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there. This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style. Some notes: * Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those. * Some multiline comments may have been munged into single line comments * Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them. * Enum comments can go after the enumeration itself '[value] /// comment' * include/aegisub/*.h haven't been converted yet, this will be done in a later commit * Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa. See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'. Originally committed to SVN as r3312.
2105 lines
54 KiB
C++
2105 lines
54 KiB
C++
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
// may be used to endorse or promote products derived from this software
|
|
// without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Aegisub Project http://www.aegisub.org/
|
|
//
|
|
// $Id$
|
|
|
|
/// @file frame_main_events.cpp
|
|
/// @brief Event handlers for controls in main window
|
|
/// @ingroup main_ui
|
|
///
|
|
|
|
|
|
///////////////////
|
|
// Include headers
|
|
#include "config.h"
|
|
|
|
#include <wx/wxprec.h>
|
|
#include <wx/mimetype.h>
|
|
#include <wx/filename.h>
|
|
#include <wx/tglbtn.h>
|
|
#include <wx/rawbmp.h>
|
|
#include <wx/stdpaths.h>
|
|
#include <wx/sysopt.h>
|
|
#include "subs_grid.h"
|
|
#include "frame_main.h"
|
|
#include "video_display.h"
|
|
#include "video_slider.h"
|
|
#include "video_box.h"
|
|
#include "ass_file.h"
|
|
#include "ass_dialogue.h"
|
|
#include "dialog_style_manager.h"
|
|
#include "dialog_translation.h"
|
|
#include "dialog_jumpto.h"
|
|
#include "dialog_shift_times.h"
|
|
#include "dialog_search_replace.h"
|
|
#include "vfr.h"
|
|
#include "subs_edit_box.h"
|
|
#include "options.h"
|
|
#include "dialog_properties.h"
|
|
#include "dialog_attachments.h"
|
|
#include "main.h"
|
|
#include "dialog_fonts_collector.h"
|
|
#include "dialog_about.h"
|
|
#include "dialog_export.h"
|
|
#include "audio_box.h"
|
|
#include "dialog_selection.h"
|
|
#include "dialog_styling_assistant.h"
|
|
#include "dialog_resample.h"
|
|
#include "dialog_kanji_timer.h"
|
|
#include "audio_display.h"
|
|
#include "toggle_bitmap.h"
|
|
#include "dialog_timing_processor.h"
|
|
#include "dialog_progress.h"
|
|
#include "dialog_options.h"
|
|
#include "utils.h"
|
|
#ifdef WITH_AUTOMATION
|
|
#include "auto4_base.h"
|
|
#endif
|
|
#include "dialog_automation.h"
|
|
#include "dialog_version_check.h"
|
|
#include "dialog_dummy_video.h"
|
|
#include "dialog_spellchecker.h"
|
|
#include "dialog_associations.h"
|
|
#include "standard_paths.h"
|
|
#include "dialog_video_details.h"
|
|
#include "keyframe.h"
|
|
#include "charset_conv.h"
|
|
#include "libresrc/libresrc.h"
|
|
|
|
|
|
|
|
////////////////////
|
|
// Menu event table
|
|
BEGIN_EVENT_TABLE(FrameMain, wxFrame)
|
|
EVT_TIMER(AutoSave_Timer, FrameMain::OnAutoSave)
|
|
EVT_TIMER(StatusClear_Timer, FrameMain::OnStatusClear)
|
|
|
|
EVT_CLOSE(FrameMain::OnCloseWindow)
|
|
|
|
EVT_KEY_DOWN(FrameMain::OnKeyDown)
|
|
|
|
EVT_MENU_OPEN(FrameMain::OnMenuOpen)
|
|
EVT_MENU_RANGE(Menu_File_Recent,Menu_File_Recent+99, FrameMain::OnOpenRecentSubs)
|
|
EVT_MENU_RANGE(Menu_Video_Recent,Menu_Video_Recent+99, FrameMain::OnOpenRecentVideo)
|
|
EVT_MENU_RANGE(Menu_Audio_Recent,Menu_Audio_Recent+99, FrameMain::OnOpenRecentAudio)
|
|
EVT_MENU_RANGE(Menu_Timecodes_Recent,Menu_Timecodes_Recent+99, FrameMain::OnOpenRecentTimecodes)
|
|
EVT_MENU_RANGE(Menu_Keyframes_Recent,Menu_Keyframes_Recent+99, FrameMain::OnOpenRecentKeyframes)
|
|
EVT_MENU_RANGE(Menu_Automation_Macro,Menu_Automation_Macro+99, FrameMain::OnAutomationMacro)
|
|
|
|
EVT_MENU_RANGE(MENU_GRID_START+1,MENU_GRID_END-1,FrameMain::OnGridEvent)
|
|
EVT_MENU(Menu_File_New_Window, FrameMain::OnNewWindow)
|
|
EVT_MENU(Menu_File_Exit, FrameMain::OnExit)
|
|
EVT_MENU(Menu_File_Open_Video, FrameMain::OnOpenVideo)
|
|
EVT_MENU(Menu_File_Close_Video, FrameMain::OnCloseVideo)
|
|
EVT_MENU(Menu_File_Open_Subtitles, FrameMain::OnOpenSubtitles)
|
|
EVT_MENU(Menu_File_Open_Subtitles_Charset, FrameMain::OnOpenSubtitlesCharset)
|
|
EVT_MENU(Menu_File_New_Subtitles, FrameMain::OnNewSubtitles)
|
|
EVT_MENU(Menu_File_Save_Subtitles, FrameMain::OnSaveSubtitles)
|
|
EVT_MENU(Menu_File_Save_Subtitles_As, FrameMain::OnSaveSubtitlesAs)
|
|
EVT_MENU(Menu_File_Save_Subtitles_With_Charset, FrameMain::OnSaveSubtitlesCharset)
|
|
EVT_MENU(Menu_File_Export_Subtitles, FrameMain::OnExportSubtitles)
|
|
EVT_MENU(Menu_File_Open_VFR, FrameMain::OnOpenVFR)
|
|
EVT_MENU(Menu_File_Save_VFR, FrameMain::OnSaveVFR)
|
|
EVT_MENU(Menu_File_Close_VFR, FrameMain::OnCloseVFR)
|
|
EVT_MENU(Menu_Video_Load_Keyframes, FrameMain::OnOpenKeyframes)
|
|
EVT_MENU(Menu_Video_Save_Keyframes, FrameMain::OnSaveKeyframes)
|
|
EVT_MENU(Menu_Video_Close_Keyframes, FrameMain::OnCloseKeyframes)
|
|
|
|
EVT_MENU(Menu_View_Zoom_50, FrameMain::OnSetZoom50)
|
|
EVT_MENU(Menu_View_Zoom_100, FrameMain::OnSetZoom100)
|
|
EVT_MENU(Menu_View_Zoom_200, FrameMain::OnSetZoom200)
|
|
EVT_COMBOBOX(Toolbar_Zoom_Dropdown, FrameMain::OnSetZoom)
|
|
EVT_MENU(Video_Frame_Play, FrameMain::OnVideoPlay)
|
|
EVT_MENU(Menu_Video_Zoom_In, FrameMain::OnZoomIn)
|
|
EVT_MENU(Menu_Video_Zoom_Out, FrameMain::OnZoomOut)
|
|
EVT_MENU(Menu_Video_AR_Default, FrameMain::OnSetARDefault)
|
|
EVT_MENU(Menu_Video_AR_Full, FrameMain::OnSetARFull)
|
|
EVT_MENU(Menu_Video_AR_Wide, FrameMain::OnSetARWide)
|
|
EVT_MENU(Menu_Video_AR_235, FrameMain::OnSetAR235)
|
|
EVT_MENU(Menu_Video_AR_Custom, FrameMain::OnSetARCustom)
|
|
EVT_MENU(Menu_Video_JumpTo, FrameMain::OnJumpTo)
|
|
EVT_MENU(Menu_Video_Select_Visible, FrameMain::OnSelectVisible)
|
|
EVT_MENU(Menu_Video_Detach, FrameMain::OnDetachVideo)
|
|
EVT_MENU(Menu_Video_Dummy, FrameMain::OnDummyVideo)
|
|
EVT_MENU(Menu_Video_Overscan, FrameMain::OnOverscan)
|
|
EVT_MENU(Menu_Video_Details, FrameMain::OnOpenVideoDetails)
|
|
|
|
EVT_MENU(Menu_Audio_Open_File, FrameMain::OnOpenAudio)
|
|
EVT_MENU(Menu_Audio_Open_From_Video, FrameMain::OnOpenAudioFromVideo)
|
|
EVT_MENU(Menu_Audio_Close, FrameMain::OnCloseAudio)
|
|
#ifdef _DEBUG
|
|
EVT_MENU(Menu_Audio_Open_Dummy, FrameMain::OnOpenDummyAudio)
|
|
EVT_MENU(Menu_Audio_Open_Dummy_Noise, FrameMain::OnOpenDummyNoiseAudio)
|
|
#endif
|
|
|
|
EVT_MENU(Menu_Edit_Undo, FrameMain::OnUndo)
|
|
EVT_MENU(Menu_Edit_Redo, FrameMain::OnRedo)
|
|
EVT_MENU(Menu_Edit_Cut, FrameMain::OnCut)
|
|
EVT_MENU(Menu_Edit_Copy, FrameMain::OnCopy)
|
|
EVT_MENU(Menu_Edit_Paste, FrameMain::OnPaste)
|
|
EVT_MENU(Menu_Edit_Paste_Over, FrameMain::OnPasteOver)
|
|
EVT_MENU(Menu_Edit_Find, FrameMain::OnFind)
|
|
EVT_MENU(Menu_Edit_Find_Next, FrameMain::OnFindNext)
|
|
EVT_MENU(Menu_Edit_Replace, FrameMain::OnReplace)
|
|
EVT_MENU(Menu_Edit_Shift, FrameMain::OnShift)
|
|
EVT_MENU(Menu_Edit_Select, FrameMain::OnSelect)
|
|
EVT_MENU(Menu_Edit_Sort, FrameMain::OnSort)
|
|
|
|
EVT_MENU(Menu_Tools_Properties, FrameMain::OnOpenProperties)
|
|
EVT_MENU(Menu_Tools_Styles_Manager, FrameMain::OnOpenStylesManager)
|
|
EVT_MENU(Menu_Tools_Attachments, FrameMain::OnOpenAttachments)
|
|
EVT_MENU(Menu_Tools_Translation, FrameMain::OnOpenTranslation)
|
|
EVT_MENU(Menu_Tools_SpellCheck, FrameMain::OnOpenSpellCheck)
|
|
EVT_MENU(Menu_Tools_Fonts_Collector, FrameMain::OnOpenFontsCollector)
|
|
EVT_MENU(Menu_Tools_Automation, FrameMain::OnOpenAutomation)
|
|
EVT_MENU(Menu_Tools_Styling, FrameMain::OnOpenStylingAssistant)
|
|
EVT_MENU(Menu_Tools_Resample, FrameMain::OnOpenResample)
|
|
EVT_MENU(Menu_Tools_Timing_Processor, FrameMain::OnOpenTimingProcessor)
|
|
EVT_MENU(Menu_Tools_Kanji_Timer, FrameMain::OnOpenKanjiTimer)
|
|
EVT_MENU(Menu_Tools_Options, FrameMain::OnOpenOptions)
|
|
EVT_MENU(Menu_Tools_Log, FrameMain::OnOpenLog)
|
|
EVT_MENU(Menu_Tools_ASSDraw, FrameMain::OnOpenASSDraw)
|
|
|
|
EVT_MENU(Menu_Subs_Snap_Start_To_Video, FrameMain::OnSnapSubsStartToVid)
|
|
EVT_MENU(Menu_Subs_Snap_End_To_Video, FrameMain::OnSnapSubsEndToVid)
|
|
EVT_MENU(Menu_Subs_Snap_Video_To_Start, FrameMain::OnSnapVidToSubsStart)
|
|
EVT_MENU(Menu_Subs_Snap_Video_To_End, FrameMain::OnSnapVidToSubsEnd)
|
|
EVT_MENU(Menu_Video_Snap_To_Scene, FrameMain::OnSnapToScene)
|
|
EVT_MENU(Menu_Video_Shift_To_Frame, FrameMain::OnShiftToFrame)
|
|
|
|
EVT_MENU(Menu_Help_Contents, FrameMain::OnContents)
|
|
EVT_MENU(Menu_Help_Website, FrameMain::OnWebsite)
|
|
EVT_MENU(Menu_Help_Forums, FrameMain::OnForums)
|
|
EVT_MENU(Menu_Help_BugTracker, FrameMain::OnBugTracker)
|
|
EVT_MENU(Menu_Help_IRCChannel, FrameMain::OnIRCChannel)
|
|
EVT_MENU(Menu_Help_Check_Updates, FrameMain::OnCheckUpdates)
|
|
EVT_MENU(Menu_Help_About, FrameMain::OnAbout)
|
|
|
|
EVT_MENU(Menu_View_Language, FrameMain::OnChooseLanguage)
|
|
EVT_MENU(Menu_View_Associations, FrameMain::OnPickAssociations)
|
|
EVT_MENU(Menu_View_Standard, FrameMain::OnViewStandard)
|
|
EVT_MENU(Menu_View_Audio, FrameMain::OnViewAudio)
|
|
EVT_MENU(Menu_View_Video, FrameMain::OnViewVideo)
|
|
EVT_MENU(Menu_View_Subs, FrameMain::OnViewSubs)
|
|
|
|
EVT_MENU(Video_Prev_Frame,FrameMain::OnPrevFrame)
|
|
EVT_MENU(Video_Next_Frame,FrameMain::OnNextFrame)
|
|
EVT_MENU(Video_Focus_Seek,FrameMain::OnFocusSeek)
|
|
EVT_MENU(Grid_Next_Line,FrameMain::OnNextLine)
|
|
EVT_MENU(Grid_Prev_Line,FrameMain::OnPrevLine)
|
|
EVT_MENU(Grid_Toggle_Tags,FrameMain::OnToggleTags)
|
|
EVT_MENU(Edit_Box_Commit,FrameMain::OnEditBoxCommit)
|
|
|
|
EVT_MENU(Medusa_Play, FrameMain::OnMedusaPlay)
|
|
EVT_MENU(Medusa_Stop, FrameMain::OnMedusaStop)
|
|
EVT_MENU(Medusa_Play_After, FrameMain::OnMedusaPlayAfter)
|
|
EVT_MENU(Medusa_Play_Before, FrameMain::OnMedusaPlayBefore)
|
|
EVT_MENU(Medusa_Next, FrameMain::OnMedusaNext)
|
|
EVT_MENU(Medusa_Prev, FrameMain::OnMedusaPrev)
|
|
EVT_MENU(Medusa_Shift_Start_Forward, FrameMain::OnMedusaShiftStartForward)
|
|
EVT_MENU(Medusa_Shift_Start_Back, FrameMain::OnMedusaShiftStartBack)
|
|
EVT_MENU(Medusa_Shift_End_Forward, FrameMain::OnMedusaShiftEndForward)
|
|
EVT_MENU(Medusa_Shift_End_Back, FrameMain::OnMedusaShiftEndBack)
|
|
EVT_MENU(Medusa_Enter, FrameMain::OnMedusaEnter)
|
|
|
|
#ifdef __WXMAC__
|
|
EVT_MENU(wxID_ABOUT, FrameMain::OnAbout)
|
|
EVT_MENU(wxID_EXIT, FrameMain::OnExit)
|
|
#endif
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
/// @brief Redirect grid events to grid
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnGridEvent (wxCommandEvent &event) {
|
|
SubsBox->GetEventHandler()->ProcessEvent(event);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Rebuild recent list
|
|
/// @param listName
|
|
/// @param menu
|
|
/// @param startID
|
|
///
|
|
void FrameMain::RebuildRecentList(wxString listName,wxMenu *menu,int startID) {
|
|
// Wipe previous list
|
|
int count = (int)menu->GetMenuItemCount();
|
|
for (int i=count;--i>=0;) {
|
|
menu->Destroy(menu->FindItemByPosition(i));
|
|
}
|
|
|
|
// Rebuild
|
|
int added = 0;
|
|
wxString n;
|
|
wxArrayString entries = Options.GetRecentList(listName);
|
|
for (size_t i=0;i<entries.Count();i++) {
|
|
n = wxString::Format(_T("%i"),i+1);
|
|
if (i < 9) n = _T("&") + n;
|
|
wxFileName shortname(entries[i]);
|
|
wxString filename = shortname.GetFullName();
|
|
menu->Append(startID+i,n + _T(" ") + filename);
|
|
added++;
|
|
}
|
|
|
|
// Nothing added, add an empty placeholder
|
|
if (added == 0) menu->Append(startID,_("Empty"))->Enable(false);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Menu is being opened
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMenuOpen (wxMenuEvent &event) {
|
|
// Get menu
|
|
MenuBar->Freeze();
|
|
wxMenu *curMenu = event.GetMenu();
|
|
|
|
// File menu
|
|
if (curMenu == fileMenu) {
|
|
// Rebuild recent
|
|
RebuildRecentList(_T("Recent sub"),RecentSubs,Menu_File_Recent);
|
|
}
|
|
|
|
// View menu
|
|
else if (curMenu == viewMenu) {
|
|
// Flags
|
|
bool aud = audioBox->audioDisplay->loaded;
|
|
bool vid = VideoContext::Get()->IsLoaded();
|
|
|
|
// Set states
|
|
MenuBar->Enable(Menu_View_Audio,aud);
|
|
MenuBar->Enable(Menu_View_Video,vid);
|
|
MenuBar->Enable(Menu_View_Standard,aud && vid);
|
|
|
|
// Select option
|
|
if (!showVideo && !showAudio) MenuBar->Check(Menu_View_Subs,true);
|
|
else if (showVideo && !showAudio) MenuBar->Check(Menu_View_Video,true);
|
|
else if (showAudio && showVideo) MenuBar->Check(Menu_View_Standard,true);
|
|
else MenuBar->Check(Menu_View_Audio,true);
|
|
}
|
|
|
|
// Video menu
|
|
else if (curMenu == videoMenu) {
|
|
bool state = VideoContext::Get()->IsLoaded();
|
|
|
|
// Set states
|
|
MenuBar->Enable(Menu_Video_JumpTo,state);
|
|
MenuBar->Enable(Menu_Subs_Snap_Video_To_Start,state);
|
|
MenuBar->Enable(Menu_Subs_Snap_Video_To_End,state);
|
|
MenuBar->Enable(Menu_View_Zoom,state);
|
|
MenuBar->Enable(Menu_View_Zoom_50,state);
|
|
MenuBar->Enable(Menu_View_Zoom_100,state);
|
|
MenuBar->Enable(Menu_View_Zoom_200,state);
|
|
MenuBar->Enable(Menu_File_Close_Video,state);
|
|
MenuBar->Enable(Menu_Video_AR,state);
|
|
MenuBar->Enable(Menu_Video_AR_Default,state);
|
|
MenuBar->Enable(Menu_Video_AR_Full,state);
|
|
MenuBar->Enable(Menu_Video_AR_Wide,state);
|
|
MenuBar->Enable(Menu_Video_AR_235,state);
|
|
MenuBar->Enable(Menu_Video_AR_Custom,state);
|
|
MenuBar->Enable(Menu_Video_Detach,state && !detachedVideo);
|
|
MenuBar->Enable(Menu_File_Save_VFR,VFR_Output.GetFrameRateType() == VFR);
|
|
MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.GetFrameRateType() == VFR);
|
|
MenuBar->Enable(Menu_Video_Close_Keyframes,VideoContext::Get()->OverKeyFramesLoaded());
|
|
MenuBar->Enable(Menu_Video_Save_Keyframes,VideoContext::Get()->KeyFramesLoaded());
|
|
MenuBar->Enable(Menu_Video_Details,state);
|
|
MenuBar->Enable(Menu_Video_Overscan,state);
|
|
|
|
// Set AR radio
|
|
int arType = VideoContext::Get()->GetAspectRatioType();
|
|
MenuBar->Check(Menu_Video_AR_Default,false);
|
|
MenuBar->Check(Menu_Video_AR_Full,false);
|
|
MenuBar->Check(Menu_Video_AR_Wide,false);
|
|
MenuBar->Check(Menu_Video_AR_235,false);
|
|
MenuBar->Check(Menu_Video_AR_Custom,false);
|
|
switch (arType) {
|
|
case 0: MenuBar->Check(Menu_Video_AR_Default,true); break;
|
|
case 1: MenuBar->Check(Menu_Video_AR_Full,true); break;
|
|
case 2: MenuBar->Check(Menu_Video_AR_Wide,true); break;
|
|
case 3: MenuBar->Check(Menu_Video_AR_235,true); break;
|
|
case 4: MenuBar->Check(Menu_Video_AR_Custom,true); break;
|
|
}
|
|
|
|
// Set overscan mask
|
|
MenuBar->Check(Menu_Video_Overscan,Options.AsBool(_T("Show Overscan Mask")));
|
|
|
|
// Rebuild recent lists
|
|
RebuildRecentList(_T("Recent vid"),RecentVids,Menu_Video_Recent);
|
|
RebuildRecentList(_T("Recent timecodes"),RecentTimecodes,Menu_Timecodes_Recent);
|
|
RebuildRecentList(_T("Recent Keyframes"),RecentKeyframes,Menu_Keyframes_Recent);
|
|
}
|
|
|
|
// Audio menu
|
|
else if (curMenu == audioMenu) {
|
|
bool state = audioBox->loaded;
|
|
bool vidstate = VideoContext::Get()->IsLoaded();
|
|
|
|
MenuBar->Enable(Menu_Audio_Open_From_Video,vidstate);
|
|
MenuBar->Enable(Menu_Audio_Close,state);
|
|
|
|
// Rebuild recent
|
|
RebuildRecentList(_T("Recent aud"),RecentAuds,Menu_Audio_Recent);
|
|
}
|
|
|
|
// Subtitles menu
|
|
else if (curMenu == subtitlesMenu) {
|
|
// Variables
|
|
bool continuous;
|
|
wxArrayInt sels = SubsBox->GetSelection(&continuous);
|
|
int count = sels.Count();
|
|
bool state,state2;
|
|
|
|
// Entries
|
|
state = count > 0;
|
|
MenuBar->Enable(MENU_INSERT_BEFORE,state);
|
|
MenuBar->Enable(MENU_INSERT_AFTER,state);
|
|
MenuBar->Enable(MENU_SPLIT_BY_KARAOKE,state);
|
|
MenuBar->Enable(MENU_DELETE,state);
|
|
state2 = count > 0 && VideoContext::Get()->IsLoaded();
|
|
MenuBar->Enable(MENU_INSERT_BEFORE_VIDEO,state2);
|
|
MenuBar->Enable(MENU_INSERT_AFTER_VIDEO,state2);
|
|
MenuBar->Enable(Menu_Subtitles_Insert,state);
|
|
state = count > 0 && continuous;
|
|
MenuBar->Enable(MENU_DUPLICATE,state);
|
|
state = count > 0 && continuous && VFR_Output.IsLoaded();
|
|
MenuBar->Enable(MENU_DUPLICATE_NEXT_FRAME,state);
|
|
state = count == 2;
|
|
MenuBar->Enable(MENU_SWAP,state);
|
|
state = count >= 2 && continuous;
|
|
MenuBar->Enable(MENU_JOIN_CONCAT,state);
|
|
MenuBar->Enable(MENU_JOIN_REPLACE,state);
|
|
MenuBar->Enable(MENU_JOIN_AS_KARAOKE,state);
|
|
MenuBar->Enable(Menu_Subtitles_Join,state);
|
|
state = (count == 2 || count == 3) && continuous;
|
|
MenuBar->Enable(MENU_RECOMBINE,state);
|
|
}
|
|
|
|
// Timing menu
|
|
else if (curMenu == timingMenu) {
|
|
// Variables
|
|
bool continuous;
|
|
wxArrayInt sels = SubsBox->GetSelection(&continuous);
|
|
int count = sels.Count();
|
|
|
|
// Video related
|
|
bool state = VideoContext::Get()->IsLoaded();
|
|
MenuBar->Enable(Menu_Subs_Snap_Start_To_Video,state);
|
|
MenuBar->Enable(Menu_Subs_Snap_End_To_Video,state);
|
|
MenuBar->Enable(Menu_Video_Snap_To_Scene,state);
|
|
MenuBar->Enable(Menu_Video_Shift_To_Frame,state);
|
|
|
|
// Other
|
|
state = count >= 2 && continuous;
|
|
MenuBar->Enable(MENU_ADJOIN,state);
|
|
MenuBar->Enable(MENU_ADJOIN2,state);
|
|
}
|
|
|
|
// Edit menu
|
|
else if (curMenu == editMenu) {
|
|
// Undo state
|
|
editMenu->Remove(Menu_Edit_Undo);
|
|
editMenu->Remove(Menu_Edit_Redo);
|
|
AppendBitmapMenuItem(editMenu,Menu_Edit_Undo, wxString::Format(_T("%s %s\t%s"), _("&Undo"), AssFile::GetUndoDescription().c_str(), Hotkeys.GetText(_T("Undo")).c_str()), _("Undoes last action"),GETIMAGE(undo_button_16),0)->Enable(!AssFile::IsUndoStackEmpty());
|
|
AppendBitmapMenuItem(editMenu,Menu_Edit_Redo, wxString::Format(_T("%s %s\t%s"), _("&Redo"), AssFile::GetRedoDescription().c_str(), Hotkeys.GetText(_T("Redo")).c_str()), _("Redoes last action"),GETIMAGE(redo_button_16),1)->Enable(!AssFile::IsRedoStackEmpty());
|
|
|
|
// Copy/cut/paste
|
|
wxArrayInt sels = SubsBox->GetSelection();
|
|
bool can_copy = (sels.Count() > 0);
|
|
|
|
bool can_paste = true;
|
|
if (wxTheClipboard->Open()) {
|
|
can_paste = wxTheClipboard->IsSupported(wxDF_TEXT);
|
|
wxTheClipboard->Close();
|
|
}
|
|
|
|
MenuBar->Enable(Menu_Edit_Cut,can_copy);
|
|
MenuBar->Enable(Menu_Edit_Copy,can_copy);
|
|
MenuBar->Enable(Menu_Edit_Paste,can_paste);
|
|
MenuBar->Enable(Menu_Edit_Paste_Over,can_copy&&can_paste);
|
|
}
|
|
|
|
// Automation menu
|
|
#ifdef WITH_AUTOMATION
|
|
else if (curMenu == automationMenu) {
|
|
// Remove old macro items
|
|
for (unsigned int i = 0; i < activeMacroItems.size(); i++) {
|
|
wxMenu *p = 0;
|
|
wxMenuItem *it = MenuBar->FindItem(Menu_Automation_Macro + i, &p);
|
|
if (it)
|
|
p->Delete(it);
|
|
}
|
|
activeMacroItems.clear();
|
|
|
|
// Add new ones
|
|
int added = 0;
|
|
added += AddMacroMenuItems(automationMenu, wxGetApp().global_scripts->GetMacros());
|
|
added += AddMacroMenuItems(automationMenu, local_scripts->GetMacros());
|
|
|
|
// If none were added, show a ghosted notice
|
|
if (added == 0) {
|
|
automationMenu->Append(Menu_Automation_Macro, _("No Automation macros loaded"))->Enable(false);
|
|
activeMacroItems.push_back(0);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
MenuBar->Thaw();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Macro menu creation helper
|
|
/// @param menu
|
|
/// @param macros
|
|
/// @return
|
|
///
|
|
int FrameMain::AddMacroMenuItems(wxMenu *menu, const std::vector<Automation4::FeatureMacro*> ¯os) {
|
|
#ifdef WITH_AUTOMATION
|
|
if (macros.empty()) {
|
|
return 0;
|
|
}
|
|
|
|
int id = activeMacroItems.size();;
|
|
for (std::vector<Automation4::FeatureMacro*>::const_iterator i = macros.begin(); i != macros.end(); ++i) {
|
|
wxMenuItem * m = menu->Append(Menu_Automation_Macro + id, (*i)->GetName(), (*i)->GetDescription());
|
|
m->Enable((*i)->Validate(SubsBox->ass, SubsBox->GetAbsoluteSelection(), SubsBox->GetFirstSelRow()));
|
|
activeMacroItems.push_back(*i);
|
|
id++;
|
|
}
|
|
|
|
return macros.size();
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open recent subs menu entry
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenRecentSubs(wxCommandEvent &event) {
|
|
int number = event.GetId()-Menu_File_Recent;
|
|
wxString key = _T("Recent sub #") + wxString::Format(_T("%i"),number+1);
|
|
LoadSubtitles(Options.AsText(key));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open recent video menu entry
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenRecentVideo(wxCommandEvent &event) {
|
|
int number = event.GetId()-Menu_Video_Recent;
|
|
wxString key = _T("Recent vid #") + wxString::Format(_T("%i"),number+1);
|
|
LoadVideo(Options.AsText(key));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open recent timecodes entry
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenRecentTimecodes(wxCommandEvent &event) {
|
|
int number = event.GetId()-Menu_Timecodes_Recent;
|
|
wxString key = _T("Recent timecodes #") + wxString::Format(_T("%i"),number+1);
|
|
LoadVFR(Options.AsText(key));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open recent Keyframes entry
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenRecentKeyframes(wxCommandEvent &event) {
|
|
int number = event.GetId()-Menu_Keyframes_Recent;
|
|
wxString key = _T("Recent Keyframes #") + wxString::Format(_T("%i"),number+1);
|
|
KeyFrameFile::Load(Options.AsText(key));
|
|
videoBox->videoSlider->Refresh();
|
|
audioBox->audioDisplay->Update();
|
|
Refresh();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open recent audio menu entry
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenRecentAudio(wxCommandEvent &event) {
|
|
int number = event.GetId()-Menu_Audio_Recent;
|
|
wxString key = _T("Recent aud #") + wxString::Format(_T("%i"),number+1);
|
|
LoadAudio(Options.AsText(key));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open new Window
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
|
RestartAegisub();
|
|
//wxStandardPaths stand;
|
|
//wxExecute(stand.GetExecutablePath());
|
|
}
|
|
|
|
|
|
|
|
/// @brief Exit
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnExit(wxCommandEvent& WXUNUSED(event)) {
|
|
Close();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open about box
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnAbout(wxCommandEvent &event) {
|
|
AboutScreen About(this);
|
|
About.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open check updates
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCheckUpdates(wxCommandEvent &event) {
|
|
DialogVersionCheck *check = new DialogVersionCheck(this,false);
|
|
(void)check;
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open help topics
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnContents(wxCommandEvent& WXUNUSED(event)) {
|
|
OpenHelp(_T(""));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open website
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnWebsite(wxCommandEvent& WXUNUSED(event)) {
|
|
AegisubApp::OpenURL(_T("http://www.aegisub.net/"));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open forums
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnForums(wxCommandEvent& WXUNUSED(event)) {
|
|
AegisubApp::OpenURL(_T("http://forum.aegisub.net/"));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open bugtracker
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnBugTracker(wxCommandEvent& WXUNUSED(event)) {
|
|
if (wxGetMouseState().CmdDown()) {
|
|
if (wxGetMouseState().ShiftDown()) {
|
|
wxMessageBox(_T("Now crashing with an access violation..."));
|
|
for (char *foo = (char*)0;;) *foo++ = 42;
|
|
}
|
|
else {
|
|
wxMessageBox(_T("Now crashing with an unhandled exception..."));
|
|
throw this;
|
|
}
|
|
}
|
|
|
|
AegisubApp::OpenURL(_T("http://devel.aegisub.org/"));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open IRC channel
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnIRCChannel(wxCommandEvent& WXUNUSED(event)) {
|
|
AegisubApp::OpenURL(_T("irc://irc.rizon.net/aegisub"));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Play video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnVideoPlay(wxCommandEvent &event) {
|
|
VideoContext::Get()->Play();
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief Open video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenVideo(wxCommandEvent& WXUNUSED(event)) {
|
|
wxString path = Options.AsText(_T("Last open video path"));
|
|
wxString str = wxString(_("Video Formats")) + _T(" (*.avi,*.mkv,*.mp4,*.avs,*.d2v,*.ogm,*.mpeg,*.mpg,*.vob)|*.avi;*.avs;*.d2v;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg;*.vob|")
|
|
+ _("All Files") + _T(" (*.*)|*.*");
|
|
wxString filename = wxFileSelector(_("Open video file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
if (!filename.empty()) {
|
|
LoadVideo(filename);
|
|
Options.SetText(_T("Last open video path"), filename);
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Close video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCloseVideo(wxCommandEvent& WXUNUSED(event)) {
|
|
LoadVideo(_T(""));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Audio
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenAudio (wxCommandEvent& WXUNUSED(event)) {
|
|
wxString path = Options.AsText(_T("Last open audio path"));
|
|
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|")
|
|
+ _("Video Formats") + _T(" (*.avi,*.mkv,*.ogm,*.mpg,*.mpeg)|*.avi;*.mkv;*.ogm;*.mp4;*.mpeg;*.mpg|")
|
|
+ _("All files") + _T(" (*.*)|*.*");
|
|
wxString filename = wxFileSelector(_("Open audio file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
if (!filename.empty()) {
|
|
LoadAudio(filename);
|
|
Options.SetText(_T("Last open audio path"), filename);
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenAudioFromVideo (wxCommandEvent& WXUNUSED(event)) {
|
|
LoadAudio(_T(""),true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCloseAudio (wxCommandEvent& WXUNUSED(event)) {
|
|
LoadAudio(_T(""));
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenDummyAudio (wxCommandEvent& WXUNUSED(event)) {
|
|
LoadAudio(_T("?dummy"));
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenDummyNoiseAudio (wxCommandEvent& WXUNUSED(event)) {
|
|
LoadAudio(_T("?noise"));
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/// @brief Open subtitles
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenSubtitles(wxCommandEvent& WXUNUSED(event)) {
|
|
wxString path = Options.AsText(_T("Last open subtitles path"));
|
|
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
if (!filename.empty()) {
|
|
LoadSubtitles(filename);
|
|
wxFileName filepath(filename);
|
|
Options.SetText(_T("Last open subtitles path"), filepath.GetPath());
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open subtitles with specific charset
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenSubtitlesCharset(wxCommandEvent& WXUNUSED(event)) {
|
|
// Initialize charsets
|
|
wxArrayString choices = AegisubCSConv::GetEncodingsList();
|
|
wxString path = Options.AsText(_T("Last open subtitles path"));
|
|
|
|
// Get options and load
|
|
wxString filename = wxFileSelector(_("Open subtitles file"),path,_T(""),_T(""),AssFile::GetWildcardList(0),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
if (!filename.empty()) {
|
|
wxString charset = wxGetSingleChoice(_("Choose charset code:"), _("Charset"),choices,this,-1, -1,true,250,200);
|
|
if (!charset.empty()) {
|
|
LoadSubtitles(filename,charset);
|
|
}
|
|
Options.SetText(_T("Last open subtitles path"), filename);
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Save subtitles as
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSaveSubtitlesAs(wxCommandEvent& WXUNUSED(event)) {
|
|
SaveSubtitles(true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Save subtitles
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSaveSubtitles(wxCommandEvent& WXUNUSED(event)) {
|
|
SaveSubtitles(false);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Save subtitles with specific charset
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSaveSubtitlesCharset(wxCommandEvent& WXUNUSED(event)) {
|
|
SaveSubtitles(true,true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Close subtitles
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnNewSubtitles(wxCommandEvent& WXUNUSED(event)) {
|
|
LoadSubtitles(_T(""));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Export subtitles
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnExportSubtitles(wxCommandEvent & WXUNUSED(event)) {
|
|
#ifdef WITH_AUTOMATION
|
|
int autoreload = Options.AsInt(_T("Automation Autoreload Mode"));
|
|
if (autoreload & 1) {
|
|
// Local scripts
|
|
const std::vector<Automation4::Script*> scripts = local_scripts->GetScripts();
|
|
for (size_t i = 0; i < scripts.size(); ++i) {
|
|
try {
|
|
scripts[i]->Reload();
|
|
}
|
|
catch (const wchar_t *e) {
|
|
wxLogError(_T("Error while reloading Automation scripts before export: %s"), e);
|
|
}
|
|
catch (...) {
|
|
wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
|
|
}
|
|
}
|
|
}
|
|
if (autoreload & 2) {
|
|
// Global scripts
|
|
wxGetApp().global_scripts->Reload();
|
|
}
|
|
#endif
|
|
|
|
DialogExport exporter(this);
|
|
exporter.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open VFR tags
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenVFR(wxCommandEvent &event) {
|
|
wxString path = Options.AsText(_T("Last open timecodes path"));
|
|
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|")
|
|
+ _("All Files") + _T(" (*.*)|*.*");
|
|
wxString filename = wxFileSelector(_("Open timecodes file"),path,_T(""),_T(""),str,wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
if (!filename.empty()) {
|
|
LoadVFR(filename);
|
|
Options.SetText(_T("Last open timecodes path"), filename);
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Save VFR tags
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSaveVFR(wxCommandEvent &event) {
|
|
wxString path = Options.AsText(_T("Last open timecodes path"));
|
|
wxString str = wxString(_("All Supported Types")) + _T("(*.txt)|*.txt|")
|
|
+ _("All Files") + _T(" (*.*)|*.*");
|
|
wxString filename = wxFileSelector(_("Save timecodes file"),path,_T(""),_T(""),str,wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
|
if (!filename.empty()) {
|
|
SaveVFR(filename);
|
|
Options.SetText(_T("Last open timecodes path"), filename);
|
|
Options.Save();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief Close VFR tags
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCloseVFR(wxCommandEvent &event) {
|
|
LoadVFR(_T(""));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open keyframes
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnOpenKeyframes (wxCommandEvent &event) {
|
|
// Pick file
|
|
wxString path = Options.AsText(_T("Last open keyframes path"));
|
|
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);
|
|
if (filename.IsEmpty()) return;
|
|
Options.SetText(_T("Last open keyframes path"),filename);
|
|
Options.Save();
|
|
|
|
// Load
|
|
KeyFrameFile::Load(filename);
|
|
videoBox->videoSlider->Refresh();
|
|
audioBox->audioDisplay->Update();
|
|
Refresh();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Close keyframes
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCloseKeyframes (wxCommandEvent &event) {
|
|
VideoContext::Get()->CloseOverKeyFrames();
|
|
videoBox->videoSlider->Refresh();
|
|
audioBox->audioDisplay->Update();
|
|
Refresh();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Save keyframes
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnSaveKeyframes (wxCommandEvent &event) {
|
|
// Pick file
|
|
wxString path = Options.AsText(_T("Last open keyframes path"));
|
|
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);
|
|
if (filename.IsEmpty()) return;
|
|
Options.SetText(_T("Last open keyframes path"),filename);
|
|
Options.Save();
|
|
|
|
// Save
|
|
KeyFrameFile::Save(filename);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Zoom levels
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetZoom50(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
videoBox->videoDisplay->zoomBox->SetSelection(3);
|
|
videoBox->videoDisplay->SetZoomPos(3);
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetZoom100(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
videoBox->videoDisplay->zoomBox->SetSelection(7);
|
|
videoBox->videoDisplay->SetZoomPos(7);
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetZoom200(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
videoBox->videoDisplay->zoomBox->SetSelection(15);
|
|
videoBox->videoDisplay->SetZoomPos(15);
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnZoomIn (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
videoBox->videoDisplay->zoomBox->SetSelection(videoBox->videoDisplay->zoomBox->GetSelection()+1);
|
|
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnZoomOut (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
int selTo = videoBox->videoDisplay->zoomBox->GetSelection()-1;
|
|
if (selTo < 0) selTo = 0;
|
|
videoBox->videoDisplay->zoomBox->SetSelection(selTo);
|
|
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetZoom(wxCommandEvent &event) {
|
|
videoBox->videoDisplay->SetZoomPos(videoBox->videoDisplay->zoomBox->GetSelection());
|
|
}
|
|
|
|
|
|
|
|
/// @brief Detach video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnDetachVideo(wxCommandEvent &event) {
|
|
DetachVideo();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Use dummy video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnDummyVideo (wxCommandEvent &event) {
|
|
wxString fn;
|
|
if (DialogDummyVideo::CreateDummyVideo(this, fn)) {
|
|
LoadVideo(fn);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Overscan toggle
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOverscan (wxCommandEvent &event) {
|
|
Options.SetBool(_T("Show overscan mask"),event.IsChecked());
|
|
Options.Save();
|
|
VideoContext::Get()->Stop();
|
|
videoBox->videoDisplay->Render();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Show video details
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenVideoDetails (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
DialogVideoDetails videodetails(this);
|
|
videodetails.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open jump to dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnJumpTo(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
DialogJumpTo JumpTo(this);
|
|
JumpTo.ShowModal();
|
|
videoBox->videoSlider->SetFocus();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open shift dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnShift(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
DialogShiftTimes Shift(this,SubsBox);
|
|
Shift.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open properties
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenProperties (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
DialogProperties Properties(this);
|
|
int res = Properties.ShowModal();
|
|
if (res) {
|
|
SubsBox->CommitChanges();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open styles manager
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenStylesManager(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
DialogStyleManager StyleManager(this,SubsBox);
|
|
StyleManager.ShowModal();
|
|
EditBox->UpdateGlobals();
|
|
SubsBox->CommitChanges();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open attachments
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenAttachments(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
DialogAttachments attachments(this);
|
|
attachments.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open translation assistant
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenTranslation(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
int start = SubsBox->GetFirstSelRow();
|
|
if (start == -1) start = 0;
|
|
DialogTranslation Trans(this,AssFile::top,SubsBox,start,true);
|
|
Trans.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Spell Checker
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenSpellCheck (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
new DialogSpellChecker(this);
|
|
//DialogSpellChecker *spell =
|
|
//spell->ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Fonts Collector
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenFontsCollector (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
DialogFontsCollector Collector(this);
|
|
Collector.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Resolution Resampler
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenResample (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
DialogResample diag(this, SubsBox);
|
|
diag.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Timing post-processor dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenTimingProcessor (wxCommandEvent &event) {
|
|
DialogTimingProcessor timing(this,SubsBox);
|
|
timing.ShowModal();
|
|
}
|
|
|
|
/// @brief Open Kanji Timer dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenKanjiTimer (wxCommandEvent &event) {
|
|
DialogKanjiTimer kanjitimer(this,SubsBox);
|
|
kanjitimer.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Options dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenOptions (wxCommandEvent &event) {
|
|
try {
|
|
DialogOptions options(this);
|
|
options.ShowModal();
|
|
}
|
|
catch (const wxChar *e) {
|
|
wxLogError(e);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open log window
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenLog (wxCommandEvent &event) {
|
|
LogWindow->Show(true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Launch ASSDraw
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenASSDraw (wxCommandEvent &event) {
|
|
wxExecute(_T("\"") + StandardPaths::DecodePath(_T("?data/ASSDraw3.exe")) + _T("\""));
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open Automation
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenAutomation (wxCommandEvent &event) {
|
|
#ifdef WITH_AUTOMATION
|
|
#ifdef __APPLE__
|
|
if (wxGetMouseState().CmdDown()) {
|
|
#else
|
|
if (wxGetMouseState().ControlDown()) {
|
|
#endif
|
|
wxGetApp().global_scripts->Reload();
|
|
if (wxGetMouseState().ShiftDown()) {
|
|
const std::vector<Automation4::Script*> scripts = local_scripts->GetScripts();
|
|
for (size_t i = 0; i < scripts.size(); ++i) {
|
|
try {
|
|
scripts[i]->Reload();
|
|
}
|
|
catch (const wchar_t *e) {
|
|
wxLogError(e);
|
|
}
|
|
catch (...) {
|
|
wxLogError(_T("An unknown error occurred reloading Automation script '%s'."), scripts[i]->GetName().c_str());
|
|
}
|
|
}
|
|
|
|
StatusTimeout(_("Reloaded all Automation scripts"));
|
|
}
|
|
else {
|
|
StatusTimeout(_("Reloaded autoload Automation scripts"));
|
|
}
|
|
}
|
|
else {
|
|
VideoContext::Get()->Stop();
|
|
DialogAutomation dlg(this, local_scripts);
|
|
dlg.ShowModal();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/// @brief General handler for all Automation-generated menu items
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnAutomationMacro (wxCommandEvent &event) {
|
|
#ifdef WITH_AUTOMATION
|
|
SubsBox->BeginBatch();
|
|
// First get selection data
|
|
// This much be done before clearing the maps, since selection data are lost during that
|
|
std::vector<int> selected_lines = SubsBox->GetAbsoluteSelection();
|
|
int first_sel = SubsBox->GetFirstSelRow();
|
|
// Clear all maps from the subs grid before running the macro
|
|
// The stuff done by the macro might invalidate some of the iterators held by the grid, which will cause great crashing
|
|
SubsBox->Clear();
|
|
// Run the macro...
|
|
activeMacroItems[event.GetId()-Menu_Automation_Macro]->Process(SubsBox->ass, selected_lines, first_sel, this);
|
|
// Have the grid update its maps, this properly refreshes it to reflect the changed subs
|
|
SubsBox->UpdateMaps();
|
|
SubsBox->SetSelectionFromAbsolute(selected_lines);
|
|
SubsBox->CommitChanges(true, false);
|
|
SubsBox->AdjustScrollbar();
|
|
SubsBox->EndBatch();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/// @brief Snap subs to video
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSnapSubsStartToVid (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
wxArrayInt sel = SubsBox->GetSelection();
|
|
if (sel.Count() > 0) {
|
|
wxCommandEvent dummy;
|
|
SubsBox->SetSubsToVideo(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSnapSubsEndToVid (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
wxArrayInt sel = SubsBox->GetSelection();
|
|
if (sel.Count() > 0) {
|
|
wxCommandEvent dummy;
|
|
SubsBox->SetSubsToVideo(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Jump video to subs
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSnapVidToSubsStart (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
wxArrayInt sel = SubsBox->GetSelection();
|
|
if (sel.Count() > 0) {
|
|
wxCommandEvent dummy;
|
|
SubsBox->SetVideoToSubs(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSnapVidToSubsEnd (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
wxArrayInt sel = SubsBox->GetSelection();
|
|
if (sel.Count() > 0) {
|
|
wxCommandEvent dummy;
|
|
SubsBox->SetVideoToSubs(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Snap to scene
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSnapToScene (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
// Get frames
|
|
wxArrayInt sel = SubsBox->GetSelection();
|
|
int curFrame = VideoContext::Get()->GetFrameN();
|
|
int prev = 0;
|
|
int next = 0;
|
|
int frame = 0;
|
|
wxArrayInt keyframes = VideoContext::Get()->GetKeyFrames();
|
|
size_t n = keyframes.Count();
|
|
bool found = false;
|
|
for (size_t i=0;i<n;i++) {
|
|
frame = keyframes[i];
|
|
|
|
if (frame == curFrame) {
|
|
prev = frame;
|
|
if (i < n-1) next = keyframes[i+1];
|
|
else next = VideoContext::Get()->GetLength();
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
if (frame > curFrame) {
|
|
if (i != 0) prev = keyframes[i-1];
|
|
else prev = 0;
|
|
next = frame;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Last section?
|
|
if (!found) {
|
|
if (n > 0) prev = keyframes[n-1];
|
|
else prev = 0;
|
|
next = VideoContext::Get()->GetLength();
|
|
}
|
|
|
|
// Get times
|
|
int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
|
|
int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
|
|
AssDialogue *cur;
|
|
|
|
// Update rows
|
|
for (size_t i=0;i<sel.Count();i++) {
|
|
cur = SubsBox->GetDialogue(sel[i]);
|
|
cur->Start.SetMS(start_ms);
|
|
cur->End.SetMS(end_ms);
|
|
cur->UpdateData();
|
|
}
|
|
|
|
// Commit
|
|
SubsBox->editBox->Update(true);
|
|
SubsBox->ass->FlagAsModified(_("snap to scene"));
|
|
SubsBox->CommitChanges();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Shift to frame
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnShiftToFrame (wxCommandEvent &event) {
|
|
if (VideoContext::Get()->IsLoaded()) {
|
|
// Get selection
|
|
wxArrayInt sels = SubsBox->GetSelection();
|
|
size_t n=sels.Count();
|
|
if (n == 0) return;
|
|
|
|
// Get shifting in ms
|
|
AssDialogue *cur = SubsBox->GetDialogue(sels[0]);
|
|
if (!cur) return;
|
|
int shiftBy = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true) - cur->Start.GetMS();
|
|
|
|
// Update
|
|
for (size_t i=0;i<n;i++) {
|
|
cur = SubsBox->GetDialogue(sels[i]);
|
|
if (cur) {
|
|
cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
|
|
cur->End.SetMS(cur->End.GetMS()+shiftBy);
|
|
cur->UpdateData();
|
|
}
|
|
}
|
|
|
|
// Commit
|
|
SubsBox->ass->FlagAsModified(_("shift to frame"));
|
|
SubsBox->CommitChanges();
|
|
SubsBox->editBox->Update(true,false);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Undo
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnUndo(wxCommandEvent& WXUNUSED(event)) {
|
|
// Block if it's on a editbox
|
|
//wxWindow *focused = wxWindow::FindFocus();
|
|
//if (focused && focused->IsKindOf(CLASSINFO(wxTextCtrl))) return;
|
|
|
|
VideoContext::Get()->Stop();
|
|
AssFile::StackPop();
|
|
SubsBox->LoadFromAss(AssFile::top,true);
|
|
AssFile::Popping = false;
|
|
}
|
|
|
|
|
|
|
|
/// @brief Redo
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnRedo(wxCommandEvent& WXUNUSED(event)) {
|
|
VideoContext::Get()->Stop();
|
|
AssFile::StackRedo();
|
|
SubsBox->LoadFromAss(AssFile::top,true);
|
|
AssFile::Popping = false;
|
|
}
|
|
|
|
|
|
|
|
/// @brief Find
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnFind(wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
Search.OpenDialog(false);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Find next
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnFindNext(wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
Search.FindNext();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Find & replace
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnReplace(wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
Search.OpenDialog(true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Change aspect ratio to default
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetARDefault (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
VideoContext::Get()->SetAspectRatio(0);
|
|
SetDisplayMode(-1,-2);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Change aspect ratio to fullscreen
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetARFull (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
VideoContext::Get()->SetAspectRatio(1);
|
|
SetDisplayMode(-1,-2);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Change aspect ratio to widescreen
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetARWide (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
VideoContext::Get()->SetAspectRatio(2);
|
|
SetDisplayMode(-1,-2);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Change aspect ratio to 2:35
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSetAR235 (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
VideoContext::Get()->SetAspectRatio(3);
|
|
SetDisplayMode(-1,-2);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Change aspect ratio to a custom value
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnSetARCustom (wxCommandEvent &event) {
|
|
// Get text
|
|
VideoContext::Get()->Stop();
|
|
|
|
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()));
|
|
if (value.IsEmpty()) return;
|
|
|
|
value.MakeLower();
|
|
|
|
// Process text
|
|
double numval;
|
|
if (value.ToDouble(&numval)) {
|
|
//Nothing to see here, move along
|
|
}
|
|
else {
|
|
double a,b;
|
|
int pos=0;
|
|
bool scale=false;
|
|
|
|
//Why bloat using Contains when we can just check the output of Find?
|
|
pos = value.Find(':');
|
|
if (pos==wxNOT_FOUND) pos = value.Find('/');
|
|
if (pos==wxNOT_FOUND&&value.Contains(_T('x'))) {
|
|
pos = value.Find('x');
|
|
scale=true;
|
|
}
|
|
|
|
if (pos>0) {
|
|
wxString num = value.Left(pos);
|
|
wxString denum = value.Mid(pos+1);
|
|
if (num.ToDouble(&a) && denum.ToDouble(&b) && b!=0) {
|
|
numval = a/b;
|
|
if (scale) videoBox->videoDisplay->SetZoom(b / VideoContext::Get()->GetHeight());
|
|
}
|
|
}
|
|
else numval = 0.0;
|
|
}
|
|
|
|
// Sanity check
|
|
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|wxOK);
|
|
|
|
// Set value
|
|
else {
|
|
VideoContext::Get()->SetAspectRatio(4,numval);
|
|
SetDisplayMode(-1,-1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Window is attempted to be closed
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnCloseWindow (wxCloseEvent &event) {
|
|
// Stop audio and video
|
|
VideoContext::Get()->Stop();
|
|
audioBox->audioDisplay->Stop();
|
|
|
|
// Ask user if he wants to save first
|
|
bool canVeto = event.CanVeto();
|
|
int result = TryToCloseSubs(canVeto);
|
|
|
|
// Store maximization state
|
|
Options.SetBool(_T("Maximized"),IsMaximized());
|
|
Options.Save();
|
|
|
|
// Abort/destroy
|
|
if (canVeto) {
|
|
if (result == wxCANCEL) event.Veto();
|
|
else Destroy();
|
|
}
|
|
else Destroy();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Cut/copy/paste
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnCut (wxCommandEvent &event) {
|
|
if (FindFocus() == EditBox->TextEdit) {
|
|
EditBox->TextEdit->Cut();
|
|
return;
|
|
}
|
|
SubsBox->CutLines(SubsBox->GetSelection());
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnCopy (wxCommandEvent &event) {
|
|
if (FindFocus() == EditBox->TextEdit) {
|
|
EditBox->TextEdit->Copy();
|
|
return;
|
|
}
|
|
SubsBox->CopyLines(SubsBox->GetSelection());
|
|
}
|
|
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnPaste (wxCommandEvent &event) {
|
|
if (FindFocus() == EditBox->TextEdit) {
|
|
EditBox->TextEdit->Paste();
|
|
return;
|
|
}
|
|
SubsBox->PasteLines(SubsBox->GetFirstSelRow());
|
|
}
|
|
|
|
|
|
|
|
/// @brief Paste over
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnPasteOver (wxCommandEvent &event) {
|
|
SubsBox->PasteLines(SubsBox->GetFirstSelRow(),true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Select visible lines
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSelectVisible (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
SubsBox->SelectVisible();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open select dialog
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSelect (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
DialogSelection select(this, SubsBox);
|
|
select.ShowModal();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Sort subtitles
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnSort (wxCommandEvent &event) {
|
|
// Ensure that StartMS is set properly
|
|
AssEntry *curEntry;
|
|
AssDialogue *curDiag;
|
|
int startMS = -1;
|
|
for (std::list<AssEntry*>::iterator cur = AssFile::top->Line.begin(); cur != AssFile::top->Line.end(); cur++) {
|
|
curEntry = *cur;
|
|
curDiag = AssEntry::GetAsDialogue(curEntry);
|
|
if (curDiag) startMS = curDiag->GetStartMS();
|
|
curEntry->SetStartMS(startMS);
|
|
}
|
|
|
|
// Sort
|
|
AssFile::top->Line.sort(LessByPointedToValue<AssEntry>());
|
|
AssFile::top->FlagAsModified(_("sort"));
|
|
SubsBox->UpdateMaps();
|
|
SubsBox->CommitChanges();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Open styling assistant
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnOpenStylingAssistant (wxCommandEvent &event) {
|
|
VideoContext::Get()->Stop();
|
|
if (!stylingAssistant) stylingAssistant = new DialogStyling(this,SubsBox);
|
|
stylingAssistant->Show(true);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Auto backup
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnAutoSave(wxTimerEvent &event) {
|
|
// Auto Save
|
|
try {
|
|
if (AssFile::top->loaded) {
|
|
// Set path
|
|
wxFileName origfile(AssFile::top->filename);
|
|
wxString path = Options.AsText(_T("Auto save path"));
|
|
if (path.IsEmpty()) path = origfile.GetPath();
|
|
wxFileName dstpath(path);
|
|
if (!dstpath.IsAbsolute()) path = StandardPaths::DecodePathMaybeRelative(path, _T("?user/"));
|
|
path += _T("/");
|
|
dstpath.Assign(path);
|
|
if (!dstpath.DirExists()) wxMkdir(path);
|
|
|
|
// Save
|
|
wxString name = origfile.GetName();
|
|
wxString backup = path;
|
|
if (name.IsEmpty()) backup += _T("Untitled.AUTOSAVE.ass");
|
|
else backup += origfile.GetName() + _T(".AUTOSAVE.ass");
|
|
AssFile::top->Save(backup,false,false);
|
|
|
|
// Set status bar
|
|
StatusTimeout(_("File backup saved as \"") + backup + _T("\"."));
|
|
}
|
|
}
|
|
catch (wxString err) {
|
|
StatusTimeout(_T("Exception when attempting to autosave file: ") + err);
|
|
}
|
|
catch (const wchar_t *err) {
|
|
StatusTimeout(_T("Exception when attempting to autosave file: ") + wxString(err));
|
|
}
|
|
catch (...) {
|
|
StatusTimeout(_T("Unhandled exception when attempting to autosave file."));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Clear statusbar
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnStatusClear(wxTimerEvent &event) {
|
|
SetStatusText(_T(""),1);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Key down
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnKeyDown(wxKeyEvent &event) {
|
|
audioBox->audioDisplay->AddPendingEvent(event);
|
|
event.Skip();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Next frame hotkey
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnNextFrame(wxCommandEvent &event) {
|
|
videoBox->videoSlider->NextFrame();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Previous frame hotkey
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnPrevFrame(wxCommandEvent &event) {
|
|
videoBox->videoSlider->PrevFrame();
|
|
}
|
|
|
|
|
|
|
|
/// @brief Toggle focus between seek bar and whatever else
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnFocusSeek(wxCommandEvent &event) {
|
|
wxWindow *curFocus = wxWindow::FindFocus();
|
|
if (curFocus == videoBox->videoSlider) {
|
|
if (PreviousFocus) PreviousFocus->SetFocus();
|
|
}
|
|
else {
|
|
PreviousFocus = curFocus;
|
|
videoBox->videoSlider->SetFocus();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Previous line hotkey
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnPrevLine(wxCommandEvent &event) {
|
|
int next = EditBox->linen-1;
|
|
if (next < 0) return;
|
|
SubsBox->SelectRow(next);
|
|
SubsBox->MakeCellVisible(next,0);
|
|
EditBox->SetToLine(next);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Next line hotkey
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnNextLine(wxCommandEvent &event) {
|
|
int nrows = SubsBox->GetRows();
|
|
int next = EditBox->linen+1;
|
|
if (next >= nrows) return;
|
|
SubsBox->SelectRow(next);
|
|
SubsBox->MakeCellVisible(next,0);
|
|
EditBox->SetToLine(next);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Cycle through tag hiding modes
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnToggleTags(wxCommandEvent &event) {
|
|
// Read value
|
|
int tagMode = Options.AsInt(_T("Grid hide overrides"));
|
|
|
|
// Cycle to next
|
|
if (tagMode < 0 || tagMode > 2) tagMode = 1;
|
|
else {
|
|
tagMode = (tagMode+1)%3;
|
|
}
|
|
|
|
// Show on status bar
|
|
wxString message = _("ASS Override Tag mode set to ");
|
|
if (tagMode == 0) message += _("show full tags.");
|
|
if (tagMode == 1) message += _("simplify tags.");
|
|
if (tagMode == 2) message += _("hide tags.");
|
|
StatusTimeout(message,10000);
|
|
|
|
// Set option
|
|
Options.SetInt(_T("Grid hide overrides"),tagMode);
|
|
Options.Save();
|
|
|
|
// Refresh grid
|
|
SubsBox->Refresh(false);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Commit Edit Box's changes
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnEditBoxCommit(wxCommandEvent &event) {
|
|
// Find focus
|
|
wxWindow *focus = FindFocus();
|
|
if (!focus) return;
|
|
|
|
// Is the text edit
|
|
if (focus == EditBox->TextEdit) {
|
|
EditBox->Commit(true);
|
|
EditBox->Update(true);
|
|
}
|
|
|
|
// Other window
|
|
else {
|
|
//wxKeyEvent keyevent;
|
|
//keyevent.m_keyCode = WXK_RETURN;
|
|
//keyevent.m_controlDown = true;
|
|
//keyevent.SetEventType(wxEVT_KEY_DOWN);
|
|
wxCommandEvent keyevent(wxEVT_COMMAND_TEXT_ENTER,focus->GetId());
|
|
focus->GetEventHandler()->AddPendingEvent(keyevent);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Choose a different language
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnChooseLanguage (wxCommandEvent &event) {
|
|
// Get language
|
|
AegisubApp *app = (AegisubApp*) wxTheApp;
|
|
int old = app->locale.curCode;
|
|
int newCode = app->locale.PickLanguage();
|
|
|
|
// Is OK?
|
|
if (newCode != -1) {
|
|
// Set code
|
|
Options.SetInt(_T("Locale Code"),newCode);
|
|
Options.Save();
|
|
|
|
// Language actually changed?
|
|
if (newCode != old) {
|
|
// Ask to restart program
|
|
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);
|
|
if (result == wxYES) {
|
|
// Restart Aegisub
|
|
if (Close()) {
|
|
RestartAegisub();
|
|
//wxStandardPaths stand;
|
|
//wxExecute(_T("\"") + stand.GetExecutablePath() + _T("\""));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @brief Pick associations
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnPickAssociations(wxCommandEvent &event) {
|
|
#ifdef WIN32
|
|
DialogAssociations diag(NULL);
|
|
diag.ShowModal();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/// @brief View standard
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnViewStandard (wxCommandEvent &event) {
|
|
if (!audioBox->audioDisplay->loaded || !VideoContext::Get()->IsLoaded()) return;
|
|
SetDisplayMode(1,1);
|
|
}
|
|
|
|
|
|
|
|
/// @brief View video
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnViewVideo (wxCommandEvent &event) {
|
|
if (!VideoContext::Get()->IsLoaded()) return;
|
|
SetDisplayMode(1,0);
|
|
}
|
|
|
|
|
|
|
|
/// @brief View audio
|
|
/// @param event
|
|
/// @return
|
|
///
|
|
void FrameMain::OnViewAudio (wxCommandEvent &event) {
|
|
if (!audioBox->audioDisplay->loaded) return;
|
|
SetDisplayMode(0,1);
|
|
}
|
|
|
|
|
|
|
|
/// @brief View subs
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnViewSubs (wxCommandEvent &event) {
|
|
SetDisplayMode(0,0);
|
|
}
|
|
|
|
|
|
|
|
/// @brief Medusa shortcuts
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaPlay(wxCommandEvent &event) {
|
|
int start=0,end=0;
|
|
audioBox->audioDisplay->GetTimesSelection(start,end);
|
|
audioBox->audioDisplay->Play(start,end);
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaStop(wxCommandEvent &event) {
|
|
// Playing, stop
|
|
if (audioBox->audioDisplay->player->IsPlaying()) {
|
|
audioBox->audioDisplay->Stop();
|
|
audioBox->audioDisplay->Refresh();
|
|
}
|
|
|
|
// Otherwise, play the last 500 ms
|
|
else {
|
|
int start=0,end=0;
|
|
audioBox->audioDisplay->GetTimesSelection(start,end);
|
|
audioBox->audioDisplay->Play(end-500,end);
|
|
}
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->curStartMS += 10;
|
|
audioBox->audioDisplay->Update();
|
|
audioBox->audioDisplay->wxWindow::Update();
|
|
audioBox->audioDisplay->UpdateTimeEditCtrls();
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->curStartMS -= 10;
|
|
audioBox->audioDisplay->Update();
|
|
audioBox->audioDisplay->wxWindow::Update();
|
|
audioBox->audioDisplay->UpdateTimeEditCtrls();
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->curEndMS += 10;
|
|
audioBox->audioDisplay->Update();
|
|
audioBox->audioDisplay->wxWindow::Update();
|
|
audioBox->audioDisplay->UpdateTimeEditCtrls();
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->curEndMS -= 10;
|
|
audioBox->audioDisplay->Update();
|
|
audioBox->audioDisplay->wxWindow::Update();
|
|
audioBox->audioDisplay->UpdateTimeEditCtrls();
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaPlayBefore(wxCommandEvent &event) {
|
|
int start=0,end=0;
|
|
audioBox->audioDisplay->GetTimesSelection(start,end);
|
|
audioBox->audioDisplay->Play(start-500,start);
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaPlayAfter(wxCommandEvent &event) {
|
|
int start=0,end=0;
|
|
audioBox->audioDisplay->GetTimesSelection(start,end);
|
|
audioBox->audioDisplay->Play(end,end+500);
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaNext(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->Next(false);
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaPrev(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->Prev(false);
|
|
}
|
|
|
|
/// @brief DOCME
|
|
/// @param event
|
|
///
|
|
void FrameMain::OnMedusaEnter(wxCommandEvent &event) {
|
|
audioBox->audioDisplay->CommitChanges(true);
|
|
}
|
|
|
|
|