Aegisub/aegisub/src/subs_edit_box.cpp

1443 lines
38 KiB
C++
Raw Normal View History

2006-01-16 22:02:54 +01:00
// 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/
2006-01-16 22:02:54 +01:00
//
// $Id$
/// @file subs_edit_box.cpp
/// @brief Main subtitle editing area, including toolbars around the text control
/// @ingroup main_ui
///
2006-01-16 22:02:54 +01:00
////////////
// Includes
#include "config.h"
#ifndef AGI_PRE
#include <wx/colordlg.h>
#include <wx/fontdlg.h>
#endif
2006-01-16 22:02:54 +01:00
#include "ass_dialogue.h"
#include "ass_file.h"
2006-01-16 22:02:54 +01:00
#include "ass_override.h"
#include "ass_style.h"
2006-01-16 22:02:54 +01:00
#include "audio_display.h"
#include "dialog_colorpicker.h"
#include "dialog_search_replace.h"
#include "frame_main.h"
#include "hilimod_textctrl.h"
#include "idle_field_event.h"
#include "libresrc/libresrc.h"
#include "main.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "timeedit_ctrl.h"
#include "tooltip_manager.h"
#include "utils.h"
#include "validators.h"
#include "video_context.h"
#include "video_display.h"
2006-01-16 22:02:54 +01:00
/// @brief Constructor
/// @param parent
/// @param gridp
///
2006-01-16 22:02:54 +01:00
SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxRAISED_BORDER, _T("SubsEditBox"))
{
// Setup
audio = NULL;
grid = gridp;
grid->editBox = this;
enabled = false;
textEditReady = true;
controlState = true;
setupDone = false;
2006-01-16 22:02:54 +01:00
// Top controls
wxArrayString styles;
styles.Add(_T("Default"));
2006-01-16 22:02:54 +01:00
CommentBox = new wxCheckBox(this,COMMENT_CHECKBOX,_("Comment"));
CommentBox->SetToolTip(_("Comment this line out. Commented lines don't show up on screen."));
StyleBox = new wxComboBox(this,STYLE_COMBOBOX,_T("Default"),wxDefaultPosition,wxSize(110,-1),styles,wxCB_READONLY | wxTE_PROCESS_ENTER);
2006-01-16 22:02:54 +01:00
StyleBox->SetToolTip(_("Style for this line."));
ActorBox = new wxComboBox(this,ACTOR_COMBOBOX,_T("Actor"),wxDefaultPosition,wxSize(110,-1),styles,wxCB_DROPDOWN | wxTE_PROCESS_ENTER);
2006-01-16 22:02:54 +01:00
ActorBox->SetToolTip(_("Actor name for this speech. This is only for reference, and is mainly useless."));
ActorBox->PushEventHandler(new IdleFieldHandler(ActorBox,_("Actor")));
Effect = new HiliModTextCtrl(this,EFFECT_BOX,_T(""),wxDefaultPosition,wxSize(80,-1),wxTE_PROCESS_ENTER);
Effect->SetToolTip(_("Effect for this line. This can be used to store extra information for karaoke scripts, or for the effects supported by the renderer."));
Effect->PushEventHandler(new IdleFieldHandler(Effect,_("Effect")));
2006-01-16 22:02:54 +01:00
// Middle controls
Layer = new wxSpinCtrl(this,LAYER_BOX,_T(""),wxDefaultPosition,wxSize(50,-1),wxSP_ARROW_KEYS,0,0x7FFFFFFF,0);
2006-01-16 22:02:54 +01:00
Layer->SetToolTip(_("Layer number"));
StartTime = new TimeEdit(this,STARTTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,-1),wxTE_PROCESS_ENTER);
2006-01-16 22:02:54 +01:00
StartTime->SetToolTip(_("Start time"));
StartTime->showModified = true;
EndTime = new TimeEdit(this,ENDTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,-1),wxTE_PROCESS_ENTER);
2006-01-16 22:02:54 +01:00
EndTime->SetToolTip(_("End time"));
EndTime->isEnd = true;
EndTime->showModified = true;
Duration = new TimeEdit(this,DURATION_BOX,_T(""),wxDefaultPosition,wxSize(75,-1),wxTE_PROCESS_ENTER);
2006-01-16 22:02:54 +01:00
Duration->SetToolTip(_("Line duration"));
Duration->showModified = true;
MarginL = new HiliModTextCtrl(this,MARGINL_BOX,_T(""),wxDefaultPosition,wxSize(40,-1),wxTE_CENTRE | wxTE_PROCESS_ENTER,NumValidator());
MarginL->SetToolTip(_("Left Margin (0 = default)"));
MarginL->SetMaxLength(4);
MarginR = new HiliModTextCtrl(this,MARGINR_BOX,_T(""),wxDefaultPosition,wxSize(40,-1),wxTE_CENTRE | wxTE_PROCESS_ENTER,NumValidator());
MarginR->SetToolTip(_("Right Margin (0 = default)"));
MarginR->SetMaxLength(4);
MarginV = new HiliModTextCtrl(this,MARGINV_BOX,_T(""),wxDefaultPosition,wxSize(40,-1),wxTE_CENTRE | wxTE_PROCESS_ENTER,NumValidator());
MarginV->SetToolTip(_("Vertical Margin (0 = default)"));
MarginV->SetMaxLength(4);
2006-01-16 22:02:54 +01:00
// Middle-bottom controls
Bold = new wxBitmapButton(this,BUTTON_BOLD,GETIMAGE(button_bold_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Bold->SetToolTip(_("Bold"));
Italics = new wxBitmapButton(this,BUTTON_ITALICS,GETIMAGE(button_italics_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Italics->SetToolTip(_("Italics"));
Underline = new wxBitmapButton(this,BUTTON_UNDERLINE,GETIMAGE(button_underline_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Underline->SetToolTip(_("Underline"));
Strikeout = new wxBitmapButton(this,BUTTON_STRIKEOUT,GETIMAGE(button_strikeout_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Strikeout->SetToolTip(_("Strikeout"));
FontName = new wxBitmapButton(this,BUTTON_FONT_NAME,GETIMAGE(button_fontname_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
FontName->SetToolTip(_("Font Face Name"));
Color1 = new wxBitmapButton(this,BUTTON_COLOR1,GETIMAGE(button_color_one_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Color1->SetToolTip(_("Primary color"));
Color2 = new wxBitmapButton(this,BUTTON_COLOR2,GETIMAGE(button_color_two_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Color2->SetToolTip(_("Secondary color"));
Color3 = new wxBitmapButton(this,BUTTON_COLOR3,GETIMAGE(button_color_three_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Color3->SetToolTip(_("Outline color"));
Color4 = new wxBitmapButton(this,BUTTON_COLOR4,GETIMAGE(button_color_four_16),wxDefaultPosition,wxDefaultSize);
2006-01-16 22:02:54 +01:00
Color4->SetToolTip(_("Shadow color"));
CommitButton = new wxBitmapButton(this,BUTTON_COMMIT,GETIMAGE(button_audio_commit_16),wxDefaultPosition,wxDefaultSize);
ToolTipManager::Bind(CommitButton,_("Commits the text (Enter). Hold Ctrl to stay in line (%KEY%)."),_T("Edit Box Commit"));
ByTime = new wxRadioButton(this,RADIO_TIME_BY_TIME,_("Time"),wxDefaultPosition,wxDefaultSize,wxRB_GROUP);
ByTime->SetToolTip(_("Time by h:mm:ss.cs"));
ByFrame = new wxRadioButton(this,RADIO_TIME_BY_FRAME,_("Frame"));
ByFrame->SetToolTip(_("Time by frame number"));
// Top sizer
TopSizer = new wxBoxSizer(wxHORIZONTAL);
TopSizer->Add(CommentBox,0,wxRIGHT | wxALIGN_CENTER,5);
TopSizer->Add(StyleBox,2,wxRIGHT|wxALIGN_CENTER,5);
TopSizer->Add(ActorBox,2,wxRIGHT|wxALIGN_CENTER,5);
TopSizer->Add(Effect,3,wxALIGN_CENTER,5);
// Middle sizer
splitLineMode = true;
MiddleSizer = new wxBoxSizer(wxHORIZONTAL);
MiddleSizer->Add(Layer,0,wxRIGHT|wxALIGN_CENTER,5);
MiddleSizer->Add(StartTime,0,wxRIGHT|wxALIGN_CENTER,0);
MiddleSizer->Add(EndTime,0,wxRIGHT|wxALIGN_CENTER,5);
MiddleSizer->Add(Duration,0,wxRIGHT|wxALIGN_CENTER,5);
MiddleSizer->Add(MarginL,0,wxALIGN_CENTER,0);
MiddleSizer->Add(MarginR,0,wxALIGN_CENTER,0);
MiddleSizer->Add(MarginV,0,wxALIGN_CENTER,0);
MiddleSizer->AddSpacer(5);
2006-01-16 22:02:54 +01:00
// Middle-bottom sizer
MiddleBotSizer = new wxBoxSizer(wxHORIZONTAL);
MiddleBotSizer->Add(Bold,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Italics,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Underline,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Strikeout,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(FontName,0,wxALIGN_CENTER|wxEXPAND,0);
2006-01-16 22:02:54 +01:00
MiddleBotSizer->AddSpacer(5);
MiddleBotSizer->Add(Color1,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Color2,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Color3,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->Add(Color4,0,wxALIGN_CENTER|wxEXPAND,0);
MiddleBotSizer->AddSpacer(5);
MiddleBotSizer->Add(CommitButton,0,wxALIGN_CENTER,0);
MiddleBotSizer->AddSpacer(10);
MiddleBotSizer->Add(ByTime,0,wxRIGHT | wxALIGN_CENTER | wxEXPAND,5);
MiddleBotSizer->Add(ByFrame,0,wxRIGHT | wxALIGN_CENTER | wxEXPAND,5);
2006-01-16 22:02:54 +01:00
// Text editor
int textStyle = wxBORDER_SUNKEN;
TextEdit = new SubsTextEditCtrl(this,EDIT_BOX,_T(""),wxDefaultPosition,wxSize(300,50),textStyle);
2006-01-16 22:02:54 +01:00
TextEdit->PushEventHandler(new SubsEditBoxEvent(this));
TextEdit->control = this;
BottomSizer = new wxBoxSizer(wxHORIZONTAL);
2006-01-16 22:02:54 +01:00
BottomSizer->Add(TextEdit,1,wxEXPAND,0);
// Main sizer
MainSizer = new wxBoxSizer(wxVERTICAL);
MainSizer->Add(TopSizer,0,wxEXPAND | wxALL,3);
2006-01-16 22:02:54 +01:00
MainSizer->Add(MiddleSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
MainSizer->Add(MiddleBotSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
MainSizer->Add(BottomSizer,1,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
// Set sizer
SetSizer(MainSizer);
MainSizer->SetSizeHints(this);
// HACK: Fix colour of bg of editbox
origBgColour = TextEdit->GetBackgroundColour();
disabledBgColour = GetBackgroundColour();
// Set split mode
setupDone = true;
SetSplitLineMode();
Update();
grid->AddSelectionListener(this);
2006-01-16 22:02:54 +01:00
}
/// @brief Destructor
///
SubsEditBox::~SubsEditBox() {
grid->RemoveSelectionListener(this);
ActorBox->PopEventHandler(true);
Effect->PopEventHandler(true);
TextEdit->PopEventHandler(true);
}
/// @brief Set split or single line mode
/// @param newSize
///
void SubsEditBox::SetSplitLineMode(wxSize newSize) {
// Widths
int topWidth;
if (newSize.GetWidth() == -1) topWidth = TopSizer->GetSize().GetWidth();
else topWidth = newSize.GetWidth()-GetSize().GetWidth()+GetClientSize().GetWidth();
int midMin = MiddleSizer->GetMinSize().GetWidth();
int botMin = MiddleBotSizer->GetMinSize().GetWidth();
// Currently split
if (splitLineMode) {
if (topWidth >= midMin + botMin) {
MainSizer->Detach(MiddleBotSizer);
MiddleSizer->Add(MiddleBotSizer,0,wxALIGN_CENTER_VERTICAL);
Layout();
splitLineMode = false;
}
}
// Currently joined
else {
if (topWidth < midMin) {
MiddleSizer->Detach(MiddleBotSizer);
MainSizer->Insert(2,MiddleBotSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,3);
Layout();
splitLineMode = true;
}
}
}
/// @brief Update function
/// @param timeOnly
/// @param weak
///
void SubsEditBox::Update (bool timeOnly,bool weak) {
2006-01-16 22:02:54 +01:00
if (enabled) {
AssDialogue *curdiag = grid->GetActiveLine();
2006-01-16 22:02:54 +01:00
if (curdiag) {
// Controls
SetControlsState(true);
int start = curdiag->Start.GetMS();
int end = curdiag->End.GetMS();
StartTime->SetTime(start);
StartTime->Update();
2006-01-16 22:02:54 +01:00
EndTime->SetTime(end);
EndTime->Update();
2006-01-16 22:02:54 +01:00
Duration->SetTime(end-start);
Duration->Update();
2006-01-16 22:02:54 +01:00
if (!timeOnly) {
TextEdit->SetTextTo(curdiag->Text);
Layer->SetValue(curdiag->Layer);
MarginL->SetValue(curdiag->GetMarginString(0,false));
MarginR->SetValue(curdiag->GetMarginString(1,false));
MarginV->SetValue(curdiag->GetMarginString(2,false));
Effect->SetValue(curdiag->Effect);
2006-01-16 22:02:54 +01:00
CommentBox->SetValue(curdiag->Comment);
StyleBox->Select(StyleBox->FindString(curdiag->Style));
2006-01-16 22:02:54 +01:00
ActorBox->SetValue(curdiag->Actor);
ActorBox->SetStringSelection(curdiag->Actor);
// Force actor box to update its idle status
wxCommandEvent changeEvent(wxEVT_COMMAND_TEXT_UPDATED,ActorBox->GetId());
ActorBox->GetEventHandler()->AddPendingEvent(changeEvent);
2006-01-16 22:02:54 +01:00
}
// Audio
if (!weak) audio->SetDialogue(grid,curdiag,grid->GetDialogueIndex(curdiag));
2006-01-16 22:02:54 +01:00
TextEdit->EmptyUndoBuffer();
2006-01-16 22:02:54 +01:00
}
else enabled = false;
}
else {
SetControlsState(false);
}
}
/// @brief Update globals
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::UpdateGlobals () {
// Styles
StyleBox->Clear();
StyleBox->Append(grid->ass->GetStyles());
// Actors
ActorBox->Freeze();
ActorBox->Clear();
int nrows = grid->GetRows();
wxString actor;
for (int i=0;i<nrows;i++) {
actor = grid->GetDialogue(i)->Actor;
// OSX doesn't like combo boxes that are empty.
if (actor == "") actor = _T("Actor");
2006-01-16 22:02:54 +01:00
if (ActorBox->FindString(actor) == wxNOT_FOUND) {
ActorBox->Append(actor);
}
}
ActorBox->Thaw();
// Set subs update
OnActiveLineChanged(grid->GetActiveLine());
2006-01-16 22:02:54 +01:00
TextEdit->SetSelection(0,0);
}
2006-01-16 22:02:54 +01:00
///////////////
// Event table
BEGIN_EVENT_TABLE(SubsEditBox, wxPanel)
EVT_STC_MODIFIED(EDIT_BOX,SubsEditBox::OnEditText)
EVT_STC_STYLENEEDED(EDIT_BOX,SubsEditBox::OnNeedStyle)
EVT_STC_KEY(EDIT_BOX,SubsEditBox::OnKeyDown)
EVT_STC_CHARADDED(EDIT_BOX,SubsEditBox::OnCharAdded)
EVT_STC_UPDATEUI(EDIT_BOX,SubsEditBox::OnUpdateUI)
2006-01-16 22:02:54 +01:00
EVT_CHECKBOX(SYNTAX_BOX, SubsEditBox::OnSyntaxBox)
EVT_RADIOBUTTON(RADIO_TIME_BY_FRAME, SubsEditBox::OnFrameRadio)
EVT_RADIOBUTTON(RADIO_TIME_BY_TIME, SubsEditBox::OnTimeRadio)
EVT_COMBOBOX(STYLE_COMBOBOX, SubsEditBox::OnStyleChange)
EVT_COMBOBOX(ACTOR_COMBOBOX, SubsEditBox::OnActorChange)
EVT_TEXT_ENTER(ACTOR_COMBOBOX, SubsEditBox::OnActorChange)
EVT_TEXT_ENTER(LAYER_BOX, SubsEditBox::OnLayerEnter)
EVT_SPINCTRL(LAYER_BOX, SubsEditBox::OnLayerChange)
2006-01-16 22:02:54 +01:00
EVT_TEXT_ENTER(STARTTIME_BOX, SubsEditBox::OnStartTimeChange)
EVT_TEXT_ENTER(ENDTIME_BOX, SubsEditBox::OnEndTimeChange)
EVT_TEXT_ENTER(DURATION_BOX, SubsEditBox::OnDurationChange)
EVT_TEXT_ENTER(MARGINL_BOX, SubsEditBox::OnMarginLChange)
EVT_TEXT_ENTER(MARGINR_BOX, SubsEditBox::OnMarginRChange)
EVT_TEXT_ENTER(MARGINV_BOX, SubsEditBox::OnMarginVChange)
EVT_TEXT_ENTER(EFFECT_BOX, SubsEditBox::OnEffectChange)
2006-01-16 22:02:54 +01:00
EVT_CHECKBOX(COMMENT_CHECKBOX, SubsEditBox::OnCommentChange)
EVT_BUTTON(BUTTON_COLOR1,SubsEditBox::OnButtonColor1)
EVT_BUTTON(BUTTON_COLOR2,SubsEditBox::OnButtonColor2)
EVT_BUTTON(BUTTON_COLOR3,SubsEditBox::OnButtonColor3)
EVT_BUTTON(BUTTON_COLOR4,SubsEditBox::OnButtonColor4)
EVT_BUTTON(BUTTON_FONT_NAME,SubsEditBox::OnButtonFontFace)
EVT_BUTTON(BUTTON_BOLD,SubsEditBox::OnButtonBold)
EVT_BUTTON(BUTTON_ITALICS,SubsEditBox::OnButtonItalics)
EVT_BUTTON(BUTTON_UNDERLINE,SubsEditBox::OnButtonUnderline)
EVT_BUTTON(BUTTON_STRIKEOUT,SubsEditBox::OnButtonStrikeout)
EVT_BUTTON(BUTTON_COMMIT,SubsEditBox::OnButtonCommit)
EVT_SIZE(SubsEditBox::OnSize)
2006-01-16 22:02:54 +01:00
END_EVENT_TABLE()
/// @brief On size
/// @param event
///
void SubsEditBox::OnSize(wxSizeEvent &event) {
if (setupDone) SetSplitLineMode(event.GetSize());
event.Skip();
}
/// @brief Text edited event
/// @param event
///
void SubsEditBox::OnEditText(wxStyledTextEvent &event) {
int modType = event.GetModificationType();
if (modType == (wxSTC_MOD_INSERTTEXT | wxSTC_PERFORMED_USER) || modType == (wxSTC_MOD_DELETETEXT | wxSTC_PERFORMED_USER)) {
//TextEdit->UpdateCallTip();
}
}
/// @brief User Interface updated
/// @param event
///
void SubsEditBox::OnUpdateUI(wxStyledTextEvent &event) {
TextEdit->UpdateCallTip();
}
/// @brief Need style
/// @param event
///
void SubsEditBox::OnNeedStyle(wxStyledTextEvent &event) {
// Check if it needs to fix text
wxString text = TextEdit->GetText();
if (text.Contains(_T("\n")) || text.Contains(_T("\r"))) {
TextEdit->SetTextTo(TextEdit->GetText());
2006-01-16 22:02:54 +01:00
}
// Just update style
else TextEdit->UpdateStyle();
2006-01-16 22:02:54 +01:00
}
/// @brief Character added
/// @param event
///
void SubsEditBox::OnCharAdded(wxStyledTextEvent &event) {
//int character = event.GetKey();
}
/// @brief Key down
/// @param event
///
void SubsEditBox::OnKeyDown(wxStyledTextEvent &event) {
2007-01-02 19:28:09 +01:00
}
/// @brief Syntax highlight checkbox
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnSyntaxBox(wxCommandEvent &event) {
TextEdit->UpdateStyle();
OPT_SET("Subtitle/Highlight/Syntax")->SetBool(SyntaxHighlight->GetValue());
2006-01-16 22:02:54 +01:00
event.Skip();
}
/// @brief Time by frame radiobox
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnFrameRadio(wxCommandEvent &event) {
if (ByFrame->GetValue()) {
StartTime->SetByFrame(true);
EndTime->SetByFrame(true);
Duration->SetByFrame(true);
2006-01-16 22:02:54 +01:00
grid->SetByFrame(true);
}
event.Skip();
}
/// @brief Standard time radiobox
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnTimeRadio(wxCommandEvent &event) {
if (ByTime->GetValue()) {
StartTime->SetByFrame(false);
EndTime->SetByFrame(false);
Duration->SetByFrame(false);
2006-01-16 22:02:54 +01:00
grid->SetByFrame(false);
}
event.Skip();
}
/// @brief Sets state (enabled/disabled) for all controls
/// @param state
/// @return
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::SetControlsState (bool state) {
if (state == controlState) return;
controlState = state;
// HACK: TextEdit workaround the stupid colour lock bug
TextEdit->SetReadOnly(!state);
2006-01-16 22:02:54 +01:00
if (state) TextEdit->SetBackgroundColour(origBgColour);
else TextEdit->SetBackgroundColour(disabledBgColour);
// Sets controls
StartTime->Enable(state);
EndTime->Enable(state);
Duration->Enable(state);
Layer->Enable(state);
MarginL->Enable(state);
MarginR->Enable(state);
MarginV->Enable(state);
Effect->Enable(state);
2006-01-16 22:02:54 +01:00
CommentBox->Enable(state);
StyleBox->Enable(state);
ActorBox->Enable(state);
ByTime->Enable(state);
//SyntaxHighlight->Enable(state);
2006-01-16 22:02:54 +01:00
Bold->Enable(state);
Italics->Enable(state);
Underline->Enable(state);
Strikeout->Enable(state);
Color1->Enable(state);
Color2->Enable(state);
Color3->Enable(state);
Color4->Enable(state);
FontName->Enable(state);
CommitButton->Enable(state);
2006-01-16 22:02:54 +01:00
UpdateFrameTiming();
// Clear values if it's false
if (state==false) {
TextEdit->SetTextTo(_T(""));
2006-01-16 22:02:54 +01:00
StartTime->SetTime(0);
EndTime->SetTime(0);
Duration->SetTime(0);
2006-01-16 22:02:54 +01:00
Layer->SetValue(_T(""));
MarginL->SetValue(_T(""));
MarginR->SetValue(_T(""));
MarginV->SetValue(_T(""));
Effect->SetValue(_T(""));
2006-01-16 22:02:54 +01:00
CommentBox->SetValue(false);
}
}
/// @brief Disables or enables frame timing
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::UpdateFrameTiming () {
if (VideoContext::Get()->TimecodesLoaded()) ByFrame->Enable(enabled);
2006-01-16 22:02:54 +01:00
else {
ByFrame->Enable(false);
ByTime->SetValue(true);
StartTime->SetByFrame(false);
EndTime->SetByFrame(false);
grid->SetByFrame(false);
}
}
/// @brief Style changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnStyleChange(wxCommandEvent &event) {
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur;
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Style = StyleBox->GetValue();
}
}
grid->ass->Commit(_("style change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Style changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnActorChange(wxCommandEvent &event) {
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
AssDialogue *cur;
wxString actor = ActorBox->GetValue();
// Update rows
int n = sel.Count();
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Actor = actor;
}
}
// Add actor to list
if (ActorBox->GetString(0).IsEmpty()) ActorBox->Delete(0);
2006-01-16 22:02:54 +01:00
if (ActorBox->FindString(actor) == wxNOT_FOUND) {
ActorBox->Append(actor);
}
// Update grid
grid->ass->Commit(_("actor change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Layer changed with spin
/// @param event
///
void SubsEditBox::OnLayerChange(wxSpinEvent &event) {
// Value
long temp = event.GetPosition();
// Get selection
2006-01-16 22:02:54 +01:00
wxArrayInt sel = grid->GetSelection();
// Update
2006-01-16 22:02:54 +01:00
int n = sel.Count();
AssDialogue *cur;
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Layer = temp;
}
}
// Done
grid->ass->Commit(_("layer change"));
grid->CommitChanges();
}
/// @brief Layer changed with enter
/// @param event
///
void SubsEditBox::OnLayerEnter(wxCommandEvent &event) {
// Value
long temp = Layer->GetValue();
// Get selection
wxArrayInt sel = grid->GetSelection();
// Update
int n = sel.Count();
AssDialogue *cur;
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Layer = temp;
}
}
// Done
grid->ass->Commit(_("layer change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
}
/// @brief Start time changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnStartTimeChange(wxCommandEvent &event) {
if (StartTime->time > EndTime->time) StartTime->SetTime(EndTime->time.GetMS());
bool join = OPT_GET("Subtitle/Edit Box/Link Time Boxes Commit")->GetBool() && EndTime->HasBeenModified();
2006-01-16 22:02:54 +01:00
StartTime->Update();
Duration->Update();
2006-01-16 22:02:54 +01:00
if (join) EndTime->Update();
CommitTimes(true,join,true);
2006-01-16 22:02:54 +01:00
}
/// @brief End time changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnEndTimeChange(wxCommandEvent &event) {
if (StartTime->time > EndTime->time) EndTime->SetTime(StartTime->time.GetMS());
bool join = OPT_GET("Subtitle/Edit Box/Link Time Boxes Commit")->GetBool() && StartTime->HasBeenModified();
2006-01-16 22:02:54 +01:00
EndTime->Update();
Duration->Update();
2006-01-16 22:02:54 +01:00
if (join) StartTime->Update();
CommitTimes(join,true,false);
2006-01-16 22:02:54 +01:00
}
/// @brief Duration changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnDurationChange(wxCommandEvent &event) {
EndTime->SetTime(StartTime->time.GetMS() + Duration->time.GetMS());
StartTime->Update();
EndTime->Update();
2006-01-16 22:02:54 +01:00
Duration->Update();
CommitTimes(false,true,true);
2006-01-16 22:02:54 +01:00
}
/// @brief Commit time changes
/// @param start
/// @param end
/// @param fromStart
/// @param commit
/// @return
///
void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) {
2006-01-16 22:02:54 +01:00
// Get selection
if (!start && !end) return;
Selection sel;
grid->GetSelectedSet(sel);
if (sel.size() == 0) return;
2006-01-16 22:02:54 +01:00
AssDialogue *cur;
Duration->SetTime(EndTime->time.GetMS() - StartTime->time.GetMS());
// Update lines
for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) {
if (sel.find(grid->GetActiveLine()) != sel.end()) cur = *it;
else cur = grid->GetActiveLine();
2006-01-16 22:02:54 +01:00
if (cur) {
// Set times
2006-01-16 22:02:54 +01:00
if (start) cur->Start = StartTime->time;
if (end) cur->End = EndTime->time;
// Ensure that they have positive length
if (cur->Start > cur->End) {
if (fromStart) cur->End = cur->Start;
else cur->Start = cur->End;
}
if (sel.find(grid->GetActiveLine()) == sel.end()) break;
2006-01-16 22:02:54 +01:00
}
}
// Commit
if (commit) {
StartTime->Update();
EndTime->Update();
Duration->Update();
grid->ass->Commit(_("modify times"));
grid->CommitChanges();
int sel0 = grid->GetFirstSelRow();
audio->SetDialogue(grid,grid->GetDialogue(sel0),sel0);
VideoContext::Get()->UpdateDisplays(false);
}
2006-01-16 22:02:54 +01:00
}
/// @brief Margin L changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnMarginLChange(wxCommandEvent &event) {
MarginL->Commited();
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur = NULL;
2006-01-16 22:02:54 +01:00
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->SetMarginString(MarginL->GetValue(),0);
2006-01-16 22:02:54 +01:00
}
}
MarginL->SetValue(cur->GetMarginString(0,false));
grid->ass->Commit(_("MarginL change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Margin R changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnMarginRChange(wxCommandEvent &event) {
MarginR->Commited();
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur = NULL;
2006-01-16 22:02:54 +01:00
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->SetMarginString(MarginR->GetValue(),1);
2006-01-16 22:02:54 +01:00
}
}
MarginR->SetValue(cur->GetMarginString(1,false));
grid->ass->Commit(_("MarginR change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Margin V changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnMarginVChange(wxCommandEvent &event) {
MarginV->Commited();
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur = NULL;
2006-01-16 22:02:54 +01:00
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->SetMarginString(MarginV->GetValue(),2);
cur->SetMarginString(MarginV->GetValue(),3); // also bottom margin for now
2006-01-16 22:02:54 +01:00
}
}
MarginV->SetValue(cur->GetMarginString(2,false));
grid->ass->Commit(_("MarginV change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Effect changed
/// @param event
///
void SubsEditBox::OnEffectChange(wxCommandEvent &event) {
Effect->Commited();
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur;
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Effect = Effect->GetValue();
}
}
grid->ass->Commit(_("effect change"));
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Comment state changed
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnCommentChange(wxCommandEvent &event) {
grid->BeginBatch();
wxArrayInt sel = grid->GetSelection();
int n = sel.Count();
AssDialogue *cur;
for (int i=0;i<n;i++) {
cur = grid->GetDialogue(sel[i]);
if (cur) {
cur->Comment = CommentBox->GetValue();
}
}
grid->ass->Commit(_("comment change"));
2006-01-16 22:02:54 +01:00
grid->CommitChanges();
grid->EndBatch();
}
/// @brief Event handler class
/// @param _control
///
2006-01-16 22:02:54 +01:00
SubsEditBoxEvent::SubsEditBoxEvent(SubsEditBox *_control) {
control = _control;
}
BEGIN_EVENT_TABLE(SubsEditBoxEvent, wxEvtHandler)
EVT_KEY_DOWN(SubsEditBoxEvent::OnKeyPress)
END_EVENT_TABLE()
/// @brief DOCME
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBoxEvent::OnKeyPress(wxKeyEvent &event) {
control->DoKeyPress(event);
2006-01-16 22:02:54 +01:00
}
/// @brief Actual text changed
/// @param event
/// @return
///
void SubsEditBox::DoKeyPress(wxKeyEvent &event) {
2006-01-16 22:02:54 +01:00
int key = event.GetKeyCode();
if (key == WXK_RETURN || key == WXK_NUMPAD_ENTER) {
if (enabled) {
#ifdef __APPLE__
Commit(event.m_metaDown);
#else
Commit(event.m_controlDown);
#endif
2006-01-16 22:02:54 +01:00
return;
}
}
event.Skip();
}
/// @brief Commit
/// @param stay
/// @return
///
void SubsEditBox::Commit(bool stay) {
// Record pre-commit data
AssDialogue *old_line = grid->GetActiveLine();
wxString oldText = old_line->Text;
int oldStart = old_line->Start.GetMS();
int oldEnd = old_line->End.GetMS();
// Update line
CommitText();
// Change text/time if needed for all selected lines
bool textNeedsCommit = old_line->Text != oldText;
bool timeNeedsCommit = old_line->Start.GetMS() != oldStart || old_line->End.GetMS() != oldEnd;
Selection sel;
grid->GetSelectedSet(sel);
if (sel.find(old_line) != sel.end()) {
for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) {
if (textNeedsCommit) {
(*it)->Text = TextEdit->GetText();
}
if (timeNeedsCommit) {
(*it)->Start.SetMS(StartTime->time.GetMS());
(*it)->End.SetMS(EndTime->time.GetMS());
}
}
}
// Update file
if (textNeedsCommit) {
grid->ass->Commit(_("editing"));
grid->CommitChanges();
}
else if (StartTime->HasBeenModified() || EndTime->HasBeenModified()) {
CommitTimes(StartTime->HasBeenModified(),EndTime->HasBeenModified(),StartTime->HasBeenModified(),true);
}
// Get next line if ctrl was not held down
if (!stay) {
int next;
if (sel.find(old_line) == sel.end())
next = grid->GetDialogueIndex(old_line)+1;
else
next = grid->GetLastSelRow()+1;
AssDialogue *cur = grid->GetDialogue(next-1);
if (next >= grid->GetRows()) {
AssDialogue *newline = new AssDialogue;
newline->Start = cur->End;
newline->End.SetMS(cur->End.GetMS()+OPT_GET("Timing/Default Duration")->GetInt());
newline->Style = cur->Style;
grid->InsertLine(newline,next-1,true,true);
}
grid->SelectRow(next);
grid->MakeCellVisible(next,0);
grid->SetActiveLine(grid->GetDialogue(next));
}
}
/// @brief Commit text
/// @param weak
///
void SubsEditBox::CommitText(bool weak) {
AssDialogue *cur = grid->GetActiveLine();
2006-01-16 22:02:54 +01:00
// Update line
if (cur) {
// Update text
cur->Text = TextEdit->GetText();
// Update times
if (grid->IsInSelection(grid->GetDialogueIndex(cur))) {
cur->Start = StartTime->time;
cur->End = EndTime->time;
if (cur->Start > cur->End) {
cur->End = cur->Start;
EndTime->SetTime(cur->End.GetMS());
}
}
// Update audio
if (!weak) {
grid->Refresh(false);
audio->SetDialogue(grid,cur,grid->GetDialogueIndex(cur));
}
2006-01-16 22:02:54 +01:00
}
}
/// @brief Gets block number at text position
/// @param pos
/// @return
///
2006-01-16 22:02:54 +01:00
int SubsEditBox::BlockAtPos(int pos) {
// Prepare
int n=0;
wxString text = TextEdit->GetText();;
2006-01-16 22:02:54 +01:00
int max = text.Length()-1;
// Find block number at pos
for (int i=0;i<=pos && i<=max;i++) {
2006-01-16 22:02:54 +01:00
if (i > 0 && text[i] == _T('{')) n++;
if (text[i] == _T('}') && i != max && i != pos && i != pos -1 && (i+1 == max || text[i+1] != _T('{'))) n++;
}
return n;
}
/// @brief Set override
/// @param tagname
/// @param preValue
/// @param forcePos
/// @param getFocus
/// @return
///
void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,bool getFocus) {
2006-01-16 22:02:54 +01:00
// Selection
int selstart, selend;
2006-01-16 22:02:54 +01:00
if (forcePos != -1) {
selstart = forcePos;
selend = forcePos;
}
else TextEdit->GetSelection(&selstart,&selend);
int len = TextEdit->GetText().Length();
selstart = MID(0,TextEdit->GetReverseUnicodePosition(selstart),len);
selend = MID(0,TextEdit->GetReverseUnicodePosition(selend),len);
// Current tag name
wxString alttagname = tagname;
wxString removeTag;
if (tagname == _T("\\1c")) tagname = _T("\\c");
if (tagname == _T("\\fr")) tagname = _T("\\frz");
if (tagname == _T("\\pos")) removeTag = _T("\\move");
if (tagname == _T("\\move")) removeTag = _T("\\pos");
2006-01-16 22:02:54 +01:00
// Get block at start
size_t blockn = BlockAtPos(selstart);
AssDialogue *line = new AssDialogue();
line->Text = TextEdit->GetText();
2006-01-16 22:02:54 +01:00
line->ParseASSTags();
AssDialogueBlock *block = line->Blocks.at(blockn);
// Insert variables
wxString insert;
wxString insert2;
int shift = 0;
int nInserted = 1;
2006-01-16 22:02:54 +01:00
// Default value
wxColour startcolor;
wxFont startfont;
2006-01-16 22:02:54 +01:00
bool isColor = false;
bool isFont = false;
bool isGeneric = false;
bool isFlag = false;
bool state = false;
AssStyle *style = grid->ass->GetStyle(grid->GetActiveLine()->Style);
2006-01-16 22:02:54 +01:00
AssStyle defStyle;
if (style == NULL) style = &defStyle;
if (tagname == _T("\\b")) {
state = style->bold;
isFlag = true;
}
else if (tagname == _T("\\i")) {
state = style->italic;
isFlag = true;
}
else if (tagname == _T("\\u")) {
state = style->underline;
isFlag = true;
}
else if (tagname == _T("\\s")) {
state = style->strikeout;
isFlag = true;
}
else if (tagname == _T("\\fn")) {
startfont.SetFaceName(style->font);
startfont.SetPointSize(int(style->fontsize));
startfont.SetWeight(style->bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
startfont.SetStyle(style->italic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL);
startfont.SetUnderlined(style->underline);
isFont = true;
}
else if (tagname == _T("\\c")) {
2006-01-16 22:02:54 +01:00
startcolor = style->primary.GetWXColor();
isColor = true;
}
else if (tagname == _T("\\2c")) {
startcolor = style->secondary.GetWXColor();
isColor = true;
}
else if (tagname == _T("\\3c")) {
startcolor = style->outline.GetWXColor();
isColor = true;
}
else if (tagname == _T("\\4c")) {
startcolor = style->shadow.GetWXColor();
isColor = true;
}
else isGeneric = true;
bool hasEnd = isFlag;
2006-01-16 22:02:54 +01:00
// Find current value of style
2006-01-16 22:02:54 +01:00
AssDialogueBlockOverride *override;
AssOverrideTag *tag;
if (isFont || isColor || isFlag) {
2006-01-16 22:02:54 +01:00
for (size_t i=0;i<=blockn;i++) {
override = dynamic_cast<AssDialogueBlockOverride*>(line->Blocks.at(i));
2006-01-16 22:02:54 +01:00
if (override) {
for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j);
if (tag->Name == tagname || tag->Name == alttagname || tagname == _T("\\fn")) {
if (isColor) startcolor = tag->Params.at(0)->Get<wxColour>();
if (isFlag) state = tag->Params.at(0)->Get<bool>();
if (isFont) {
if (tag->Name == _T("\\fn")) startfont.SetFaceName(tag->Params.at(0)->Get<wxString>());
if (tag->Name == _T("\\fs")) startfont.SetPointSize(tag->Params.at(0)->Get<int>());
if (tag->Name == _T("\\b")) startfont.SetWeight((tag->Params.at(0)->Get<int>() > 0) ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
if (tag->Name == _T("\\i")) startfont.SetStyle(tag->Params.at(0)->Get<bool>() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL);
if (tag->Name == _T("\\u")) startfont.SetUnderlined(tag->Params.at(0)->Get<bool>());
}
2006-01-16 22:02:54 +01:00
}
}
}
}
}
// Overrides being inserted
wxArrayString insertTags;
// Toggle value
if (isFlag) {
state = !state;
int stateval = 0;
if (state) stateval = 1;
// Generate insert string
insert = tagname + wxString::Format(_T("%i"),stateval);
insert2 = tagname + wxString::Format(_T("%i"),1-stateval);
insertTags.Add(tagname);
}
2006-01-16 22:02:54 +01:00
// Choose color
if (isColor) {
// Pick from dialog
//wxColour color = wxGetColourFromUser(this,startcolor);
wxColour color = GetColorFromUser(((AegisubApp*)wxTheApp)->frame, startcolor);
if (!color.Ok() || color == startcolor) {
delete line;
return;
}
2006-01-16 22:02:54 +01:00
// Generate insert string
AssColor asscolor(color);
insert = tagname + asscolor.GetASSFormatted(false);
insertTags.Add(tagname);
2006-01-16 22:02:54 +01:00
}
// Choose font
if (isFont) {
// Pick from dialog
wxFont font = wxGetFontFromUser(this,startfont);
if (!font.Ok()) {
delete line;
return;
}
2006-01-16 22:02:54 +01:00
// Generate insert string
nInserted = 0;
if (font.GetFaceName() != startfont.GetFaceName()) {
insert = _T("\\fn") + font.GetFaceName();
nInserted++;
insertTags.Add(_T("\\fn"));
}
if (font.GetPointSize() != startfont.GetPointSize()) {
insert += _T("\\fs") + wxString::Format(_T("%i"),font.GetPointSize());
nInserted++;
insertTags.Add(_T("\\fs"));
}
if (font.GetWeight() != startfont.GetWeight()) {
insert += _T("\\b") + wxString::Format(_T("%i"),font.GetWeight() == wxFONTWEIGHT_BOLD ? 1 : 0);
nInserted++;
insertTags.Add(_T("\\b"));
}
if (font.GetStyle() != startfont.GetStyle()) {
insert += _T("\\i") + wxString::Format(_T("%i"),font.GetStyle() == wxFONTSTYLE_ITALIC ? 1 : 0);
nInserted++;
insertTags.Add(_T("\\i"));
}
if (font.GetUnderlined() != startfont.GetUnderlined()) {
insert += _T("\\u") + wxString::Format(_T("%i"),font.GetUnderlined() ? 1 : 0);
nInserted++;
insertTags.Add(_T("\\u"));
}
if (insert.IsEmpty()) {
delete line;
return;
}
2006-01-16 22:02:54 +01:00
}
// Generic tag
if (isGeneric) {
2006-01-16 22:02:54 +01:00
insert = tagname + preValue;
insertTags.Add(tagname);
2006-01-16 22:02:54 +01:00
}
// Get current block as plain or override
AssDialogueBlockPlain *plain = dynamic_cast<AssDialogueBlockPlain*>(block);
override = dynamic_cast<AssDialogueBlockOverride*>(block);
2006-01-16 22:02:54 +01:00
// Plain
if (plain) {
// Insert in text
line->Text = line->Text.Left(selstart) + _T("{") + insert + _T("}") + line->Text.Mid(selstart);
shift = 2 + insert.Length();
line->ParseASSTags();
}
// Override
else if (override) {
// Insert new tag
override->text += insert;
override->ParseTags();
shift = insert.Length();
// Remove old of same
for (size_t i=0;i<override->Tags.size()-nInserted;i++) {
//if (insert.Contains(override->Tags.at(i)->Name)) {
wxString name = override->Tags.at(i)->Name;
if (insertTags.Index(name) != wxNOT_FOUND || removeTag == name) {
shift -= ((wxString)*override->Tags.at(i)).Length();
delete override->Tags.at(i);
2006-01-16 22:02:54 +01:00
override->Tags.erase(override->Tags.begin() + i);
i--;
}
}
// Update line
line->UpdateText();
}
// End
if (hasEnd && selend != selstart) {
// Prepare variables again
2006-02-19 06:10:57 +01:00
int origStart = selstart;
selstart = selend + shift;
2006-01-16 22:02:54 +01:00
insert = insert2;
TextEdit->SetTextTo(line->Text);
2006-02-19 06:10:57 +01:00
blockn = BlockAtPos(selstart);
2006-01-16 22:02:54 +01:00
block = line->Blocks.at(blockn);
plain = dynamic_cast<AssDialogueBlockPlain*>(block);
override = dynamic_cast<AssDialogueBlockOverride*>(block);
2006-01-16 22:02:54 +01:00
// Plain
if (plain) {
// Insert in text
line->Text = line->Text.Left(selstart) + _T("{") + insert + _T("}") + line->Text.Mid(selstart);
}
// Override
else if (override) {
// Insert new tag
override->text += insert;
override->ParseTags();
// Remove old of same
for (size_t i=0;i<override->Tags.size()-nInserted;i++) {
wxString name = override->Tags.at(i)->Name;
if (insert.Contains(name) || removeTag == name) {
shift -= ((wxString)*override->Tags.at(i)).Length();
2006-01-16 22:02:54 +01:00
override->Tags.erase(override->Tags.begin() + i);
i--;
}
}
// Update line
line->UpdateText();
}
// Shift selection
selstart = origStart;
TextEdit->SetSelectionU(origStart+shift,selend+shift);
2006-01-16 22:02:54 +01:00
}
// Commit changes and shift selection
TextEdit->SetTextTo(line->Text);
delete line;
TextEdit->SetSelectionU(selstart+shift,selend+shift);
if (getFocus) TextEdit->SetFocus();
2006-01-16 22:02:54 +01:00
}
/// @brief Set primary color
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonColor1(wxCommandEvent &event) {
SetOverride(_T("\\1c"));
}
/// @brief Set secondary color
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonColor2(wxCommandEvent &event) {
SetOverride(_T("\\2c"));
}
/// @brief Set outline color
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonColor3(wxCommandEvent &event) {
SetOverride(_T("\\3c"));
}
/// @brief Set shadow color
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonColor4(wxCommandEvent &event) {
SetOverride(_T("\\4c"));
}
/// @brief Set font face
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonFontFace(wxCommandEvent &event) {
SetOverride(_T("\\fn"));
}
/// @brief Bold
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonBold(wxCommandEvent &event) {
SetOverride(_T("\\b"));
2006-01-16 22:02:54 +01:00
}
/// @brief Italics
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonItalics(wxCommandEvent &event) {
SetOverride(_T("\\i"));
2006-01-16 22:02:54 +01:00
}
/// @brief Underline
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonUnderline(wxCommandEvent &event) {
SetOverride(_T("\\u"));
2006-01-16 22:02:54 +01:00
}
/// @brief Strikeout
/// @param event
///
2006-01-16 22:02:54 +01:00
void SubsEditBox::OnButtonStrikeout(wxCommandEvent &event) {
SetOverride(_T("\\s"));
2006-01-16 22:02:54 +01:00
}
/// @brief Commit
/// @param event
///
void SubsEditBox::OnButtonCommit(wxCommandEvent &event) {
#ifdef __APPLE__
Commit(wxGetMouseState().CmdDown());
#else
Commit(wxGetMouseState().ControlDown());
#endif
}
void SubsEditBox::OnActiveLineChanged(AssDialogue *new_line) {
// Set to nothing
enabled = (new_line != 0);
// Set line
if (enabled) {
StartTime->Update();
EndTime->Update();
Duration->Update();
}
// Update controls
Update();
// Set video
if (VideoContext::Get()->IsLoaded()) {
bool sync;
if (Search.hasFocus) sync = OPT_GET("Tool/Search Replace/Video Update")->GetBool();
else sync = OPT_GET("Video/Subtitle Sync")->GetBool();
if (sync) {
VideoContext::Get()->Stop();
if (new_line) VideoContext::Get()->JumpToTime(new_line->Start.GetMS());
}
}
TextEdit->EmptyUndoBuffer();
}
void SubsEditBox::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) {
}