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

« back to all changes in this revision

Viewing changes to src/dialog_translation.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/wxprec.h>
 
42
#include <wx/settings.h>
 
43
#include "dialog_translation.h"
 
44
#include "ass_dialogue.h"
 
45
#include "ass_file.h"
 
46
#include "subs_grid.h"
 
47
#include "video_display.h"
 
48
#include "video_context.h"
 
49
#include "subs_edit_box.h"
 
50
#include "options.h"
 
51
#include "audio_display.h"
 
52
#include "frame_main.h"
 
53
#include "hotkeys.h"
 
54
#include "utils.h"
 
55
#include "help_button.h"
 
56
 
 
57
 
 
58
///////////////
 
59
// Constructor
 
60
DialogTranslation::DialogTranslation (wxWindow *parent,AssFile *_subs,SubtitlesGrid *_grid,int startrow,bool preview)
 
61
: wxDialog(parent, -1, _("Translation Assistant"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX, _T("TranslationAssistant"))
 
62
{
 
63
        // Set icon
 
64
        SetIcon(BitmapToIcon(wxBITMAP(translation_toolbutton)));
 
65
 
 
66
        // Set variables
 
67
        enablePreview = preview;
 
68
        main = parent;
 
69
        subs = _subs;
 
70
        grid = _grid;
 
71
        audio = VideoContext::Get()->audio;
 
72
        video = video->Get();
 
73
 
 
74
        // Create sizers (especially StaticBoxSizers) first to get control Z order right
 
75
        wxSizer *TranslationSizer = new wxBoxSizer(wxVERTICAL);
 
76
        wxSizer *OriginalTransSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Original"));
 
77
        wxSizer *TranslatedSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Translation"));
 
78
 
 
79
        // Translation controls
 
80
        OrigText = new ScintillaTextCtrl(this,TEXT_ORIGINAL,_T(""),wxDefaultPosition,wxSize(320,80));
 
81
        OrigText->SetWrapMode(wxSTC_WRAP_WORD);
 
82
        OrigText->SetMarginWidth(1,0);
 
83
        OrigText->StyleSetForeground(1,wxColour(10,60,200));
 
84
        OrigText->SetReadOnly(true);
 
85
        //OrigText->PushEventHandler(new DialogTranslationEvent(this));
 
86
        TransText = new ScintillaTextCtrl(this,TEXT_TRANS,_T(""),wxDefaultPosition,wxSize(320,80));
 
87
        TransText->SetWrapMode(wxSTC_WRAP_WORD);
 
88
        TransText->SetMarginWidth(1,0);
 
89
        TransText->PushEventHandler(new DialogTranslationEvent(this));
 
90
        TransText->SetFocus();
 
91
 
 
92
        // Translation box
 
93
        LineCount = new wxStaticText(this,-1,_("Current line: ?"));
 
94
        OriginalTransSizer->Add(LineCount,0,wxBOTTOM,5);
 
95
        OriginalTransSizer->Add(OrigText,1,wxEXPAND,0);
 
96
        TranslatedSizer->Add(TransText,1,wxEXPAND,0);
 
97
        TranslationSizer->Add(OriginalTransSizer,1,wxEXPAND,0);
 
98
        TranslationSizer->Add(TranslatedSizer,1,wxTOP|wxEXPAND,5);
 
99
 
 
100
        // Hotkeys
 
101
        wxSizer *KeysSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Keys"));
 
102
        wxSizer *KeysInnerSizer = new wxGridSizer(2,0,5);
 
103
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Accept")) + _T(": ")));
 
104
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Accept changes")));
 
105
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Preview")) + _T(": ")));
 
106
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Preview changes")));
 
107
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Prev")) + _T(": ")));
 
108
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Previous line")));
 
109
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Next")) + _T(": ")));
 
110
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Next line")));
 
111
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Insert Original")) + _T(": ")));
 
112
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Insert original")));
 
113
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Video")) + _T(": ")));
 
114
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Video")));
 
115
        KeysInnerSizer->Add(new wxStaticText(this,-1,Hotkeys.GetText(_T("Translation Assistant Play Audio")) + _T(": ")));
 
116
        KeysInnerSizer->Add(new wxStaticText(this,-1,_("Play Audio")));
 
117
        PreviewCheck = new wxCheckBox(this,PREVIEW_CHECK,_("Enable preview"));
 
118
        PreviewCheck->SetValue(preview);
 
119
        PreviewCheck->PushEventHandler(new DialogTranslationEvent(this));
 
120
        KeysSizer->Add(KeysInnerSizer,0,wxEXPAND,0);
 
121
        KeysSizer->Add(PreviewCheck,0,wxTOP,5);
 
122
        
 
123
        // Tool sizer
 
124
        wxStaticBoxSizer *ToolSizer = new wxStaticBoxSizer(wxVERTICAL,this, _("Actions"));
 
125
        wxButton *PlayVideoButton = new wxButton(this,BUTTON_TRANS_PLAY_VIDEO,_("Play Video"));
 
126
        wxButton *PlayAudioButton = new wxButton(this,BUTTON_TRANS_PLAY_AUDIO,_("Play Audio"));
 
127
        PlayVideoButton->Enable(video->IsLoaded());
 
128
        PlayAudioButton->Enable(audio->loaded);
 
129
        ToolSizer->Add(PlayAudioButton,0,wxALL,5);
 
130
        ToolSizer->Add(PlayVideoButton,0,wxLEFT | wxRIGHT | wxBOTTOM,5);
 
131
 
 
132
        // Hotkeys + Tool sizer
 
133
        wxBoxSizer *HTSizer = new wxBoxSizer(wxHORIZONTAL);
 
134
        HTSizer->Add(KeysSizer,1,wxRIGHT | wxEXPAND,5);
 
135
        HTSizer->Add(ToolSizer,0);
 
136
 
 
137
        // Button sizer
 
138
        wxStdDialogButtonSizer *ButtonSizer = new wxStdDialogButtonSizer();
 
139
        ButtonSizer->AddButton(new wxButton(this,wxID_CANCEL));
 
140
        ButtonSizer->AddButton(new HelpButton(this,_T("Translation Assistant")));
 
141
        ButtonSizer->Realize();
 
142
 
 
143
        // General layout
 
144
        wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
 
145
        MainSizer->Add(TranslationSizer,1,wxALL | wxEXPAND,5);
 
146
        MainSizer->Add(HTSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
 
147
        MainSizer->Add(ButtonSizer,0,wxALIGN_RIGHT | wxLEFT | wxBOTTOM | wxRIGHT,5);
 
148
 
 
149
        // Set sizer
 
150
        SetSizer(MainSizer);
 
151
        MainSizer->SetSizeHints(this);
 
152
 
 
153
        // Position window
 
154
        if (lastx == -1 && lasty == -1) {
 
155
                CenterOnParent();
 
156
        } else {
 
157
                Move(lastx, lasty);
 
158
        }
 
159
 
 
160
        // Set subs/grid
 
161
        JumpToLine(startrow,0);
 
162
        UpdatePreview();
 
163
}
 
164
 
 
165
 
 
166
//////////////////////////
 
167
// Jumps to line at block
 
168
bool DialogTranslation::JumpToLine(int n,int block) {
 
169
        using std::vector;
 
170
        AssDialogue *nextLine;
 
171
        try {
 
172
                nextLine = grid->GetDialogue(n);
 
173
        } catch (...) {
 
174
                return false;
 
175
        }
 
176
        if (!nextLine) return false;
 
177
        current = nextLine;
 
178
 
 
179
        // Count blocks
 
180
        int nblocks = 0;
 
181
        current->ParseASSTags();
 
182
        size_t size_blocks = current->Blocks.size();
 
183
        for (size_t i=0;i<size_blocks;i++) {
 
184
                if (current->Blocks.at(i)->GetType() == BLOCK_PLAIN) nblocks++;
 
185
        }
 
186
 
 
187
        // Wrap around
 
188
        if (block == 0xFFFF) block = nblocks-1;
 
189
        if (block < 0) {
 
190
                block = 0xFFFF;
 
191
                n--;
 
192
                return JumpToLine(n,block);
 
193
        }
 
194
        if (block >= nblocks) {
 
195
                block = 0;
 
196
                n++;
 
197
                return JumpToLine(n,block);
 
198
        }
 
199
 
 
200
        // Set current
 
201
        curline = n;
 
202
        current = grid->GetDialogue(n);
 
203
        curblock = block;
 
204
        LineCount->SetLabel(wxString::Format(_("Current line: %i/%i"),curline+1,grid->GetRows()));
 
205
 
 
206
        // Update grid
 
207
        grid->BeginBatch();
 
208
        grid->SelectRow(curline);
 
209
        grid->MakeCellVisible(curline,0);
 
210
        grid->editBox->SetToLine(curline);
 
211
        grid->EndBatch();
 
212
 
 
213
        // Adds blocks
 
214
        OrigText->SetReadOnly(false);
 
215
        OrigText->ClearAll();
 
216
        AssDialogueBlock *curBlock;
 
217
        bool found = false;
 
218
        int pos=-1;
 
219
        for (vector<AssDialogueBlock*>::iterator cur=current->Blocks.begin();cur!=current->Blocks.end();cur++) {
 
220
                curBlock = *cur;
 
221
                if (curBlock->GetType() == BLOCK_PLAIN) {
 
222
                        pos++;
 
223
                        int curLen = OrigText->GetReverseUnicodePosition(OrigText->GetLength());
 
224
                        OrigText->AppendText(curBlock->text);
 
225
                        if (pos == block) {
 
226
                                OrigText->StartUnicodeStyling(curLen);
 
227
                                OrigText->SetUnicodeStyling(curLen,curBlock->text.Length(),1);
 
228
                                found = true;
 
229
                        }
 
230
                }
 
231
                else if (curBlock->GetType() == BLOCK_OVERRIDE) OrigText->AppendText(_T("{") + curBlock->text + _T("}"));
 
232
        }
 
233
        current->ClearBlocks();
 
234
        OrigText->SetReadOnly(true);
 
235
 
 
236
        return true;
 
237
}
 
238
 
 
239
 
 
240
/////////////////////////
 
241
// Updates video preview
 
242
void DialogTranslation::UpdatePreview () {
 
243
        if (enablePreview) {
 
244
                try {
 
245
                        if (VideoContext::Get()->IsLoaded()) {
 
246
                                AssDialogue *cur = grid->GetDialogue(curline);
 
247
                                VideoContext::Get()->JumpToTime(cur->Start.GetMS());
 
248
                        }
 
249
                }
 
250
                catch (...) {
 
251
                        return;
 
252
                }
 
253
        }
 
254
}
 
255
 
 
256
///////////////
 
257
// Event table
 
258
BEGIN_EVENT_TABLE(DialogTranslation, wxDialog)
 
259
        EVT_BUTTON(wxID_CANCEL,DialogTranslation::OnClose)
 
260
        EVT_BUTTON(BUTTON_TRANS_PLAY_VIDEO,DialogTranslation::OnPlayVideoButton)
 
261
        EVT_BUTTON(BUTTON_TRANS_PLAY_AUDIO,DialogTranslation::OnPlayAudioButton)
 
262
END_EVENT_TABLE()
 
263
 
 
264
 
 
265
/////////////////
 
266
// Event handler
 
267
 
 
268
// Constructor
 
269
DialogTranslationEvent::DialogTranslationEvent(DialogTranslation *ctrl) {
 
270
        control = ctrl;
 
271
}
 
272
 
 
273
// Event table
 
274
BEGIN_EVENT_TABLE(DialogTranslationEvent, wxEvtHandler)
 
275
        EVT_KEY_DOWN(DialogTranslationEvent::OnTransBoxKey)
 
276
        EVT_CHECKBOX(PREVIEW_CHECK, DialogTranslationEvent::OnPreviewCheck)
 
277
END_EVENT_TABLE()
 
278
 
 
279
// Redirects
 
280
void DialogTranslationEvent::OnPreviewCheck(wxCommandEvent &event) { control->enablePreview = event.IsChecked(); }
 
281
void DialogTranslationEvent::OnTransBoxKey(wxKeyEvent &event) { control->OnTransBoxKey(event); }
 
282
 
 
283
 
 
284
/////////////////////
 
285
// Key pressed event
 
286
void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) {
 
287
#ifdef __APPLE__
 
288
        Hotkeys.SetPressed(event.GetKeyCode(),event.m_metaDown,event.m_altDown,event.m_shiftDown);
 
289
#else
 
290
        Hotkeys.SetPressed(event.GetKeyCode(),event.m_controlDown,event.m_altDown,event.m_shiftDown);
 
291
#endif
 
292
 
 
293
        // Previous
 
294
        if (Hotkeys.IsPressed(_T("Translation Assistant Prev"))) {
 
295
                bool ok = JumpToLine(curline,curblock-1);
 
296
                if (ok) {
 
297
                        TransText->ClearAll();
 
298
                        TransText->SetFocus();
 
299
                }
 
300
 
 
301
                UpdatePreview();
 
302
                return;
 
303
        }
 
304
 
 
305
        // Next
 
306
        if (Hotkeys.IsPressed(_T("Translation Assistant Next")) || (Hotkeys.IsPressed(_T("Translation Assistant Accept")) && TransText->GetValue().IsEmpty())) {
 
307
                bool ok = JumpToLine(curline,curblock+1);
 
308
                if (ok) {
 
309
                        TransText->ClearAll();
 
310
                        TransText->SetFocus();
 
311
                }
 
312
 
 
313
                UpdatePreview();
 
314
                return;
 
315
        }
 
316
 
 
317
        // Accept (enter)
 
318
        if (Hotkeys.IsPressed(_T("Translation Assistant Accept")) || Hotkeys.IsPressed(_T("Translation Assistant Preview"))) {
 
319
                // Store
 
320
                AssDialogue *cur = grid->GetDialogue(curline);
 
321
                cur->ParseASSTags();
 
322
                int nblock = -1;
 
323
                for (unsigned int i=0;i<cur->Blocks.size();i++) {
 
324
                        if (cur->Blocks.at(i)->GetType() == BLOCK_PLAIN) nblock++;
 
325
                        if (nblock == curblock) {
 
326
                                cur->Blocks.at(i)->text = TransText->GetValue();
 
327
                                break;
 
328
                        }
 
329
                }
 
330
                
 
331
                // Update line
 
332
                cur->UpdateText();
 
333
                cur->UpdateData();
 
334
                cur->ClearBlocks();
 
335
                subs->FlagAsModified(_("translation assistant"));
 
336
                grid->CommitChanges();
 
337
                ((FrameMain*)main)->UpdateTitle();
 
338
                UpdatePreview();
 
339
 
 
340
                // Next
 
341
                if (Hotkeys.IsPressed(_T("Translation Assistant Accept"))) {
 
342
                        // JumpToLine() returns false if the requested line doesn't exist.
 
343
                        // Assume that means we were on the last line.
 
344
                        if (!JumpToLine(curline,curblock+1)) {
 
345
                                wxMessageBox(_("No more lines to translate."));
 
346
                                EndModal(1);
 
347
                                return;
 
348
                        }
 
349
                        TransText->ClearAll();
 
350
                        TransText->SetFocus();
 
351
                }
 
352
                else JumpToLine(curline,curblock);
 
353
                return;
 
354
        }
 
355
 
 
356
        // Insert original text (insert)
 
357
        if (Hotkeys.IsPressed(_T("Translation Assistant Insert Original"))) {
 
358
                using std::vector;
 
359
                AssDialogueBlock *curBlock;
 
360
                int pos = -1;
 
361
                current->ParseASSTags();
 
362
                for (vector<AssDialogueBlock*>::iterator cur=current->Blocks.begin();cur!=current->Blocks.end();cur++) {
 
363
                        curBlock = *cur;
 
364
                        if (curBlock->GetType() == BLOCK_PLAIN) {
 
365
                                pos++;
 
366
                                if (pos == curblock) {
 
367
                                        TransText->AddText(curBlock->text);
 
368
                                }
 
369
                        }
 
370
                }
 
371
                current->ClearBlocks();
 
372
                return;
 
373
        }
 
374
 
 
375
        // Play video
 
376
        if (Hotkeys.IsPressed(_T("Translation Assistant Play Video"))) {
 
377
                if (video->IsLoaded()) {
 
378
                        video->PlayLine();
 
379
                        TransText->SetFocus();
 
380
                }
 
381
                return;
 
382
        }
 
383
 
 
384
        // Play audio
 
385
        if (Hotkeys.IsPressed(_T("Translation Assistant Play Audio"))) {
 
386
                if (audio->loaded) {
 
387
                        audio->Play(current->Start.GetMS(),current->End.GetMS());
 
388
                        TransText->SetFocus();
 
389
                }
 
390
                return;
 
391
        }
 
392
 
 
393
        // Close
 
394
        if (event.GetKeyCode() == WXK_ESCAPE) EndModal(1);
 
395
 
 
396
        // Ignore enter
 
397
        if (event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER) return;
 
398
 
 
399
        // Skip anything else
 
400
        event.Skip();
 
401
}
 
402
 
 
403
 
 
404
/////////////////////
 
405
// Play video button
 
406
void DialogTranslation::OnPlayVideoButton(wxCommandEvent &event) {
 
407
        video->PlayLine();
 
408
        TransText->SetFocus();
 
409
}
 
410
 
 
411
 
 
412
/////////////////////
 
413
// Play audio button
 
414
void DialogTranslation::OnPlayAudioButton(wxCommandEvent &event) {
 
415
        audio->Play(current->Start.GetMS(),current->End.GetMS());
 
416
        TransText->SetFocus();
 
417
}
 
418
 
 
419
 
 
420
/////////
 
421
// Close
 
422
void DialogTranslation::OnClose (wxCommandEvent &event) {
 
423
        GetPosition(&lastx, &lasty);
 
424
        TransText->PopEventHandler(true);
 
425
        PreviewCheck->PopEventHandler(true);
 
426
        EndModal(0);
 
427
}
 
428
 
 
429
 
 
430
////////////
 
431
// Minimize
 
432
void DialogTranslation::OnMinimize (wxIconizeEvent &event) {
 
433
        //Iconize(true);
 
434
        if (main) ((wxFrame*)main)->Iconize(true);
 
435
        event.Skip();
 
436
}
 
437
 
 
438
 
 
439
int DialogTranslation::lastx = -1;
 
440
int DialogTranslation::lasty = -1;