From 0492fae298199f1ffd73187c546bd5d2251baa77 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Sat, 13 Jan 2007 02:22:28 +0000 Subject: [PATCH] Added Dansolo's Kanji Timer code Originally committed to SVN as r781. --- aegisub/ass_dialogue.cpp | 16 ++ aegisub/ass_dialogue.h | 1 + aegisub/dialog_kanji_timer.cpp | 397 +++++++++++++++++++++++++++++++++ aegisub/dialog_kanji_timer.h | 119 ++++++++++ aegisub/frame_main.cpp | 1 + aegisub/frame_main.h | 3 + aegisub/frame_main_events.cpp | 9 +- 7 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 aegisub/dialog_kanji_timer.cpp create mode 100644 aegisub/dialog_kanji_timer.h diff --git a/aegisub/ass_dialogue.cpp b/aegisub/ass_dialogue.cpp index 6baafecd5..8cf1789c2 100644 --- a/aegisub/ass_dialogue.cpp +++ b/aegisub/ass_dialogue.cpp @@ -756,6 +756,19 @@ bool AssDialogue::CollidesWith(AssDialogue *target) { } +//////////////////////// +// Return just the text without any overrides +wxString AssDialogue::GetStrippedText() { + wxString justtext = wxString(_T("")); + bool inCode = false; + + for (int charindex = 0; charindex != Text.Len(); charindex++) { + if (Text[charindex] == '{') inCode = true; + else if (Text[charindex] == '}') inCode = false; + else if (!inCode) justtext = justtext + Text[charindex]; + } + return justtext; +} ///////// // Clone AssEntry *AssDialogue::Clone() { @@ -905,3 +918,6 @@ void AssDialogueBlockDrawing::MultiplyCoords(double x,double y) { final = final.Left(final.Length()-1); text = final; } + + + diff --git a/aegisub/ass_dialogue.h b/aegisub/ass_dialogue.h index 08b401b85..ccc414522 100644 --- a/aegisub/ass_dialogue.h +++ b/aegisub/ass_dialogue.h @@ -196,6 +196,7 @@ public: wxString GetSSAText(); bool CollidesWith(AssDialogue *target); // Checks if two lines collide void ClearBlocks(); + wxString GetStrippedText(); AssEntry *Clone(); diff --git a/aegisub/dialog_kanji_timer.cpp b/aegisub/dialog_kanji_timer.cpp new file mode 100644 index 000000000..1c5679675 --- /dev/null +++ b/aegisub/dialog_kanji_timer.cpp @@ -0,0 +1,397 @@ +// 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 +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +/////////// +// Headers +#include "dialog_kanji_timer.h" +#include "ass_file.h" +#include "ass_dialogue.h" +#include "ass_style.h" +#include "ass_override.h" +#include "subs_grid.h" +#include "validators.h" +#include "video_display.h" +#include "video_provider.h" + + +/////////////// +// Constructor +DialogKanjiTimer::DialogKanjiTimer(wxWindow *parent, SubtitlesGrid *_grid) +: wxDialog (parent,-1,_("Kanji timing"),wxDefaultPosition) +{ + // Variables + AssFile *subs = AssFile::top; + grid = _grid; + vid = grid->video; + + //Sizers + wxSizer *ResBoxSizer1 = new wxStaticBoxSizer(wxVERTICAL,this,_("Text")); + wxSizer *ResBoxSizer2 = new wxStaticBoxSizer(wxVERTICAL,this,_("Shortcut Keys")); + wxSizer *ResBoxSizer3 = new wxStaticBoxSizer(wxVERTICAL,this,_("Groups")); + wxSizer *ResBoxSizer4 = new wxStaticBoxSizer(wxVERTICAL,this,_("Styles")); + wxSizer *ResBoxSizer5 = new wxStaticBoxSizer(wxVERTICAL,this,_("Commands")); + wxBoxSizer *ResSizer1 = new wxBoxSizer(wxHORIZONTAL); + + + SourceText = new wxTextCtrl(this,TEXT_SOURCE,_T(""),wxDefaultPosition,wxSize(560,22),wxTE_READONLY|wxTE_NOHIDESEL|wxSIMPLE_BORDER|wxTE_RIGHT|wxTE_PROCESS_ENTER); + DestText = new wxTextCtrl(this,TEXT_DEST,_T(""),wxDefaultPosition,wxSize(560,22),wxTE_NOHIDESEL|wxSIMPLE_BORDER|wxTE_RIGHT|wxTE_PROCESS_ENTER); + SourceText->SetEventHandler(new DialogKanjiTimerEvent(this)); + DestText->SetEventHandler(new DialogKanjiTimerEvent(this)); + + + wxStaticText *ShortcutKeys = new wxStaticText(this,-1,_("When the destination textbox has focus, use the following keys:\n\nRight Arrow: Increase dest. selection length\nLeft Arrow: Decrease dest. selection length\nUp Arrow: Increase source selection length\nDown Arrow: Decrease source selection length\nEnter: Link, accept line when done\nBackspace: Unlink last"),wxDefaultPosition,wxSize(380,160)); + + SourceStyle=new wxComboBox(this,-1,_(""),wxDefaultPosition,wxSize(200,24), + subs->GetStyles(),wxCB_READONLY,wxDefaultValidator,_("Source Style")); + DestStyle = new wxComboBox(this,-1,_(""),wxDefaultPosition,wxSize(200,24), + subs->GetStyles(),wxCB_READONLY,wxDefaultValidator,_("Dest Style")); + + GroupsList = new wxListCtrl(this,-1,wxDefaultPosition,wxSize(152,160),wxLC_REPORT|wxLC_NO_HEADER|wxLC_HRULES|wxLC_VRULES); + GroupsList->InsertColumn(0, _T(""), wxLIST_FORMAT_CENTER, 72); + GroupsList->InsertColumn(1, _T(""), wxLIST_FORMAT_CENTER, 72); + //Buttons + wxButton *Start = new wxButton(this,BUTTON_KTSTART,_("Start"),wxDefaultPosition,wxSize(200,24)); + wxButton *Link = new wxButton(this,BUTTON_KTLINK,_("Link"),wxDefaultPosition,wxSize(200,24)); + wxButton *Unlink = new wxButton(this,BUTTON_KTUNLINK,_("Unlink"),wxDefaultPosition,wxSize(200,24)); + wxButton *SkipSourceLine = new wxButton(this,BUTTON_KTSKIPSOURCE,_("Skip Source Line"),wxDefaultPosition,wxSize(200,24)); + wxButton *SkipDestLine = new wxButton(this,BUTTON_KTSKIPDEST,_("Skip Dest Line"),wxDefaultPosition,wxSize(200,24)); + wxButton *GoBackLine = new wxButton(this,BUTTON_KTGOBACK,_("Go Back a Line"),wxDefaultPosition,wxSize(200,24)); + wxButton *AcceptLine = new wxButton(this,BUTTON_KTACCEPT,_("Accept Line"),wxDefaultPosition,wxSize(200,24)); + + //Frame: Text + ResBoxSizer1->Add(SourceText,1,wxALIGN_CENTER,5); + ResBoxSizer1->Add(DestText,1,wxALIGN_CENTER,5); + //Frame: Shortcut Keys + ResBoxSizer2->Add(ShortcutKeys,1,wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL,5); + //Frame: Groups + ResBoxSizer3->Add(GroupsList,1,wxALIGN_CENTER,5); + //Frame: Styles + ResBoxSizer4->Add(SourceStyle,1,wxALIGN_CENTER,5); + ResBoxSizer4->Add(DestStyle,1,wxALIGN_CENTER,5); + //Frame: Commands + ResBoxSizer5->Add(Start,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(Link,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(Unlink,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(SkipSourceLine,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(SkipDestLine,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(GoBackLine,1,wxALIGN_CENTER,10); + ResBoxSizer5->Add(AcceptLine,1,wxALIGN_CENTER,10); + + //Combine Shortcut Keys and Groups + ResSizer1->Add(ResBoxSizer2,0,wxALIGN_LEFT,5); + ResSizer1->Add(ResBoxSizer3,1,wxALIGN_RIGHT,5); + + // Main sizer + wxFlexGridSizer *MainSizer = new wxFlexGridSizer(2,2,10,10); + MainSizer->Add(ResBoxSizer1,1,0,5); + MainSizer->Add(ResBoxSizer4,1,0,5); + MainSizer->Add(ResSizer1,1,0,5); + MainSizer->Add(ResBoxSizer5,1,0,5); + MainSizer->SetSizeHints(this); + SetSizer(MainSizer); + CenterOnParent(); +} + + +/////////////// +// Event table +BEGIN_EVENT_TABLE(DialogKanjiTimer,wxDialog) + EVT_BUTTON(BUTTON_KTSTART,DialogKanjiTimer::OnStart) + EVT_BUTTON(BUTTON_KTLINK,DialogKanjiTimer::OnLink) + EVT_BUTTON(BUTTON_KTUNLINK,DialogKanjiTimer::OnUnlink) + EVT_BUTTON(BUTTON_KTSKIPSOURCE,DialogKanjiTimer::OnSkipSource) + EVT_BUTTON(BUTTON_KTSKIPDEST,DialogKanjiTimer::OnSkipDest) + EVT_BUTTON(BUTTON_KTGOBACK,DialogKanjiTimer::OnGoBack) + EVT_BUTTON(BUTTON_KTACCEPT,DialogKanjiTimer::OnAccept) + EVT_KEY_DOWN(DialogKanjiTimer::OnKeyDown) + EVT_TEXT_ENTER(TEXT_SOURCE,DialogKanjiTimer::OnKeyEnter) + EVT_TEXT_ENTER(TEXT_DEST,DialogKanjiTimer::OnKeyEnter) +END_EVENT_TABLE() + +void DialogKanjiTimer::OnStart(wxCommandEvent &event) { + SourceIndex = DestIndex = 0; + OnSkipSource((wxCommandEvent)NULL); + OnSkipDest((wxCommandEvent)NULL); + DestText->SetFocus(); +} +void DialogKanjiTimer::OnLink(wxCommandEvent &event) { + int sourceLen = SourceText->GetStringSelection().Len(); + int destLen = DestText->GetStringSelection().Len(); + if (sourceLen!=0) { + wxString sourceText = SourceText->GetValue(); + wxString destText = DestText->GetValue(); + + wxListItem itm; + int i = GroupsList->GetItemCount(); + GroupsList->InsertItem(i,itm); + GroupsList->SetItem(i,0,SourceText->GetStringSelection()); + GroupsList->SetItem(i,1,DestText->GetStringSelection()); + RegroupGroups[RegroupSourceSelected<<1] = SourceText->GetStringSelection(); + RegroupGroups[(RegroupSourceSelected<<1)+1] = DestText->GetStringSelection(); + + SourceText->SetValue(sourceText.Right(sourceText.Len()-sourceLen)); + DestText->SetValue(destText.Right(destText.Len()-destLen)); + + RegroupSourceSelected++; + } + DestText->SetFocus(); +} +void DialogKanjiTimer::OnUnlink(wxCommandEvent &event) { + if (RegroupSourceSelected) { + RegroupSourceSelected--; + SourceText->ChangeValue(RegroupGroups[RegroupSourceSelected<<1]+SourceText->GetValue()); + DestText->ChangeValue(RegroupGroups[(RegroupSourceSelected<<1)+1]+DestText->GetValue()); + GroupsList->DeleteItem(GroupsList->GetItemCount()-1); + } + DestText->SetFocus(); +} +void DialogKanjiTimer::OnSkipSource(wxCommandEvent &event) { + GroupsList->DeleteAllItems(); + + int index = ListIndexFromStyleandIndex(SourceStyle->GetValue(), SourceIndex); + if (index != -1) { + AssDialogue *line = grid->GetDialogue(index); + AssDialogueBlockOverride *override; + AssDialogueBlockPlain *plain; + AssOverrideTag *tag; + int k, kIndex=0, textIndex=0; + bool LastWasOverride = false; + + line = grid->GetDialogue(index); + wxString StrippedText = line->GetStrippedText(); + SourceText->ChangeValue(StrippedText); + line->ParseASSTags(); + size_t blockn = line->Blocks.size(); + + RegroupSourceText = new wxString[(const int)blockn]; + RegroupGroups = new wxString[(const int)blockn<<1]; + RegroupSourceKLengths = new int[(const int)blockn]; + RegroupTotalLen = 0; //The above arrays won't actually be of size blockn + + for (size_t i=0;iBlocks.at(i)); + if (override) { + if (LastWasOverride) { + /* Explanation for LastWasOverride: + * If we have a karaoke block with no text (IE for a pause) + * then we will get thrown off in the SourceText array + * because the K Length array will increase without it. + */ + RegroupSourceText[textIndex++] = _T(""); + } + for (size_t j=0;jTags.size();j++) { + tag = override->Tags.at(j); + + if (tag->Name == _T("\\k") && tag->Params.size() == 1) + k = tag->Params[0]->AsInt(); + } + RegroupSourceKLengths[kIndex++] = k; + LastWasOverride = true; + } + + plain = AssDialogueBlock::GetAsPlain(line->Blocks.at(i)); + if (plain) { + RegroupSourceText[textIndex++] = plain->text; + LastWasOverride = false; + } + } + RegroupTotalLen = kIndex; //should be the same as textIndex, todo: make sure of that? + RegroupSourceSelected = 0; + SourceIndex++; + SourceText->SetSelection(0,RegroupTotalLen==0?0:RegroupSourceText[0].Len()); + } + DestText->SetFocus(); +} +void DialogKanjiTimer::OnSkipDest(wxCommandEvent &event) { + GroupsList->DeleteAllItems(); + int index = ListIndexFromStyleandIndex(DestStyle->GetValue(), DestIndex); + if (index != -1) { + AssDialogue *line = grid->GetDialogue(index); + DestText->ChangeValue(grid->GetDialogue(index)->GetStrippedText()); + + if (DestText->GetValue().StartsWith(SourceText->GetStringSelection())) + DestText->SetSelection(0,SourceText->GetStringSelection().Len()); + else + DestText->SetSelection(0,0); + + DestText->SetFocus(); + DestIndex++; + } +} +void DialogKanjiTimer::OnGoBack(wxCommandEvent &event) { + DestIndex-=2; + SourceIndex-=2; + OnSkipSource((wxCommandEvent)NULL); + OnSkipDest((wxCommandEvent)NULL); +} +void DialogKanjiTimer::OnAccept(wxCommandEvent &event) { + wxString OutputText = _T(""); + wxString ThisText; + AssDialogue *line = grid->GetDialogue(ListIndexFromStyleandIndex(DestStyle->GetValue(), DestIndex-1)); + int ItemCount = GroupsList->GetItemCount(); + int SourceLength; + int WorkingK = 0; + int SourceIndex = 0; + + for(int index=0;index!=ItemCount;index++) { + SourceLength = RegroupGroups[index<<1].Len(); + + if (RegroupSourceText[SourceIndex].Len() == 0) { + //Karaoke block w/o text that is NOT in the middle of a group, just copy it over + // since we can't figure out if it should go to the previous or the next group + OutputText = wxString::Format(_("%s{\\k%i}"),OutputText,RegroupSourceKLengths[SourceIndex]); + SourceIndex++; + } + + while(SourceLength>0) { + WorkingK += RegroupSourceKLengths[SourceIndex]; + SourceLength -= (RegroupSourceText[SourceIndex]).Len(); + SourceIndex++; + } + OutputText = wxString::Format(_("%s{\\k%i}%s"),OutputText,WorkingK,RegroupGroups[(index<<1)+1]); + + WorkingK = 0; + } + line->Text = OutputText; + grid->ass->FlagAsModified(); + grid->CommitChanges(); + + OnSkipSource((wxCommandEvent)NULL); + OnSkipDest((wxCommandEvent)NULL); +} +void DialogKanjiTimer::OnKeyDown(wxKeyEvent &event) { + int KeyCode = event.GetKeyCode(); + switch(KeyCode) { + case WXK_ESCAPE : + this->EndModal(0); + break; + case WXK_BACK : + this->OnUnlink((wxCommandEvent)NULL); + break; + case WXK_RIGHT : //inc dest selection len + if (DestText->GetStringSelection().Len()!=DestText->GetValue().Len()) + DestText->SetSelection(0,DestText->GetStringSelection().Len()+1); + break; + case WXK_LEFT : //dec dest selection len + if (DestText->GetStringSelection().Len()!=0) + DestText->SetSelection(0,DestText->GetStringSelection().Len()-1); + break; + case WXK_UP : //inc source selection len + if (SourceText->GetStringSelection().Len()!=SourceText->GetValue().Len()) { + SourceText->SetSelection(0,SourceText->GetStringSelection().Len()+RegroupSourceText[GetSourceArrayPos(false)].Len()); + } + break; + case WXK_DOWN : //dec source selection len + if (SourceText->GetStringSelection().Len()!=0) { + SourceText->SetSelection(0,SourceText->GetStringSelection().Len()-RegroupSourceText[GetSourceArrayPos(true)].Len()); + } + break; + case WXK_RETURN : + if (SourceText->GetValue().Len()==0&&GroupsList->GetItemCount()!=0) + this->OnAccept((wxCommandEvent)NULL); + else if (SourceText->GetStringSelection().Len()!=0) + this->OnLink((wxCommandEvent)NULL); + break; + default : + event.Skip(); + } +} +void DialogKanjiTimer::OnKeyEnter(wxCommandEvent &event) { + if (SourceText->GetValue().Len()==0&&GroupsList->GetItemCount()!=0) + this->OnAccept((wxCommandEvent)NULL); + else if (SourceText->GetStringSelection().Len()!=0) + this->OnLink((wxCommandEvent)NULL); + +} + +//////////////////////////////////////////////////// +// Gets the current position in RegroupSourceText // +int DialogKanjiTimer::GetSourceArrayPos(bool GoingDown) { + int Len = 0; + int index; + for(index=0;index!=GroupsList->GetItemCount();index++) { + Len+=RegroupGroups[index<<1].Len(); + } + Len+=SourceText->GetStringSelection().Len(); + for(index=0;Len>0&&index!=RegroupTotalLen;index++) { + Len-=RegroupSourceText[index].Len(); + } + + //Disregard \k blocks w/o text + if (GoingDown) { + index--; + while(index!=RegroupTotalLen && RegroupSourceText[index].Len()==0) { index--; } + } + else { + while(index!=RegroupTotalLen && RegroupSourceText[index].Len()==0) { index++; } + } + + return index; +} + + +int DialogKanjiTimer::ListIndexFromStyleandIndex(wxString StyleName, int Occurance) { + AssDialogue *line; + int index = 0; + int occindex = 0; + while(line=grid->GetDialogue(index)) { + if (line->Style == StyleName) { + if (occindex == Occurance) + return index; + occindex++; + } + index++; + } + return -1; +} + + + + + + +DialogKanjiTimerEvent::DialogKanjiTimerEvent(DialogKanjiTimer *ctrl) { + control = ctrl; +} + +// Event table +BEGIN_EVENT_TABLE(DialogKanjiTimerEvent, wxEvtHandler) + EVT_KEY_DOWN(DialogKanjiTimerEvent::KeyHandler) +END_EVENT_TABLE() + +// Redirects +void DialogKanjiTimerEvent::KeyHandler(wxKeyEvent &event) { control->OnKeyDown(event); } diff --git a/aegisub/dialog_kanji_timer.h b/aegisub/dialog_kanji_timer.h new file mode 100644 index 000000000..3fc8a036a --- /dev/null +++ b/aegisub/dialog_kanji_timer.h @@ -0,0 +1,119 @@ +// Copyright (c) 2006-2007, Dan Donovan (Dansolo) +// 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 +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +#ifndef DIALOG_KANJITIMER_H +#define DIALOG_KANJITIMER_H + + +/////////// +// Headers +#include +#include +#include + + +////////////// +// Prototypes +class SubtitlesGrid; +class VideoDisplay; +class AssOverrideParameter; + + +///////// +// Class +class DialogKanjiTimer : public wxDialog { +private: + SubtitlesGrid *grid; + VideoDisplay *vid; + + wxTextCtrl *SourceText, *DestText; + wxComboBox *SourceStyle, *DestStyle; + wxListCtrl *GroupsList; + + wxString *RegroupSourceText, *RegroupGroups; + int *RegroupSourceKLengths; + int RegroupSourceSelected, RegroupTotalLen; + int SourceIndex, DestIndex; + + void OnStart(wxCommandEvent &event); + void OnLink(wxCommandEvent &event); + void OnUnlink(wxCommandEvent &event); + void OnSkipSource(wxCommandEvent &event); + void OnSkipDest(wxCommandEvent &event); + void OnGoBack(wxCommandEvent &event); + void OnAccept(wxCommandEvent &event); + int ListIndexFromStyleandIndex(wxString StyleName, int Occurance); + int DialogKanjiTimer::GetSourceArrayPos(bool GoingDown); + void DialogKanjiTimer::OnKeyEnter(wxCommandEvent &event); + + +public: + DialogKanjiTimer(wxWindow *parent, SubtitlesGrid *grid); + void OnKeyDown(wxKeyEvent &event); + DECLARE_EVENT_TABLE() +}; + + +///////////////// +// Event handler +class DialogKanjiTimerEvent : public wxEvtHandler { +private: + DialogKanjiTimer *control; + + void KeyHandler(wxKeyEvent &event); + +public: + DialogKanjiTimerEvent(DialogKanjiTimer *control); + DECLARE_EVENT_TABLE() +}; + + +/////// +// IDs +enum { + BUTTON_KTSTART, + BUTTON_KTLINK, + BUTTON_KTUNLINK, + BUTTON_KTSKIPSOURCE, + BUTTON_KTSKIPDEST, + BUTTON_KTGOBACK, + BUTTON_KTACCEPT, + TEXT_SOURCE, + TEXT_DEST +}; + + +#endif diff --git a/aegisub/frame_main.cpp b/aegisub/frame_main.cpp index 954bfe7ad..fc9a4439e 100644 --- a/aegisub/frame_main.cpp +++ b/aegisub/frame_main.cpp @@ -326,6 +326,7 @@ void FrameMain::InitMenu() { AppendBitmapMenuItem(timingMenu,Menu_Edit_Shift, _("S&hift Times...") + wxString(_T("\t")) + Hotkeys.GetText(_T("Shift times")), _("Shift subtitles by time or frames"),wxBITMAP(shift_times_toolbutton)); AppendBitmapMenuItem(timingMenu,Menu_Edit_Sort, _("Sort by Time"), _("Sort all subtitles by their start times"),wxBITMAP(sort_times_button)); AppendBitmapMenuItem(timingMenu,Menu_Tools_Timing_Processor,_("Timing Post-Processor..."), _("Runs a post-processor for timing to deal with lead-ins, lead-outs, scene timing and etc."), wxBITMAP(timing_processor_toolbutton)); + AppendBitmapMenuItem (timingMenu,Menu_Tools_Kanji_Timer,_("Kanji Timer..."),_("Open Kanji timer"),wxBITMAP(blank_button)); timingMenu->AppendSeparator(); AppendBitmapMenuItem(timingMenu,Menu_Subs_Snap_Start_To_Video, _("Snap Start to Video") + wxString(_T("\t")) + Hotkeys.GetText(_T("Set Start To Video")), _("Set start of selected subtitles to current video frame"), wxBITMAP(substart_to_video)); AppendBitmapMenuItem(timingMenu,Menu_Subs_Snap_End_To_Video, _("Snap End to Video") + wxString(_T("\t")) + Hotkeys.GetText(_T("Set End to Video")), _("Set end of selected subtitles to current video frame"), wxBITMAP(subend_to_video)); diff --git a/aegisub/frame_main.h b/aegisub/frame_main.h index 716d90021..69f397b02 100644 --- a/aegisub/frame_main.h +++ b/aegisub/frame_main.h @@ -86,6 +86,7 @@ private: wxMenu *audioMenu; wxMenu *viewMenu; wxMenu *automationMenu; + wxMenu *kanjiTimingMenu; wxMenu *RecentSubs; wxMenu *RecentVids; @@ -198,6 +199,7 @@ private: void OnOpenStylingAssistant (wxCommandEvent &event); void OnOpenResample (wxCommandEvent &event); void OnOpenTimingProcessor (wxCommandEvent &event); + void OnOpenKanjiTimer (wxCommandEvent &event); void OnOpenHotkeys (wxCommandEvent &event); void OnOpenOptions (wxCommandEvent &event); void OnGridEvent (wxCommandEvent &event); @@ -348,6 +350,7 @@ enum { Menu_Tools_Styling, Menu_Tools_Resample, Menu_Tools_Timing_Processor, + Menu_Tools_Kanji_Timer, Menu_Tools_Hotkeys, Menu_Tools_Options, diff --git a/aegisub/frame_main_events.cpp b/aegisub/frame_main_events.cpp index 293abd316..84c8768d0 100644 --- a/aegisub/frame_main_events.cpp +++ b/aegisub/frame_main_events.cpp @@ -68,6 +68,7 @@ #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_hotkeys.h" @@ -163,6 +164,7 @@ BEGIN_EVENT_TABLE(FrameMain, wxFrame) 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_Hotkeys, FrameMain::OnOpenHotkeys) EVT_MENU(Menu_Tools_Options, FrameMain::OnOpenOptions) @@ -930,7 +932,12 @@ void FrameMain::OnOpenTimingProcessor (wxCommandEvent &event) { DialogTimingProcessor timing(this,SubsBox); timing.ShowModal(); } - +///////////////////////////////////// +// Open Kanji Timer dialog +void FrameMain::OnOpenKanjiTimer (wxCommandEvent &event) { + DialogKanjiTimer kanjitimer(this,SubsBox); + kanjitimer.ShowModal(); +} /////////////////////// // Open Hotkeys dialog