Aegisub/aegisub/src/frame_main_events.cpp
Amar Takhar 6ee2f98349 Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
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.
2009-07-29 22:59:22 +00:00

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*> &macros) {
#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);
}