1
// Copyright (c) 2005, Rodrigo Braz Monteiro
2
// All rights reserved.
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
7
// * Redistributions of source code must retain the above copyright notice,
8
// this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright notice,
10
// this list of conditions and the following disclaimer in the documentation
11
// and/or other materials provided with the distribution.
12
// * Neither the name of the Aegisub Group nor the names of its contributors
13
// may be used to endorse or promote products derived from this software
14
// without specific prior written permission.
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
// POSSIBILITY OF SUCH DAMAGE.
28
// -----------------------------------------------------------------------------
32
// Website: http://aegisub.cellosoft.com
33
// Contact: mailto:zeratul@cellosoft.com
41
#include <wx/recguard.h>
42
#include "dialog_styling_assistant.h"
43
#include "subs_grid.h"
45
#include "ass_style.h"
46
#include "ass_dialogue.h"
47
#include "video_display.h"
48
#include "video_context.h"
50
#include "frame_main.h"
51
#include "audio_display.h"
52
#include "audio_box.h"
55
#include "help_button.h"
56
#include "subs_edit_box.h"
61
DialogStyling::DialogStyling (wxWindow *parent,SubtitlesGrid *_grid) :
62
wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX)
65
SetIcon(BitmapToIcon(wxBITMAP(styling_toolbutton)));
69
audio = VideoContext::Get()->audio->box->audioDisplay;
75
wxSizer *TopSizer = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Current line"));
76
CurLine = new wxTextCtrl(this,-1,_("Current line"),wxDefaultPosition,wxSize(300,60),wxTE_MULTILINE | wxTE_READONLY);
77
TopSizer->Add(CurLine,1,wxEXPAND,0);
80
Styles = new wxListBox(this,STYLE_LIST,wxDefaultPosition,wxSize(150,180),grid->ass->GetStyles());
81
wxSizer *LeftSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Styles available"));
82
LeftSizer->Add(Styles,1,wxEXPAND,0);
85
wxSizer *RightSizer = new wxBoxSizer(wxVERTICAL);
86
wxSizer *RightTop = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Set style"));
87
wxSizer *RightMiddle = new wxStaticBoxSizer(wxVERTICAL,this,_("Keys"));
88
wxSizer *RightBottom = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Actions"));
89
TypeBox = new StyleEditBox(this);
90
RightTop->Add(TypeBox,1,wxEXPAND);
93
//wxStaticText *Keys = new wxStaticText(this,-1,_("Enter:\t\tAccept changes\nPage up:\tPrevious line\nPage down:\tNext line\nEnd:\t\tPlay sound\nClick on list:\tSet style\nCtrl+enter:\tAccept without going to next"));
94
wxSizer *KeysInnerSizer = new wxGridSizer(2,0,5);
95
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Accept")) + _T(": ")));
96
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Accept changes")));
97
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Preview")) + _T(": ")));
98
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Preview changes")));
99
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Prev")) + _T(": ")));
100
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Previous line")));
101
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Next")) + _T(": ")));
102
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Next line")));
103
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Video")) + _T(": ")));
104
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Video")));
105
KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Styling Assistant Play Audio")) + _T(": ")));
106
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Audio")));
107
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Click on list:")));
108
KeysInnerSizer->Add(new wxStaticText(this,-1,_("Select style")));
111
PreviewCheck = new wxCheckBox(this,-1,_("Enable preview (slow)"));
112
PreviewCheck->SetValue(true);
113
RightMiddle->Add(KeysInnerSizer,0,wxEXPAND | wxBOTTOM,5);
114
RightMiddle->Add(PreviewCheck,0,0,0);
115
RightMiddle->AddStretchSpacer(1);
117
// Rest of right sizer
118
PlayVideoButton = new wxButton(this,BUTTON_PLAY_VIDEO,_("Play Video"));
119
PlayAudioButton = new wxButton(this,BUTTON_PLAY_AUDIO,_("Play Audio"));
120
RightBottom->AddStretchSpacer(1);
121
RightBottom->Add(PlayAudioButton,0,wxLEFT | wxRIGHT | wxBOTTOM,5);
122
RightBottom->Add(PlayVideoButton,0,wxBOTTOM | wxRIGHT,5);
123
RightBottom->AddStretchSpacer(1);
125
RightSizer->Add(RightTop,0,wxEXPAND | wxBOTTOM,5);
126
RightSizer->Add(RightMiddle,0,wxEXPAND | wxBOTTOM,5);
127
RightSizer->Add(RightBottom,0,wxEXPAND,5);
130
wxSizer *BottomSizer = new wxBoxSizer(wxHORIZONTAL);
131
BottomSizer->Add(LeftSizer,1,wxEXPAND | wxRIGHT,5);
132
BottomSizer->Add(RightSizer,1,wxEXPAND,0);
135
wxStdDialogButtonSizer *ButtonSizer = new wxStdDialogButtonSizer();
136
ButtonSizer->AddButton(new wxButton(this,wxID_CANCEL));
137
ButtonSizer->AddButton(new HelpButton(this,_T("Styling Assistant")));
138
ButtonSizer->Realize();
141
wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
142
MainSizer->Add(TopSizer,0,wxEXPAND | wxALL,5);
143
MainSizer->Add(BottomSizer,1,wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT,5);
144
MainSizer->Add(ButtonSizer,0,wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT,5);
145
MainSizer->SetSizeHints(this);
149
if (lastx == -1 && lasty == -1) {
156
origColour = TypeBox->GetBackgroundColour();
162
DialogStyling::~DialogStyling () {
163
GetPosition(&lastx, &lasty);
165
grid->ass->FlagAsModified(_("style changes"));
166
grid->CommitChanges();
173
void DialogStyling::JumpToLine(int n) {
178
AssDialogue *nextLine = grid->GetDialogue(n);
179
if (!nextLine) return;
186
CurLine->SetValue(line->Text);
190
bool matched = false;
191
for (size_t i = 0; i < Styles->GetCount(); i++) {
192
if (TypeBox->GetValue().IsSameAs(Styles->GetString(i),true)) {
197
if (!matched || TypeBox->GetValue().IsEmpty()) TypeBox->SetValue(Styles->GetString(0));
198
TypeBox->SetSelection(0,TypeBox->GetValue().Length());
201
grid->SelectRow(linen,false);
202
grid->MakeCellVisible(linen,0);
203
grid->editBox->SetToLine(linen);
206
if (PreviewCheck->IsChecked()) VideoContext::Get()->JumpToFrame(VFR_Output.GetFrameAtTime(line->Start.GetMS(),true));
210
/////////////////////////////
211
// Set style of current line
212
void DialogStyling::SetStyle (wxString curName, bool jump) {
214
AssDialogue *line = grid->GetDialogue(linen);
217
line->Style = curName;
221
grid->Refresh(false);
222
if (PreviewCheck->IsChecked()) {
223
grid->ass->FlagAsModified(_("styling assistant"));
224
grid->CommitChanges();
226
else needCommit = true;
229
if (jump) JumpToLine(linen+1);
235
BEGIN_EVENT_TABLE(DialogStyling,wxDialog)
236
EVT_ACTIVATE(DialogStyling::OnActivate)
237
EVT_BUTTON(BUTTON_PLAY_VIDEO, DialogStyling::OnPlayVideoButton)
238
EVT_BUTTON(BUTTON_PLAY_AUDIO, DialogStyling::OnPlayAudioButton)
239
//EVT_TEXT_ENTER(ENTER_STYLE_BOX, DialogStyling::OnStyleBoxEnter)
240
EVT_TEXT(ENTER_STYLE_BOX, DialogStyling::OnStyleBoxModified)
241
EVT_LISTBOX_DCLICK(STYLE_LIST, DialogStyling::OnListClicked)
242
EVT_KEY_DOWN(DialogStyling::OnKeyDown)
246
///////////////////////////
247
// Dialog was De/Activated
248
void DialogStyling::OnActivate(wxActivateEvent &event) {
250
if (!event.GetActive()) {
252
grid->ass->FlagAsModified(_("styling assistant"));
253
grid->CommitChanges();
258
// Enable/disable play video/audio buttons
259
PlayVideoButton->Enable(video->IsLoaded());
260
PlayAudioButton->Enable(audio->loaded);
262
if (grid->ass != AssFile::top)
263
grid->LoadFromAss(AssFile::top,false,true);
265
Styles->Set(grid->ass->GetStyles());
266
// Fix line selection
267
JumpToLine(grid->GetFirstSelRow());
273
void DialogStyling::OnKeyDown(wxKeyEvent &event) {
274
int keycode = event.GetKeyCode();
277
if (keycode == WXK_PAGEUP) {
282
if (keycode == WXK_PAGEDOWN) {
292
void DialogStyling::OnStyleBoxModified (wxCommandEvent &event) {
294
static wxRecursionGuardFlag s_flag;
295
wxRecursionGuard guard(s_flag);
296
if (guard.IsInside()) return;
298
// Find partial style name
300
TypeBox->GetSelection(&from,&to);
301
wxString partial = TypeBox->GetValue().Left(from).Lower();
302
int len = partial.Length();
304
// Find first style that matches partial name
306
int n = Styles->GetCount();
308
for (int i=0;i<n;i++) {
309
curname = Styles->GetString(i);
310
if (curname.Left(len).Lower() == partial) {
318
TypeBox->SetValue(curname);
319
TypeBox->SetSelection(from,curname.Length());
320
TypeBox->SetBackgroundColour(origColour);
326
TypeBox->SetBackgroundColour(wxColour(255,108,108));
334
void DialogStyling::OnStyleBoxEnter (wxCommandEvent &event) {
339
//////////////////////
340
// Style list clicked
341
void DialogStyling::OnListClicked(wxCommandEvent &event) {
342
int n = event.GetInt();
343
SetStyle(Styles->GetString(n));
344
Styles->SetSelection(wxNOT_FOUND);
348
/////////////////////
350
void DialogStyling::OnPlayVideoButton(wxCommandEvent &event) {
355
/////////////////////
357
void DialogStyling::OnPlayAudioButton(wxCommandEvent &event) {
358
audio->Play(line->Start.GetMS(),line->End.GetMS());
363
//////////////////////////////
364
// Style edit box constructor
365
StyleEditBox::StyleEditBox(DialogStyling *parent)
366
: wxTextCtrl(parent,ENTER_STYLE_BOX,_T(""),wxDefaultPosition,wxSize(180,-1),wxTE_PROCESS_ENTER)
372
////////////////////////////
373
// Event table for edit box
374
BEGIN_EVENT_TABLE(StyleEditBox,wxTextCtrl)
375
EVT_KEY_DOWN(StyleEditBox::OnKeyDown)
381
void StyleEditBox::OnKeyDown(wxKeyEvent &event) {
382
//int keycode = event.GetKeyCode();
384
Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
386
Hotkeys.SetPressed(event.GetKeyCode(),event.m_controlDown,event.m_altDown,event.m_shiftDown);
391
if (event.GetKeyCode() == WXK_BACK && !event.m_metaDown && !event.m_altDown && !event.m_shiftDown) {
393
if (event.GetKeyCode() == WXK_BACK && !event.m_controlDown && !event.m_altDown && !event.m_shiftDown) {
396
GetSelection(&from,&to);
397
if (from > 0) SetSelection(from-1,to);
401
if (Hotkeys.IsPressed(_T("Styling Assistant Prev"))) {
402
diag->JumpToLine(diag->linen-1);
407
if (Hotkeys.IsPressed(_T("Styling Assistant Next"))) {
408
diag->JumpToLine(diag->linen+1);
413
if (Hotkeys.IsPressed(_T("Styling Assistant Play Video"))) {
414
if (diag->video->IsLoaded()) {
415
diag->video->PlayLine();
421
if (Hotkeys.IsPressed(_T("Styling Assistant Play Audio"))) {
422
if (diag->audio->loaded) {
423
diag->audio->Play(diag->line->Start.GetMS(),diag->line->End.GetMS());
429
if (Hotkeys.IsPressed(_T("Styling Assistant Accept")) || Hotkeys.IsPressed(_T("Styling Assistant Preview"))) {
430
// Make sure that entered style is valid
431
int n = diag->Styles->GetCount();
434
for (int i=0;i<n;i++) {
435
curName = diag->Styles->GetString(i);
436
if (curName == GetValue()) {
444
diag->SetStyle(curName,Hotkeys.IsPressed(_T("Styling Assistant Accept")));
453
int DialogStyling::lastx = -1;
454
int DialogStyling::lasty = -1;