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

« back to all changes in this revision

Viewing changes to src/dialog_styling_assistant.cpp

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2005, Rodrigo Braz Monteiro
 
2
// All rights reserved.
 
3
//
 
4
// Redistribution and use in source and binary forms, with or without
 
5
// modification, are permitted provided that the following conditions are met:
 
6
//
 
7
//   * Redistributions of source code must retain the above copyright notice,
 
8
//     this list of conditions and the following disclaimer.
 
9
//   * Redistributions in binary form must reproduce the above copyright notice,
 
10
//     this list of conditions and the following disclaimer in the documentation
 
11
//     and/or other materials provided with the distribution.
 
12
//   * Neither the name of the Aegisub Group nor the names of its contributors
 
13
//     may be used to endorse or promote products derived from this software
 
14
//     without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
21
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
26
// POSSIBILITY OF SUCH DAMAGE.
 
27
//
 
28
// -----------------------------------------------------------------------------
 
29
//
 
30
// AEGISUB
 
31
//
 
32
// Website: http://aegisub.cellosoft.com
 
33
// Contact: mailto:zeratul@cellosoft.com
 
34
//
 
35
 
 
36
 
 
37
///////////
 
38
// Headers
 
39
#include "config.h"
 
40
 
 
41
#include <wx/recguard.h>
 
42
#include "dialog_styling_assistant.h"
 
43
#include "subs_grid.h"
 
44
#include "ass_file.h"
 
45
#include "ass_style.h"
 
46
#include "ass_dialogue.h"
 
47
#include "video_display.h"
 
48
#include "video_context.h"
 
49
#include "vfr.h"
 
50
#include "frame_main.h"
 
51
#include "audio_display.h"
 
52
#include "audio_box.h"
 
53
#include "hotkeys.h"
 
54
#include "utils.h"
 
55
#include "help_button.h"
 
56
#include "subs_edit_box.h"
 
57
 
 
58
 
 
59
///////////////
 
60
// Constructor
 
61
DialogStyling::DialogStyling (wxWindow *parent,SubtitlesGrid *_grid) :
 
62
wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX)
 
63
{
 
64
        // Set icon
 
65
        SetIcon(BitmapToIcon(wxBITMAP(styling_toolbutton)));
 
66
 
 
67
        // Variables
 
68
        grid = _grid;
 
69
        audio = VideoContext::Get()->audio->box->audioDisplay;
 
70
        video = video->Get();
 
71
        needCommit = false;
 
72
        linen = -1;
 
73
 
 
74
        // Top sizer
 
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);
 
78
 
 
79
        // Left sizer
 
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);
 
83
 
 
84
        // Right sizer
 
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);
 
91
 
 
92
        // Shortcuts
 
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")));
 
109
 
 
110
        // Right Middle
 
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);
 
116
 
 
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);
 
124
 
 
125
        RightSizer->Add(RightTop,0,wxEXPAND | wxBOTTOM,5);
 
126
        RightSizer->Add(RightMiddle,0,wxEXPAND | wxBOTTOM,5);
 
127
        RightSizer->Add(RightBottom,0,wxEXPAND,5);
 
128
 
 
129
        // Bottom sizer
 
130
        wxSizer *BottomSizer = new wxBoxSizer(wxHORIZONTAL);
 
131
        BottomSizer->Add(LeftSizer,1,wxEXPAND | wxRIGHT,5);
 
132
        BottomSizer->Add(RightSizer,1,wxEXPAND,0);
 
133
 
 
134
        // Button sizer
 
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();
 
139
 
 
140
        // Main sizer
 
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);
 
146
        SetSizer(MainSizer);
 
147
 
 
148
        // Position window
 
149
        if (lastx == -1 && lasty == -1) {
 
150
                CenterOnParent();
 
151
        } else {
 
152
                Move(lastx, lasty);
 
153
        }
 
154
 
 
155
        // h4x
 
156
        origColour = TypeBox->GetBackgroundColour();
 
157
}
 
158
 
 
159
 
 
160
//////////////
 
161
// Destructor
 
162
DialogStyling::~DialogStyling () {
 
163
        GetPosition(&lastx, &lasty);
 
164
        if (needCommit) {
 
165
                grid->ass->FlagAsModified(_("style changes"));
 
166
                grid->CommitChanges();
 
167
        }
 
168
}
 
169
 
 
170
 
 
171
////////////////
 
172
// Jump to line
 
173
void DialogStyling::JumpToLine(int n) {
 
174
        // Check stuff
 
175
        if (n == -1) return;
 
176
 
 
177
        // Get line
 
178
        AssDialogue *nextLine = grid->GetDialogue(n);
 
179
        if (!nextLine) return;
 
180
        line = nextLine;
 
181
 
 
182
        // Set number
 
183
        linen = n;
 
184
 
 
185
        // Set text
 
186
        CurLine->SetValue(line->Text);
 
187
 
 
188
        // Set focus
 
189
        TypeBox->SetFocus();
 
190
        bool matched = false;
 
191
        for (size_t i = 0; i < Styles->GetCount(); i++) {
 
192
                if (TypeBox->GetValue().IsSameAs(Styles->GetString(i),true)) {
 
193
                        matched = true;
 
194
                        break;
 
195
                }
 
196
        }
 
197
        if (!matched || TypeBox->GetValue().IsEmpty()) TypeBox->SetValue(Styles->GetString(0));
 
198
        TypeBox->SetSelection(0,TypeBox->GetValue().Length());
 
199
 
 
200
        // Update grid
 
201
        grid->SelectRow(linen,false);
 
202
        grid->MakeCellVisible(linen,0);
 
203
        grid->editBox->SetToLine(linen);
 
204
 
 
205
        // Update display
 
206
        if (PreviewCheck->IsChecked()) VideoContext::Get()->JumpToFrame(VFR_Output.GetFrameAtTime(line->Start.GetMS(),true));
 
207
}
 
208
 
 
209
 
 
210
/////////////////////////////
 
211
// Set style of current line
 
212
void DialogStyling::SetStyle (wxString curName, bool jump) {
 
213
        // Get line
 
214
        AssDialogue *line = grid->GetDialogue(linen);
 
215
 
 
216
        // Update line
 
217
        line->Style = curName;
 
218
        line->UpdateData();
 
219
 
 
220
        // Update grid/subs
 
221
        grid->Refresh(false);
 
222
        if (PreviewCheck->IsChecked()) {
 
223
                grid->ass->FlagAsModified(_("styling assistant"));
 
224
                grid->CommitChanges();
 
225
        }
 
226
        else needCommit = true;
 
227
 
 
228
        // Next line
 
229
        if (jump) JumpToLine(linen+1);
 
230
}
 
231
 
 
232
 
 
233
///////////////
 
234
// Event table
 
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)
 
243
END_EVENT_TABLE()
 
244
 
 
245
 
 
246
///////////////////////////
 
247
// Dialog was De/Activated
 
248
void DialogStyling::OnActivate(wxActivateEvent &event) {
 
249
        // Dialog lost focus
 
250
        if (!event.GetActive()) {
 
251
                if (needCommit) {
 
252
                        grid->ass->FlagAsModified(_("styling assistant"));
 
253
                        grid->CommitChanges();
 
254
                        needCommit = false;
 
255
                }
 
256
                return;
 
257
        }
 
258
        // Enable/disable play video/audio buttons
 
259
        PlayVideoButton->Enable(video->IsLoaded());
 
260
        PlayAudioButton->Enable(audio->loaded);
 
261
        // Update grid
 
262
        if (grid->ass != AssFile::top)
 
263
                grid->LoadFromAss(AssFile::top,false,true);
 
264
        // Fix style list
 
265
        Styles->Set(grid->ass->GetStyles());
 
266
        // Fix line selection
 
267
        JumpToLine(grid->GetFirstSelRow());
 
268
}
 
269
 
 
270
 
 
271
///////////////
 
272
// Key pressed
 
273
void DialogStyling::OnKeyDown(wxKeyEvent &event) {
 
274
        int keycode = event.GetKeyCode();
 
275
 
 
276
        // Previous line
 
277
        if (keycode == WXK_PAGEUP) {
 
278
                JumpToLine(linen-1);
 
279
        }
 
280
 
 
281
        // Next line
 
282
        if (keycode == WXK_PAGEDOWN) {
 
283
                JumpToLine(linen+1);
 
284
        }
 
285
 
 
286
        event.Skip();
 
287
}
 
288
 
 
289
 
 
290
////////////////////
 
291
// Edit box changed
 
292
void DialogStyling::OnStyleBoxModified (wxCommandEvent &event) {
 
293
        // Recursion guard
 
294
        static wxRecursionGuardFlag s_flag;
 
295
        wxRecursionGuard guard(s_flag);
 
296
        if (guard.IsInside()) return;
 
297
 
 
298
        // Find partial style name
 
299
        long from,to;
 
300
        TypeBox->GetSelection(&from,&to);
 
301
        wxString partial = TypeBox->GetValue().Left(from).Lower();
 
302
        int len = partial.Length();
 
303
 
 
304
        // Find first style that matches partial name
 
305
        bool match = false;
 
306
        int n = Styles->GetCount();
 
307
        wxString curname;
 
308
        for (int i=0;i<n;i++) {
 
309
                curname = Styles->GetString(i);
 
310
                if (curname.Left(len).Lower() == partial) {
 
311
                        match = true;
 
312
                        break;
 
313
                }
 
314
        }
 
315
 
 
316
        // Found
 
317
        if (match) {
 
318
                TypeBox->SetValue(curname);
 
319
                TypeBox->SetSelection(from,curname.Length());
 
320
                TypeBox->SetBackgroundColour(origColour);
 
321
                TypeBox->Refresh();
 
322
        }
 
323
 
 
324
        // Not found
 
325
        else {
 
326
                TypeBox->SetBackgroundColour(wxColour(255,108,108));
 
327
                TypeBox->Refresh();
 
328
        }
 
329
}
 
330
 
 
331
 
 
332
/////////////////
 
333
// Enter pressed
 
334
void DialogStyling::OnStyleBoxEnter (wxCommandEvent &event) {
 
335
 
 
336
}
 
337
 
 
338
 
 
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);
 
345
        TypeBox->SetFocus();
 
346
}
 
347
 
 
348
/////////////////////
 
349
// Play video button
 
350
void DialogStyling::OnPlayVideoButton(wxCommandEvent &event) {
 
351
        video->PlayLine();
 
352
        TypeBox->SetFocus();
 
353
}
 
354
 
 
355
/////////////////////
 
356
// Play audio button
 
357
void DialogStyling::OnPlayAudioButton(wxCommandEvent &event) {
 
358
        audio->Play(line->Start.GetMS(),line->End.GetMS());
 
359
        TypeBox->SetFocus();
 
360
}
 
361
 
 
362
 
 
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)
 
367
{
 
368
        diag = parent;
 
369
}
 
370
 
 
371
 
 
372
////////////////////////////
 
373
// Event table for edit box
 
374
BEGIN_EVENT_TABLE(StyleEditBox,wxTextCtrl)
 
375
        EVT_KEY_DOWN(StyleEditBox::OnKeyDown)
 
376
END_EVENT_TABLE()
 
377
 
 
378
 
 
379
///////////////
 
380
// Key pressed
 
381
void StyleEditBox::OnKeyDown(wxKeyEvent &event) {
 
382
        //int keycode = event.GetKeyCode();
 
383
#ifdef __APPLE__
 
384
        Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
 
385
#else
 
386
        Hotkeys.SetPressed(event.GetKeyCode(),event.m_controlDown,event.m_altDown,event.m_shiftDown);
 
387
#endif
 
388
 
 
389
        // Backspace
 
390
#ifdef __APPLE__
 
391
        if (event.GetKeyCode() == WXK_BACK && !event.m_metaDown && !event.m_altDown && !event.m_shiftDown) {
 
392
#else
 
393
        if (event.GetKeyCode() == WXK_BACK && !event.m_controlDown && !event.m_altDown && !event.m_shiftDown) {
 
394
#endif
 
395
                long from,to;
 
396
                GetSelection(&from,&to);
 
397
                if (from > 0) SetSelection(from-1,to);
 
398
        }
 
399
 
 
400
        // Previous line
 
401
        if (Hotkeys.IsPressed(_T("Styling Assistant Prev"))) {
 
402
                diag->JumpToLine(diag->linen-1);
 
403
                return;
 
404
        }
 
405
 
 
406
        // Next line
 
407
        if (Hotkeys.IsPressed(_T("Styling Assistant Next"))) {
 
408
                diag->JumpToLine(diag->linen+1);
 
409
                return;
 
410
        }
 
411
 
 
412
        // Play video
 
413
        if (Hotkeys.IsPressed(_T("Styling Assistant Play Video"))) {
 
414
                if (diag->video->IsLoaded()) {
 
415
                        diag->video->PlayLine();
 
416
                }
 
417
                return;
 
418
        }
 
419
 
 
420
        // Play audio
 
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());
 
424
                }
 
425
                return;
 
426
        }
 
427
 
 
428
        // Enter key
 
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();
 
432
                wxString curName;
 
433
                bool match = false;
 
434
                for (int i=0;i<n;i++) {
 
435
                        curName = diag->Styles->GetString(i);
 
436
                        if (curName == GetValue()) {
 
437
                                match = true;
 
438
                                break;
 
439
                        }
 
440
                }
 
441
 
 
442
                // Set style name
 
443
                if (match) {
 
444
                        diag->SetStyle(curName,Hotkeys.IsPressed(_T("Styling Assistant Accept")));
 
445
                }
 
446
                return;
 
447
        }
 
448
 
 
449
        event.Skip();
 
450
}
 
451
 
 
452
 
 
453
int DialogStyling::lastx = -1;
 
454
int DialogStyling::lasty = -1;