Make the subtitle edit box auto-commit all changes

This happens to fix most of the undo issues, as it's now much harder to
have uncommitted changes to the file.

Closes #355 and #586.

Originally committed to SVN as r4699.
This commit is contained in:
Thomas Goyne 2010-07-20 03:11:11 +00:00
parent 51a75cd0fd
commit fde4a7815d
41 changed files with 1120 additions and 2933 deletions

View File

@ -671,14 +671,6 @@
RelativePath="..\..\src\help_button.h"
>
</File>
<File
RelativePath="..\..\src\hilimod_textctrl.cpp"
>
</File>
<File
RelativePath="..\..\src\hilimod_textctrl.h"
>
</File>
<File
RelativePath="..\..\src\scintilla_text_ctrl.cpp"
>
@ -819,14 +811,6 @@
RelativePath="..\..\src\font_file_lister_freetype.h"
>
</File>
<File
RelativePath="..\..\src\idle_field_event.cpp"
>
</File>
<File
RelativePath="..\..\src\idle_field_event.h"
>
</File>
<File
RelativePath="..\..\src\kana_table.cpp"
>

View File

@ -22,8 +22,10 @@
#ifndef LAGI_PRE
#include <algorithm>
#include <cmath>
#include <functional>
#include <iterator>
#include <list>
#include <numeric>
#endif

View File

@ -72,17 +72,20 @@
#include <iostream>
#include <list>
#include <map>
#ifdef _WIN32
#include <memory>
#else
#include <tr1/memory>
#endif
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#ifdef _WIN32
#include <functional>
#include <memory>
#else
#include <tr1/functional>
#include <tr1/memory>
#endif
#include "boost/shared_ptr.hpp"
// General headers

View File

@ -221,6 +221,8 @@ public:
/// Do nothing
void SetEntryData(wxString) { }
template<int which>
void SetMarginString(const wxString value) { SetMarginString(value, which);}
/// @brief Set a margin
/// @param value New value of the margin
/// @param which 0 = left, 1 = right, 2 = vertical/top, 3 = bottom

View File

@ -73,11 +73,12 @@ AssFile::AssFile ()
{
}
/// @brief AssFile destructor
/// @brief AssFile destructor
AssFile::~AssFile() {
delete_clear(Line);
}
/// @brief Load generic subs
void AssFile::Load (const wxString &_filename,wxString charset,bool addToRecent) {
bool ok = false;
Clear();
@ -447,11 +448,11 @@ void AssFile::LoadDefault (bool defline) {
AddLine(_T("PlayResX: 640"),_T("[Script Info]"),version);
AddLine(_T("PlayResY: 480"),_T("[Script Info]"),version);
AddLine(_T("ScaledBorderAndShadow: yes"),_T("[Script Info]"),version);
AddLine(_T(""),_T("[Script Info]"),version);
AddLine("",_T("[Script Info]"),version);
AddLine(_T("[V4+ Styles]"),_T("[V4+ Styles]"),version);
AddLine(_T("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding"),_T("[V4+ Styles]"),version);
AddLine(defstyle.GetEntryData(),_T("[V4+ Styles]"),version);
AddLine(_T(""),_T("[V4+ Styles]"),version);
AddLine("",_T("[V4+ Styles]"),version);
AddLine(_T("[Events]"),_T("[Events]"),version);
AddLine(_T("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"),_T("[Events]"),version);
@ -506,7 +507,7 @@ void AssFile::InsertStyle (AssStyle *style) {
// No styles found, add them
if (lastStyle == Line.end()) {
// Add space
curEntry = new AssEntry(_T(""));
curEntry = new AssEntry("");
curEntry->group = lastGroup;
Line.push_back(curEntry);
@ -559,10 +560,10 @@ void AssFile::InsertAttachment (AssAttachment *attach) {
// Otherwise, create the [Fonts] group and insert
else {
int version=1;
AddLine(_T(""),Line.back()->group,version);
AddLine("",Line.back()->group,version);
AddLine(attach->group,attach->group,version);
Line.push_back(attach);
AddLine(_T(""),attach->group,version);
AddLine("",attach->group,version);
}
}
@ -640,7 +641,7 @@ void AssFile::SetScriptInfo(const wxString _key,const wxString value) {
// Found
if (curText.StartsWith(key)) {
// Set value
if (value != _T("")) {
if (value != "") {
wxString result = _key;
result += _T(": ");
result += value;
@ -660,7 +661,7 @@ void AssFile::SetScriptInfo(const wxString _key,const wxString value) {
// Add
else if (GotIn) {
if (value != _T("")) {
if (value != "") {
wxString result = _key;
result += _T(": ");
result += value;
@ -762,7 +763,7 @@ wxString AssFile::GetWildcardList(int mode) {
if (mode == 0) return SubtitleFormat::GetWildcards(0);
else if (mode == 1) return _T("Advanced Substation Alpha (*.ass)|*.ass");
else if (mode == 2) return SubtitleFormat::GetWildcards(1);
else return _T("");
else return "";
}
int AssFile::Commit(wxString desc, int amendId) {
@ -844,9 +845,7 @@ void AssFile::Sort(std::list<AssEntry*> &lst, CompFunc comp) {
entryIter end = begin;
while (end != lst.end() && dynamic_cast<AssDialogue*>(*end)) ++end;
// std::list::sort doesn't support sorting only part of the list, but
// splice is constant-time, so just sort a temp list with only the part we
// want sorted
// used instead of std::list::sort for partial list sorting
std::list<AssEntry*> tmp;
tmp.splice(tmp.begin(), lst, begin, end);
tmp.sort(compE);

View File

@ -322,6 +322,13 @@ bool operator != (const AssTime &t1, const AssTime &t2) {
return (t1.GetMS() != t2.GetMS());
}
AssTime operator + (const AssTime &t1, const AssTime &t2) {
return AssTime(t1.GetMS() + t2.GetMS());
}
AssTime operator - (const AssTime &t1, const AssTime &t2) {
return AssTime(t1.GetMS() - t2.GetMS());
}
/// DOCME

View File

@ -72,8 +72,8 @@ public:
int GetTimeMiliseconds();
int GetTimeCentiseconds();
int GetMS() const; // Returns miliseconds
void SetMS(int ms); // Sets values to miliseconds
int GetMS() const; // Returns milliseconds
void SetMS(int ms); // Sets values to milliseconds
void ParseASS(const wxString text); // Sets value to text-form time, in ASS format
void ParseSRT(const wxString text); // Sets value to text-form time, in SRT format
wxString GetASSFormated(bool ms=false) const; // Returns the ASS representation of time
@ -87,6 +87,9 @@ bool operator < (const AssTime &t1, const AssTime &t2);
bool operator > (const AssTime &t1, const AssTime &t2);
bool operator <= (const AssTime &t1, const AssTime &t2);
bool operator >= (const AssTime &t1, const AssTime &t2);
// Arithmetic operators
AssTime operator + (const AssTime &t1, const AssTime &t2);
AssTime operator - (const AssTime &t1, const AssTime &t2);

View File

@ -61,6 +61,7 @@
#include "main.h"
#include "standard_paths.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "timeedit_ctrl.h"
#include "utils.h"
@ -2320,8 +2321,8 @@ void AudioDisplay::OnLoseFocus(wxFocusEvent &event) {
/// @brief Update time edit controls
void AudioDisplay::UpdateTimeEditCtrls() {
grid->editBox->StartTime->SetTime(curStartMS,true);
grid->editBox->EndTime->SetTime(curEndMS,true);
grid->editBox->Duration->SetTime(curEndMS-curStartMS,true);
grid->editBox->StartTime->SetTime(curStartMS);
grid->editBox->EndTime->SetTime(curEndMS);
grid->editBox->Duration->SetTime(curEndMS-curStartMS);
}

View File

@ -42,11 +42,12 @@
#include <wx/sizer.h>
#endif
#include "base_grid.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_style.h"
#include "audio_display.h"
#include "base_grid.h"
#include "compat.h"
#include "frame_main.h"
#include "main.h"
@ -1112,10 +1113,10 @@ int BaseGrid::GetDialogueIndex(AssDialogue *diag) const {
bool BaseGrid::IsDisplayed(AssDialogue *line) {
VideoContext* con = VideoContext::Get();
if (!con->IsLoaded()) return false;
int f1 = con->FrameAtTime(line->Start.GetMS(),agi::vfr::START);
int f2 = con->FrameAtTime(line->End.GetMS(),agi::vfr::END);
if (f1 <= con->GetFrameN() && f2 >= con->GetFrameN()) return true;
return false;
int frame = con->GetFrameN();
return
con->FrameAtTime(line->Start.GetMS(),agi::vfr::START) <= frame &&
con->FrameAtTime(line->End.GetMS(),agi::vfr::END) >= frame;
}
/// @brief Key press

View File

@ -46,7 +46,6 @@
#include "dialog_resample.h"
#include "help_button.h"
#include "libresrc/libresrc.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "validators.h"
@ -323,7 +322,6 @@ void DialogResample::OnResample (wxCommandEvent &event) {
// Flag as modified
subs->Commit(_("resolution resampling"));
grid->CommitChanges();
grid->editBox->Update();
EndModal(0);
}

View File

@ -51,6 +51,7 @@
#include "frame_main.h"
#include "main.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "video_display.h"
@ -545,7 +546,6 @@ void SearchReplaceEngine::ReplaceAll() {
if (count > 0) {
grid->ass->Commit(_("replace"));
grid->CommitChanges();
grid->editBox->Update();
wxMessageBox(wxString::Format(_("%i matches were replaced."),count));
}

View File

@ -57,7 +57,6 @@
#include "libresrc/libresrc.h"
#include "main.h"
#include "standard_paths.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"
@ -312,7 +311,6 @@ void DialogShiftTimes::OnOK(wxCommandEvent &event) {
// End dialog
grid->ass->Commit(_("shifting"));
grid->CommitChanges();
grid->editBox->Update();
EndModal(0);
}

View File

@ -52,6 +52,7 @@
#include "main.h"
#include "spellchecker_manager.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "utils.h"

View File

@ -52,6 +52,7 @@
#include "hotkeys.h"
#include "libresrc/libresrc.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"

View File

@ -33,26 +33,17 @@
/// @see dialog_translation.cpp
/// @ingroup tools_ui///
///////////
// Headers
#ifndef AGI_PRE
#include <wx/checkbox.h>
#include <wx/dialog.h>
#include <wx/stattext.h>
#endif
#include "scintilla_text_ctrl.h"
//////////////
// Prototypes
class AssFile;
class AssDialogue;
class SubtitlesGrid;
class AudioDisplay;
class ScintillaTextCtrl;
class SubtitlesGrid;
class VideoContext;
@ -126,8 +117,6 @@ public:
DECLARE_EVENT_TABLE()
};
/// DOCME
/// @class DialogTranslationEvent
/// @brief DOCME
@ -147,23 +136,11 @@ public:
DECLARE_EVENT_TABLE()
};
///////
// IDs
/// Event IDs
enum {
/// DOCME
TEXT_ORIGINAL = 1100,
/// DOCME
TEXT_TRANS,
/// DOCME
PREVIEW_CHECK,
/// DOCME
BUTTON_TRANS_PLAY_AUDIO,
/// DOCME
BUTTON_TRANS_PLAY_VIDEO
};

View File

@ -73,6 +73,7 @@
#include "main.h"
#include "standard_paths.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "text_file_reader.h"
#include "text_file_writer.h"
@ -604,8 +605,7 @@ void FrameMain::InitContents() {
// Top sizer
StartupLog(_T("Create subtitle editing box"));
EditBox = new SubsEditBox(Panel,SubsGrid);
EditBox->audio = audioBox->audioDisplay;
EditBox = new SubsEditBox(Panel,SubsGrid, audioBox->audioDisplay);
StartupLog(_T("Arrange controls in sizers"));
ToolSizer = new wxBoxSizer(wxVERTICAL);
ToolSizer->Add(audioBox,0,wxEXPAND | wxBOTTOM,5);
@ -863,7 +863,6 @@ void FrameMain::SetDisplayMode(int video, int audio) {
// Update
UpdateToolbar();
EditBox->SetSplitLineMode();
MainSizer->CalcMin();
MainSizer->RecalcSizes();
MainSizer->Layout();
@ -1138,7 +1137,7 @@ void FrameMain::LoadVideo(wxString file,bool autoload) {
}
}
SubsGrid->CommitChanges(true);
SubsGrid->CommitChanges();
SetDisplayMode(1,-1);
EditBox->UpdateFrameTiming();
@ -1229,7 +1228,6 @@ void FrameMain::SetAccelerators() {
entry.push_back(Hotkeys.GetAccelerator(_T("Video global zoom in"),Menu_Video_Zoom_In));
entry.push_back(Hotkeys.GetAccelerator(_T("Video global zoom out"),Menu_Video_Zoom_Out));
entry.push_back(Hotkeys.GetAccelerator(_T("Video global play"),Video_Frame_Play));
entry.push_back(Hotkeys.GetAccelerator(_T("Edit box commit"),Edit_Box_Commit));
// Medusa
bool medusaPlay = OPT_GET("Audio/Medusa Timing Hotkeys")->GetBool();

View File

@ -266,7 +266,6 @@ private:
void OnSortStart (wxCommandEvent &event);
void OnSortEnd (wxCommandEvent &event);
void OnSortStyle (wxCommandEvent &event);
void OnEditBoxCommit (wxCommandEvent &event);
void OnOpenProperties (wxCommandEvent &event);
void OnOpenStylesManager (wxCommandEvent &event);
void OnOpenAttachments (wxCommandEvent &event);
@ -508,7 +507,6 @@ enum {
Grid_Prev_Line,
Grid_Toggle_Tags,
Edit_Box_Commit,
Video_Frame_Play,

View File

@ -85,6 +85,7 @@
#include "preferences.h"
#include "standard_paths.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "toggle_bitmap.h"
#include "utils.h"
@ -223,7 +224,6 @@ BEGIN_EVENT_TABLE(FrameMain, wxFrame)
EVT_MENU(Grid_Next_Line,FrameMain::OnNextLine)
EVT_MENU(Grid_Prev_Line,FrameMain::OnPrevLine)
EVT_MENU(Grid_Toggle_Tags,FrameMain::OnToggleTags)
EVT_MENU(Edit_Box_Commit,FrameMain::OnEditBoxCommit)
EVT_MENU(Medusa_Play, FrameMain::OnMedusaPlay)
EVT_MENU(Medusa_Stop, FrameMain::OnMedusaStop)
@ -574,7 +574,6 @@ void FrameMain::OnLog(wxCommandEvent &) {
log->Show(1);
}
/// @brief Open check updates
void FrameMain::OnCheckUpdates(wxCommandEvent &) {
PerformVersionCheck(true);
@ -1056,7 +1055,7 @@ void FrameMain::OnAutomationMacro (wxCommandEvent &event) {
// Have the grid update its maps, this properly refreshes it to reflect the changed subs
SubsGrid->UpdateMaps();
SubsGrid->SetSelectionFromAbsolute(selected_lines);
SubsGrid->CommitChanges(true, false);
SubsGrid->CommitChanges();
SubsGrid->EndBatch();
#endif
}
@ -1155,8 +1154,8 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &) {
// Commit
SubsGrid->ass->Commit(_("shift to frame"));
SubsGrid->CommitChanges();
SubsGrid->editBox->Update(true,false);
SubsGrid->CommitChanges(false);
SubsGrid->editBox->Update(true);
}
/// @brief Undo
@ -1474,32 +1473,6 @@ void FrameMain::OnSetTags(wxCommandEvent &event) {
SubsGrid->Refresh(false);
}
/// @brief Commit Edit Box's changes
/// @param event
void FrameMain::OnEditBoxCommit(wxCommandEvent &event) {
// Find focus
wxWindow *focus = FindFocus();
if (!focus) return;
// Is the text edit
if (focus == EditBox->TextEdit) {
EditBox->Commit(true);
EditBox->Update(true);
}
// Other window
else {
//wxKeyEvent keyevent;
//keyevent.m_keyCode = WXK_RETURN;
//keyevent.m_controlDown = true;
//keyevent.SetEventType(wxEVT_KEY_DOWN);
wxCommandEvent keyevent(wxEVT_COMMAND_TEXT_ENTER,focus->GetId());
focus->GetEventHandler()->AddPendingEvent(keyevent);
}
}
/// @brief Choose a different language
void FrameMain::OnChooseLanguage (wxCommandEvent &) {
// Get language

View File

@ -1,127 +0,0 @@
// 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/
//
// $Id$
/// @file hilimod_textctrl.cpp
/// @brief Edit control that changes colour when its contents are modified
/// @ingroup custom_control
///
////////////
// Includes
#include "config.h"
#include "compat.h"
#include "hilimod_textctrl.h"
#include "main.h"
/// @brief Constructor
/// @param parent
/// @param id
/// @param value
/// @param pos
/// @param size
/// @param style
/// @param validator
/// @param name
///
HiliModTextCtrl::HiliModTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) :
wxTextCtrl(parent,id,value,pos,size,style,validator,name)
{
UpdateLocked = false;
isModified = false;
orig = GetValue();
Connect(wxEVT_COMMAND_TEXT_UPDATED,wxCommandEventHandler(HiliModTextCtrl::OnModified));
}
/// @brief Modified event
/// @param event
/// @return
///
void HiliModTextCtrl::OnModified(wxCommandEvent &event) {
if (UpdateLocked) return;
Modified();
event.Skip();
}
/// @brief Commited event
///
void HiliModTextCtrl::Commited() {
if (isModified) {
orig = GetValue();
SetBackgroundColour(wxNullColour);
Refresh(false);
isModified = false;
}
}
/// @brief Set value
/// @param value
///
void HiliModTextCtrl::SetValue(const wxString& value) {
UpdateLocked = true;
orig = value;
wxTextCtrl::SetValue(value);
Commited();
UpdateLocked = false;
}
/// @brief Was modified
///
void HiliModTextCtrl::Modified() {
bool match = GetValue() == orig;
// Different from original
if (!isModified && !match) {
isModified = true;
SetBackgroundColour(lagi_wxColour(OPT_GET("Colour/Background/Modified")->GetColour()));
Refresh(false);
}
// Same as original
if (isModified && match) {
SetBackgroundColour(wxNullColour);
Refresh(false);
isModified = false;
}
}

View File

@ -1,87 +0,0 @@
// 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/
//
// $Id$
/// @file hilimod_textctrl.h
/// @see hilimod_textctrl.cpp
/// @ingroup custom_control
///
#ifndef HILIMOD_TEXTCTRL
/// DOCME
#define HILIMOD_TEXTCTRL
////////////
// Includes
#ifndef AGI_PRE
#include <wx/textctrl.h>
#endif
/// DOCME
/// @class HiliModTextCtrl
/// @brief DOCME
///
/// DOCME
class HiliModTextCtrl : public wxTextCtrl {
private:
/// DOCME
bool UpdateLocked;
/// DOCME
bool isModified;
/// DOCME
wxString orig;
void OnModified(wxCommandEvent &event);
void OnKey(wxKeyEvent &event);
public:
HiliModTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value = _T(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr);
void Modified();
void Commited();
void SetValue(const wxString& value);
/// @brief DOCME
///
bool HasBeenModified() { return isModified; }
};
#endif

View File

@ -1,181 +0,0 @@
// Copyright (c) 2006, 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/
//
// $Id$
/// @file idle_field_event.cpp
/// @brief Unused event, intended to be used for automatic update of other controls after some idle time from the user
/// @ingroup custom_control
///
///////////
// Headers
#include "config.h"
#ifndef AGI_PRE
#include <wx/event.h>
#include <wx/settings.h>
#endif
#include "idle_field_event.h"
/// @brief Constructor
/// @param _control
/// @param _name
///
IdleFieldHandler::IdleFieldHandler(wxWindow *_control,wxString _name) {
control = _control;
name = _name;
overriden = false;
locked = false;
text = NULL;
box = NULL;
// Set colours
original = control->GetForegroundColour();
grey = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
wxColour bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
grey = wxColour((grey.Red() + bg.Red()) / 2,(grey.Green() + bg.Green()) / 2,(grey.Blue() + bg.Blue()) / 2);
// wxTextCtrl
if (control->IsKindOf(CLASSINFO(wxTextCtrl))) {
text = (wxTextCtrl*) control;
Connect(text->GetId(),wxEVT_COMMAND_TEXT_UPDATED,wxCommandEventHandler(IdleFieldHandler::OnChange));
}
// wxComboBox
else if (control->IsKindOf(CLASSINFO(wxComboBox))) {
box = (wxComboBox*) control;
Connect(box->GetId(),wxEVT_COMMAND_TEXT_UPDATED,wxCommandEventHandler(IdleFieldHandler::OnChange));
Connect(box->GetId(),wxEVT_COMMAND_COMBOBOX_SELECTED,wxCommandEventHandler(IdleFieldHandler::OnChange));
}
KillFocus();
}
///////////////
// Event table
BEGIN_EVENT_TABLE(IdleFieldHandler,wxEvtHandler)
EVT_SET_FOCUS(IdleFieldHandler::OnSetFocus)
EVT_KILL_FOCUS(IdleFieldHandler::OnKillFocus)
END_EVENT_TABLE()
/// @brief Get Focus event
/// @param event
///
void IdleFieldHandler::OnSetFocus(wxFocusEvent &event) {
SetFocus();
event.Skip();
}
/// @brief Lose Focus event
/// @param event
///
void IdleFieldHandler::OnKillFocus(wxFocusEvent &event) {
KillFocus();
event.Skip();
}
/// @brief Get focus
///
void IdleFieldHandler::SetFocus() {
if (overriden) {
// Prepare
locked = true;
control->Freeze();
control->SetForegroundColour(original);
// Text
if (text) text->SetValue(_T(""));
// Box
if (box) box->SetValue(_T(""));
// Finish
overriden = false;
locked = false;
control->Thaw();
}
}
/// @brief Lose Focus
///
void IdleFieldHandler::KillFocus() {
bool modify = false;
if ((text && text->GetValue().IsEmpty()) || (box && box->GetValue().IsEmpty())) modify = true;
if (modify) {
// Prepare
locked = true;
control->Freeze();
control->SetForegroundColour(grey);
// Text
if (text) text->SetValue(name);
// Box
if (box) box->SetValue(name);
// Finish
overriden = true;
locked = false;
control->Thaw();
}
}
/// @brief Parent control changed
/// @param event
///
void IdleFieldHandler::OnChange(wxCommandEvent &event) {
if (locked) return;
overriden = false;
control->SetForegroundColour(original);
if (wxWindow::FindFocus() != control) {
wxFocusEvent focus(wxEVT_KILL_FOCUS,control->GetId());
focus.SetEventObject(control);
AddPendingEvent(focus);
}
event.Skip();
}

View File

@ -1,95 +0,0 @@
// Copyright (c) 2006, 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/
//
// $Id$
/// @file idle_field_event.h
/// @see idle_field_event.cpp
/// @ingroup custom_control
///
///////////
// Headers
#ifndef AGI_PRE
#include <wx/combobox.h>
#include <wx/event.h>
#include <wx/textctrl.h>
#endif
/// DOCME
/// @class IdleFieldHandler
/// @brief DOCME
///
/// DOCME
class IdleFieldHandler : public wxEvtHandler {
private:
/// DOCME
wxComboBox *box;
/// DOCME
wxTextCtrl *text;
/// DOCME
bool overriden;
/// DOCME
bool locked;
/// DOCME
wxColour grey;
/// DOCME
wxColour original;
/// DOCME
wxWindow *control;
/// DOCME
wxString name;
void SetFocus();
void KillFocus();
void OnSetFocus(wxFocusEvent &event);
void OnKillFocus(wxFocusEvent &event);
void OnChange(wxCommandEvent &event);
public:
IdleFieldHandler(wxWindow *control,wxString name);
DECLARE_EVENT_TABLE()
};

View File

@ -34,17 +34,10 @@
/// @ingroup custom_control
///
#pragma once
////////////
// Includes
#ifndef AGI_PRE
#include <wx/stc/stc.h>
#endif
/// DOCME
/// @class ScintillaTextCtrl
/// @brief DOCME
@ -57,10 +50,6 @@ public:
int GetUnicodePosition(int pos);
int GetReverseUnicodePosition(int pos);
/// @brief DOCME
///
wxString GetValue() { return GetText(); }
void StartUnicodeStyling(int start,int mask=31);
void SetUnicodeStyling(int start,int length,int style);
void SetSelectionU(int start,int end);
@ -68,5 +57,3 @@ public:
ScintillaTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value = _T(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr);
virtual ~ScintillaTextCtrl();
};

File diff suppressed because it is too large Load Diff

View File

@ -34,335 +34,175 @@
/// @ingroup main_ui
///
////////////
// Includes
#ifndef AGI_PRE
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/combobox.h>
#include <wx/dcclient.h>
#include <wx/dcmemory.h>
#include <vector>
#include <wx/panel.h>
#include <wx/radiobut.h>
#include <wx/spinctrl.h>
#endif
#include "selection_controller.h"
#include "subs_edit_ctrl.h"
//////////////
// Prototypes
class AudioDisplay;
class AssDialogue;
class SubtitlesGrid;
class SubsTextEditCtrl;
class TimeEdit;
class SubsEditBox;
class AudioDisplay;
class HiliModTextCtrl;
class wxButton;
class wxCheckBox;
class wxComboBox;
class wxRadioButton;
class wxSizer;
class wxSpinCtrl;
class wxStyledTextCtrl;
class wxStyleTextEvent;
class wxTextCtrl;
/// DOCME
/// @class SubsEditBox
/// @brief DOCME
/// @brief Main subtitle edit box
///
/// DOCME
/// Controls the text edit and all surrounding controls
class SubsEditBox : public wxPanel, protected SelectionListener<AssDialogue> {
friend class SubsTextEditHandler;
friend class SubsTextEditCtrl;
friend class AudioDisplay;
private:
enum TimeField {
TIME_START = 0,
TIME_END,
TIME_DURATION
};
/// DOCME
/// Currently active dialogue line
AssDialogue *line;
/// Last seen grid selection
Selection sel;
/// Are the buttons currently split into two lines?
bool splitLineMode;
/// DOCME
bool setupDone;
/// DOCME
bool enabled;
/// DOCME
bool textEditReady;
/// DOCME
/// Are the controls currently enabled?
bool controlState;
/// DOCME
wxColour disabledBgColour;
wxColour origBgColour;
/// DOCME
wxColour disabledBgColour;
/// DOCME
// Externally supplied controls
AudioDisplay *audio;
SubtitlesGrid *grid;
/// DOCME
// Box controls
wxCheckBox *CommentBox;
/// DOCME
wxComboBox *StyleBox;
/// DOCME
wxComboBox *ActorBox;
/// DOCME
TimeEdit *StartTime;
/// DOCME
TimeEdit *EndTime;
/// DOCME
TimeEdit *Duration;
/// DOCME
wxSpinCtrl *Layer;
/// DOCME
HiliModTextCtrl *MarginL;
/// DOCME
HiliModTextCtrl *MarginR;
/// DOCME
HiliModTextCtrl *MarginV;
/// DOCME
HiliModTextCtrl *Effect;
/// DOCME
wxTextCtrl *MarginL;
wxTextCtrl *MarginR;
wxTextCtrl *MarginV;
wxTextCtrl *Effect;
wxRadioButton *ByTime;
/// DOCME
wxRadioButton *ByFrame;
/// DOCME
wxCheckBox *SyntaxHighlight;
/// Buttons which turn on or off with the control
std::vector<wxButton*> ToggableButtons;
/// DOCME
wxButton *Bold;
/// DOCME
wxButton *Italics;
/// DOCME
wxButton *Underline;
/// DOCME
wxButton *Strikeout;
/// DOCME
wxButton *FontName;
/// DOCME
wxButton *Color1;
/// DOCME
wxButton *Color2;
/// DOCME
wxButton *Color3;
/// DOCME
wxButton *Color4;
/// DOCME
wxButton *CommitButton;
/// DOCME
wxSizer *TopSizer;
/// DOCME
wxSizer *MiddleBotSizer;
/// DOCME
wxSizer *MiddleSizer;
/// DOCME
wxSizer *MainSizer;
/// DOCME
wxSizer *DummySizer;
/// DOCME
wxSizer *BottomSizer;
void SetControlsState(bool state);
void CommitTimes(bool start,bool end,bool fromStart,bool commit=true);
/// @brief Update times of selected lines
/// @param field Field which changed
void CommitTimes(TimeField field);
/// @brief Commits the current edit box contents
/// @param desc Undo description to use
void CommitText(wxString desc);
int BlockAtPos(int pos);
/// Get block number at text position
int BlockAtPos(int pos) const;
/// @brief Refresh the video display and move to the next line
/// @param stay Only refresh the video
void Commit(bool stay);
int timeCommitId[3];
int commitId;
wxString lastCommitType;
void OnEditText(wxStyledTextEvent &event);
void OnNeedStyle(wxStyledTextEvent &event);
void OnCharAdded(wxStyledTextEvent &event);
void OnUpdateUI(wxStyledTextEvent &event);
void OnChange(wxStyledTextEvent &event);
void OnKeyDown(wxKeyEvent &event);
void OnButtonColor1(wxCommandEvent &event);
void OnButtonColor2(wxCommandEvent &event);
void OnButtonColor3(wxCommandEvent &event);
void OnButtonColor4(wxCommandEvent &event);
void OnButtonFontFace(wxCommandEvent &event);
void OnButtonBold(wxCommandEvent &event);
void OnButtonItalics(wxCommandEvent &event);
void OnButtonUnderline(wxCommandEvent &event);
void OnButtonStrikeout(wxCommandEvent &event);
void OnButtonCommit(wxCommandEvent &event);
void OnActiveLineChanged(AssDialogue *new_line);
void OnSelectedSetChanged(const Selection &, const Selection &);
void OnSyntaxBox(wxCommandEvent &event);
void OnFrameRadio(wxCommandEvent &event);
void OnTimeRadio(wxCommandEvent &event);
void OnKeyDown(wxStyledTextEvent &event);
void OnFrameTimeRadio(wxCommandEvent &event);
void OnStyleChange(wxCommandEvent &event);
void OnActorChange(wxCommandEvent &event);
void OnLayerEnter(wxCommandEvent &event);
void OnLayerChange(wxSpinEvent &event);
void OnStartTimeChange(wxCommandEvent &event);
void OnEndTimeChange(wxCommandEvent &event);
void OnDurationChange(wxCommandEvent &event);
void OnMarginLChange(wxCommandEvent &event);
void OnMarginRChange(wxCommandEvent &event);
void OnMarginVChange(wxCommandEvent &event);
void OnCommentChange(wxCommandEvent &event);
void OnEffectChange(wxCommandEvent &event);
void OnStartTimeChange(wxCommandEvent &);
void OnEndTimeChange(wxCommandEvent &);
void OnDurationChange(wxCommandEvent &);
void OnMarginLChange(wxCommandEvent &);
void OnMarginRChange(wxCommandEvent &);
void OnMarginVChange(wxCommandEvent &);
void OnCommentChange(wxCommandEvent &);
void OnEffectChange(wxCommandEvent &);
void OnSize(wxSizeEvent &event);
protected:
// SubtitleSelectionListener implementation
virtual void OnActiveLineChanged(AssDialogue *new_line);
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed);
void OnFlagButton(wxCommandEvent &event);
void OnColorButton(wxCommandEvent &event);
void OnFontButton(wxCommandEvent &event);
void OnCommitButton(wxCommandEvent &);
/// @brief Set the value of a tag for the currently selected text
/// @param tag Tag to set
/// @param value New value of tag
/// @param atEnd Set the value at the end of the selection rather than beginning
void SetTag(wxString tag, wxString value, bool atEnd = false);
/// @brief Callback function for the color picker
/// @param newColor New color selected in the picker
void SetColorCallback(wxColor newColor);
/// Which color is currently being set
wxString colorTag;
/// @brief Set a field in each selected line to a specified value
/// @param set Callable which does the setting
/// @param value Value to pass to set
/// @param desc Undo description to use
/// @param amend Coalesce sequences of commits of the same type
template<class T, class setter>
void SetSelectedRows(setter set, T value, wxString desc, bool amend = false);
/// @brief Set a field in each selected line to a specified value
/// @param field Field to set
/// @param value Value to set the field to
/// @param desc Undo description to use
/// @param amend Coalesce sequences of commits of the same type
template<class T>
void SetSelectedRows(T AssDialogue::*field, T value, wxString desc, bool amend = false);
public:
/// DOCME
AudioDisplay *audio;
/// DOCME
SubsTextEditCtrl *TextEdit;
SubsEditBox(wxWindow *parent,SubtitlesGrid *gridp);
/// @brief Constructor
/// @param parent Parent window
/// @param grid Associated grid
/// @param audio Associated audio display
SubsEditBox(wxWindow *parent, SubtitlesGrid *grid, AudioDisplay *audio);
~SubsEditBox();
void SetOverride (wxString tag,wxString preValue=_T(""),int pos=-1,bool getFocus=true);
void SetStyleFlag (wxString tag,wxString preValue=_T(""),int pos=-1);
void SetSplitLineMode(wxSize size=wxSize(-1,-1));
void CommitText(bool weak=false);
void Update(bool timeOnly=false,bool weak=false);
/// @brief Reload the current line from the file
/// @param timeOnly Only reload times
/// @param setAudio Also update the audio display
void Update(bool timeOnly = false, bool setAudio = true);
/// Reload non-line-specific things like styles from the file
void UpdateGlobals();
/// @brief Enable or disable frame timing mode
void UpdateFrameTiming();
void DoKeyPress(wxKeyEvent &event);
void Commit(bool stay);
DECLARE_EVENT_TABLE()
};
/// DOCME
/// @class SubsEditBoxEvent
/// @brief DOCME
///
/// DOCME
class SubsEditBoxEvent : public wxEvtHandler {
private:
/// DOCME
SubsEditBox *control;
void OnKeyPress(wxKeyEvent &event);
public:
SubsEditBoxEvent(SubsEditBox *control);
DECLARE_EVENT_TABLE()
};
///////
// IDs
enum {
/// DOCME
EDIT_BOX = 1300,
/// DOCME
SYNTAX_BOX,
/// DOCME
RADIO_TIME_BY_FRAME,
/// DOCME
RADIO_TIME_BY_TIME,
/// DOCME
STYLE_COMBOBOX,
/// DOCME
ACTOR_COMBOBOX,
/// DOCME
LAYER_BOX,
/// DOCME
STARTTIME_BOX,
/// DOCME
ENDTIME_BOX,
/// DOCME
DURATION_BOX,
/// DOCME
MARGINL_BOX,
/// DOCME
MARGINR_BOX,
/// DOCME
MARGINV_BOX,
/// DOCME
EFFECT_BOX,
/// DOCME
COMMENT_CHECKBOX,
/// DOCME
BUTTON_BOLD,
/// DOCME
BUTTON_ITALICS,
/// DOCME
BUTTON_UNDERLINE,
/// DOCME
BUTTON_STRIKEOUT,
/// DOCME
BUTTON_FONT_NAME,
/// DOCME
BUTTON_COLOR1,
/// DOCME
BUTTON_COLOR2,
/// DOCME
BUTTON_COLOR3,
/// DOCME
BUTTON_COLOR4,
/// DOCME
BUTTON_COMMIT
};

View File

@ -34,22 +34,46 @@
/// @ingroup main_ui
///
////////////
// Includes
#include "config.h"
#ifndef AGI_PRE
#ifdef _WIN32
#include <functional>
#else
#include <tr1/functional>
#endif
#include <wx/intl.h>
#endif
#include "ass_dialogue.h"
#include "compat.h"
#include "main.h"
#include "spellchecker_manager.h"
#include "subs_edit_box.h"
#include "subs_edit_ctrl.h"
#include "subs_grid.h"
#include "thesaurus.h"
#include "utils.h"
/// Event ids
enum {
EDIT_MENU_SPLIT_PRESERVE = 1400,
EDIT_MENU_SPLIT_ESTIMATE,
EDIT_MENU_CUT,
EDIT_MENU_COPY,
EDIT_MENU_PASTE,
EDIT_MENU_SELECT_ALL,
EDIT_MENU_ADD_TO_DICT,
EDIT_MENU_SUGGESTION,
EDIT_MENU_SUGGESTIONS,
EDIT_MENU_THESAURUS = 1450,
EDIT_MENU_THESAURUS_SUGS,
EDIT_MENU_DIC_LANGUAGE = 1600,
EDIT_MENU_DIC_LANGS,
EDIT_MENU_THES_LANGUAGE = 1700,
EDIT_MENU_THES_LANGS
};
/// @brief Edit box constructor
/// @param parent
@ -62,8 +86,11 @@
/// @param name
/// @return
///
SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& wsize, long style, const wxValidator& validator, const wxString& name)
: ScintillaTextCtrl(parent, id, value, pos, wsize, style, validator, name)
SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, SubtitlesGrid *grid)
: ScintillaTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wsize, style)
, spellchecker(SpellCheckerFactoryManager::GetSpellChecker())
, thesaurus(Thesaurus::GetThesaurus())
, grid(grid)
{
// Set properties
SetWrapMode(wxSTC_WRAP_WORD);
@ -83,127 +110,104 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxWindowID id, const wxStri
CmdKeyClear('T',wxSTC_SCMOD_CTRL | wxSTC_SCMOD_SHIFT);
CmdKeyClear('U',wxSTC_SCMOD_CTRL);
// Set spellchecker
spellchecker = SpellCheckerFactoryManager::GetSpellChecker();
// Set thesaurus
thesaurus = Thesaurus::GetThesaurus();
// Prototypes for call tips
tipProtoN = -1;
proto.Add(_T("move(x1,y1,x2,y2)"));
proto.Add(_T("move(x1,y1,x2,y2,startTime,endTime)"));
proto.Add(_T("fn;FontName"));
proto.Add(_T("bord;Width"));
proto.Add(_T("xbord;Width"));
proto.Add(_T("ybord;Width"));
proto.Add(_T("shad;Depth"));
proto.Add(_T("xshad;Depth"));
proto.Add(_T("yshad;Depth"));
proto.Add(_T("be;Strength"));
proto.Add(_T("blur;Strength"));
proto.Add(_T("fscx;Scale"));
proto.Add(_T("fscy;Scale"));
proto.Add(_T("fsp;Spacing"));
proto.Add(_T("fs;FontSize"));
proto.Add(_T("fe;Encoding"));
proto.Add(_T("frx;Angle"));
proto.Add(_T("fry;Angle"));
proto.Add(_T("frz;Angle"));
proto.Add(_T("fr;Angle"));
proto.Add(_T("pbo;Offset"));
proto.Add(_T("clip(command)"));
proto.Add(_T("clip(scale,command)"));
proto.Add(_T("clip(x1,y1,x2,y2)"));
proto.Add(_T("iclip(command)"));
proto.Add(_T("iclip(scale,command)"));
proto.Add(_T("iclip(x1,y1,x2,y2)"));
proto.Add(_T("t(acceleration,tags)"));
proto.Add(_T("t(startTime,endTime,tags)"));
proto.Add(_T("t(startTime,endTime,acceleration,tags)"));
proto.Add(_T("pos(x,y)"));
proto.Add(_T("p;Exponent"));
proto.Add(_T("org(x,y)"));
proto.Add(_T("fade(startAlpha,middleAlpha,endAlpha,startIn,endIn,startOut,endOut)"));
proto.Add(_T("fad(startTime,endTime)"));
proto.Add(_T("c;Colour"));
proto.Add(_T("1c;Colour"));
proto.Add(_T("2c;Colour"));
proto.Add(_T("3c;Colour"));
proto.Add(_T("4c;Colour"));
proto.Add(_T("alpha;Alpha"));
proto.Add(_T("1a;Alpha"));
proto.Add(_T("2a;Alpha"));
proto.Add(_T("3a;Alpha"));
proto.Add(_T("4a;Alpha"));
proto.Add(_T("an;Alignment"));
proto.Add(_T("a;Alignment"));
proto.Add(_T("b;Weight"));
proto.Add(_T("i;1/0"));
proto.Add(_T("u;1/0"));
proto.Add(_T("s;1/0"));
proto.Add(_T("kf;Duration"));
proto.Add(_T("ko;Duration"));
proto.Add(_T("k;Duration"));
proto.Add(_T("K;Duration"));
proto.Add(_T("q;WrapStyle"));
proto.Add(_T("r;Style"));
proto.Add(_T("fax;Factor"));
proto.Add(_T("fay;Factor"));
proto.Add(L"move(x1,y1,x2,y2)");
proto.Add(L"move(x1,y1,x2,y2,startTime,endTime)");
proto.Add(L"fn;FontName");
proto.Add(L"bord;Width");
proto.Add(L"xbord;Width");
proto.Add(L"ybord;Width");
proto.Add(L"shad;Depth");
proto.Add(L"xshad;Depth");
proto.Add(L"yshad;Depth");
proto.Add(L"be;Strength");
proto.Add(L"blur;Strength");
proto.Add(L"fscx;Scale");
proto.Add(L"fscy;Scale");
proto.Add(L"fsp;Spacing");
proto.Add(L"fs;FontSize");
proto.Add(L"fe;Encoding");
proto.Add(L"frx;Angle");
proto.Add(L"fry;Angle");
proto.Add(L"frz;Angle");
proto.Add(L"fr;Angle");
proto.Add(L"pbo;Offset");
proto.Add(L"clip(command)");
proto.Add(L"clip(scale,command)");
proto.Add(L"clip(x1,y1,x2,y2)");
proto.Add(L"iclip(command)");
proto.Add(L"iclip(scale,command)");
proto.Add(L"iclip(x1,y1,x2,y2)");
proto.Add(L"t(acceleration,tags)");
proto.Add(L"t(startTime,endTime,tags)");
proto.Add(L"t(startTime,endTime,acceleration,tags)");
proto.Add(L"pos(x,y)");
proto.Add(L"p;Exponent");
proto.Add(L"org(x,y)");
proto.Add(L"fade(startAlpha,middleAlpha,endAlpha,startIn,endIn,startOut,endOut)");
proto.Add(L"fad(startTime,endTime)");
proto.Add(L"c;Colour");
proto.Add(L"1c;Colour");
proto.Add(L"2c;Colour");
proto.Add(L"3c;Colour");
proto.Add(L"4c;Colour");
proto.Add(L"alpha;Alpha");
proto.Add(L"1a;Alpha");
proto.Add(L"2a;Alpha");
proto.Add(L"3a;Alpha");
proto.Add(L"4a;Alpha");
proto.Add(L"an;Alignment");
proto.Add(L"a;Alignment");
proto.Add(L"b;Weight");
proto.Add(L"i;1/0");
proto.Add(L"u;1/0");
proto.Add(L"s;1/0");
proto.Add(L"kf;Duration");
proto.Add(L"ko;Duration");
proto.Add(L"k;Duration");
proto.Add(L"K;Duration");
proto.Add(L"q;WrapStyle");
proto.Add(L"r;Style");
proto.Add(L"fax;Factor");
proto.Add(L"fay;Factor");
using namespace std::tr1;
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::Cut, this)), EDIT_MENU_CUT);
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::Copy, this)), EDIT_MENU_COPY);
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::Paste, this)), EDIT_MENU_PASTE);
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::SelectAll, this)), EDIT_MENU_SELECT_ALL);
Bind(wxEVT_STC_STYLENEEDED, &SubsTextEditCtrl::UpdateCallTip, this);
}
/// @brief Destructor
///
SubsTextEditCtrl::~SubsTextEditCtrl() {
delete spellchecker;
spellchecker = NULL;
delete thesaurus;
thesaurus = NULL;
}
///////////////////////
// Control event table
BEGIN_EVENT_TABLE(SubsTextEditCtrl,wxStyledTextCtrl)
EVT_MOUSE_EVENTS(SubsTextEditCtrl::OnMouseEvent)
EVT_KILL_FOCUS(SubsTextEditCtrl::OnLoseFocus)
EVT_MENU(EDIT_MENU_SPLIT_PRESERVE,SubsTextEditCtrl::OnSplitLinePreserve)
EVT_MENU(EDIT_MENU_SPLIT_ESTIMATE,SubsTextEditCtrl::OnSplitLineEstimate)
EVT_MENU(EDIT_MENU_CUT,SubsTextEditCtrl::OnCut)
EVT_MENU(EDIT_MENU_COPY,SubsTextEditCtrl::OnCopy)
EVT_MENU(EDIT_MENU_PASTE,SubsTextEditCtrl::OnPaste)
EVT_MENU(EDIT_MENU_UNDO,SubsTextEditCtrl::OnUndo)
EVT_MENU(EDIT_MENU_SELECT_ALL,SubsTextEditCtrl::OnSelectAll)
EVT_MENU(EDIT_MENU_ADD_TO_DICT,SubsTextEditCtrl::OnAddToDictionary)
EVT_MENU_RANGE(EDIT_MENU_SUGGESTIONS,EDIT_MENU_THESAURUS-1,SubsTextEditCtrl::OnUseSuggestion)
EVT_MENU_RANGE(EDIT_MENU_THESAURUS_SUGS,EDIT_MENU_DIC_LANGUAGE-1,SubsTextEditCtrl::OnUseThesaurusSuggestion)
EVT_MENU_RANGE(EDIT_MENU_THESAURUS_SUGS,EDIT_MENU_DIC_LANGUAGE-1,SubsTextEditCtrl::OnUseSuggestion)
EVT_MENU_RANGE(EDIT_MENU_DIC_LANGS,EDIT_MENU_THES_LANGUAGE-1,SubsTextEditCtrl::OnSetDicLanguage)
EVT_MENU_RANGE(EDIT_MENU_THES_LANGS,EDIT_MENU_THES_LANGS+100,SubsTextEditCtrl::OnSetThesLanguage)
END_EVENT_TABLE()
/// @brief Lose focus
/// @param event
///
void SubsTextEditCtrl::OnLoseFocus(wxFocusEvent &event) {
CallTipCancel();
event.Skip();
}
/// @brief Set styles
///
void SubsTextEditCtrl::SetStyles() {
// Styles
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
font.SetEncoding(wxFONTENCODING_DEFAULT); // this solves problems with some fonts not working properly
wxString fontname = lagi_wxString(OPT_GET("Subtitle/Edit Box/Font Face")->GetString());
if (fontname != _T("")) font.SetFaceName(fontname);
if (!fontname.empty()) font.SetFaceName(fontname);
int size = OPT_GET("Subtitle/Edit Box/Font Size")->GetInt();
// Normal style
@ -256,19 +260,11 @@ void SubsTextEditCtrl::SetStyles() {
IndicatorSetForeground(0,wxColour(255,0,0));
}
/// @brief Style a range
/// @param start
/// @param _length
/// @return
///
void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
// Styling enabled?
if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return;
// Check if it's a template line
AssDialogue *diag = control->grid->GetActiveLine();
AssDialogue *diag = grid->GetActiveLine();
bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("template"));
//bool templateCodeLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("code"));
@ -320,7 +316,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
}
// Start override block
if (curChar == _T('{') && depth >= 0) {
if (curChar == '{' && depth >= 0) {
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
ran = 0;
@ -331,7 +327,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
}
// End override block
else if (curChar == _T('}') && depth <= 1) {
else if (curChar == '}' && depth <= 1) {
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
ran = 0;
@ -342,21 +338,21 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
}
// Karaoke template block
else if (templateLine && curChar == _T('!')) {
else if (templateLine && curChar == '!') {
// Apply previous style
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
ran = -1; // such that ran++ later on resets it to 0 !
// Eat entire template block
int endPos = i+1;
while (endPos < end && text[endPos] != _T('!'))
while (endPos < end && text[endPos] != '!')
endPos++;
SetUnicodeStyling(curPos,endPos-curPos+1,7);
curPos = endPos+1;
i = endPos+0;
}
// Karaoke template variable
else if (templateLine && curChar == _T('$')) {
else if (templateLine && curChar == '$') {
// Apply previous style
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
@ -365,7 +361,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
int endPos = i+1;
while (endPos < end) {
wxChar ch = text[endPos];
if ((ch >= _T('A') && ch <= _T('Z')) || (ch >= _T('a') && ch <= _T('z')) || ch == _T('_'))
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_')
endPos++;
else
break;
@ -381,7 +377,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
numMode = false;
// Is \n, \N or \h?
if (curChar == _T('\\') && (nextChar == 'n' || nextChar == 'N' || nextChar == 'h')) {
if (curChar == L'\\' && (nextChar == 'n' || nextChar == 'N' || nextChar == 'h')) {
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
ran = 1;
@ -402,7 +398,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
// Inside
else if (depth == 1) {
// Special character
if (curChar == _T('\\') || curChar == _T('(') || curChar == _T(')') || curChar == _T(',')) {
if (curChar == L'\\' || curChar == '(' || curChar == ')' || curChar == ',') {
if (curStyle != 2) {
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
@ -414,7 +410,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
else {
// Number
if (prevChar != _T('\\') && (numMode || (curChar >= '0' && curChar <= '9') || curChar == '.' || curChar == '&' || curChar == '+' || curChar == '-' || (curChar == 'H' && prevChar == '&'))) {
if (prevChar != L'\\' && (numMode || (curChar >= '0' && curChar <= '9') || curChar == '.' || curChar == '&' || curChar == '+' || curChar == '-' || (curChar == 'H' && prevChar == '&'))) {
if (curStyle != 5) {
SetUnicodeStyling(curPos,ran,curStyle);
curPos += ran;
@ -433,8 +429,8 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
// Set parameter if it's \fn or \r
int tagLen = 0;
if (text.Mid(curPos,2) == _T("fn")) tagLen = 2;
else if (text.Mid(curPos,1) == _T("r")) tagLen = 1;
if (text.Mid(curPos,2) == L"fn") tagLen = 2;
else if (text.Mid(curPos,1) == L"r") tagLen = 1;
if (tagLen) {
numMode = true;
ran = tagLen-1;
@ -442,21 +438,21 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
}
// Set drawing mode if it's \p
if (text.Mid(curPos,1) == _T("p")) {
if (text.Mid(curPos,1) == L"p") {
if (curPos+2 < (signed) text.Length()) {
// Disable
wxChar nextNext = text[curPos+2];
if ((nextNext == _T('\\') || nextNext == _T('}')) && nextChar == _T('0')) drawingMode = false;
if ((nextNext == L'\\' || nextNext == '}') && nextChar == '0') drawingMode = false;
// Enable
if (nextChar >= _T('1') && nextChar <= _T('9')) {
if (nextChar >= '1' && nextChar <= '9') {
for(int testPos = curPos+2;testPos < (signed) text.Length();testPos++) {
nextNext = text[testPos];
if (nextNext == _T('\\') || nextNext == _T('}')) {
if (nextNext == L'\\' || nextNext == '}') {
drawingMode = true;
break;
}
if (nextNext < _T('0') || nextNext > _T('9')) break;
if (nextNext < '0' || nextNext > '9') break;
}
}
}
@ -469,21 +465,15 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
ran++;
}
SetUnicodeStyling(curPos,ran,curStyle);
// Spell check
StyleSpellCheck(start,_length);
// Call tip
UpdateCallTip();
wxStyledTextEvent evt;
UpdateCallTip(evt);
}
/// @brief Update call tip
/// @return
///
void SubsTextEditCtrl::UpdateCallTip() {
// Enabled?
void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
if (!OPT_GET("App/Call Tips")->GetBool()) return;
// Get position and text
@ -503,11 +493,11 @@ void SubsTextEditCtrl::UpdateCallTip() {
else curChar = 0;
// Change depth
if (curChar == _T('{')) {
if (curChar == '{') {
depth++;
continue;
}
if (curChar == _T('}')) {
if (curChar == '}') {
depth--;
if (i >= pos && depth == 0) {
tagEnd = i-1;
@ -527,13 +517,13 @@ void SubsTextEditCtrl::UpdateCallTip() {
if (depth == 1) {
// Inner depth
if (tagStart != -1) {
if (curChar == _T('(')) inDepth++;
else if (curChar == _T(')')) inDepth--;
if (curChar == '(') inDepth++;
else if (curChar == ')') inDepth--;
}
// Not inside parenthesis
if (inDepth == 0) {
if (prevChar == _T('\\')) {
if (prevChar == L'\\') {
// Found start
if (i <= pos) tagStart = i;
@ -578,17 +568,17 @@ void SubsTextEditCtrl::UpdateCallTip() {
bool isEnd = false;
// Commas
if (curChar == _T(',')) {
if (curChar == ',') {
tagCommas++;
parN++;
}
// Parenthesis
else if (curChar == _T('(')) {
else if (curChar == '(') {
tagParenthesis++;
parN++;
}
else if (curChar == _T(')')) {
else if (curChar == ')') {
tagParenthesis++;
parN++;
isEnd = true;
@ -603,7 +593,7 @@ void SubsTextEditCtrl::UpdateCallTip() {
// Parameter it's on
if (i == posInTag) {
parPos = parN;
if (curChar == _T(',') || curChar == _T('(') || curChar == _T(')')) {
if (curChar == ',' || curChar == '(' || curChar == ')') {
parPos--;
}
}
@ -628,18 +618,18 @@ void SubsTextEditCtrl::UpdateCallTip() {
bool semiProto = false;
for (unsigned int i=0;i<proto.Count();i++) {
// Get prototype name
int div = proto[i].Find(_T(';'));
int div = proto[i].Find(';');
if (div != wxNOT_FOUND) protoName = proto[i].Left(div);
else {
div = proto[i].Find(_T('('));
div = proto[i].Find('(');
protoName = proto[i].Left(div);
}
// Fix name
semiProto = false;
cleanProto = proto[i];
if (cleanProto.Freq(_T(';')) > 0) {
cleanProto.Replace(_T(";"),_T(""));
if (cleanProto.Freq(';') > 0) {
cleanProto.Replace(L";","");
semiProto = true;
}
@ -649,7 +639,7 @@ void SubsTextEditCtrl::UpdateCallTip() {
else temp = tagName;
if (protoName == temp) {
// Parameter count match
if (proto[i].Freq(_T(',')) >= tagCommas) {
if (proto[i].Freq(',') >= tagCommas) {
// Found
useProto = proto[i];
protoN = i;
@ -674,8 +664,8 @@ void SubsTextEditCtrl::UpdateCallTip() {
int delta = 0;
for (unsigned int i=0;i<useProto.Length();i++) {
wxChar curChar = useProto[i];
if (i == 0 || curChar == _T(',') || curChar == _T(';') || curChar == _T('(') || curChar == _T(')')) {
if (curChar == _T(';')) delta++;
if (i == 0 || curChar == ',' || curChar == ';' || curChar == '(' || curChar == ')') {
if (curChar == ';') delta++;
if (parN == parPos) highStart = i+1-delta;
else if (parN == parPos+1) highEnd = i;
parN++;
@ -696,16 +686,8 @@ void SubsTextEditCtrl::UpdateCallTip() {
CallTipSetHighlight(highStart,highEnd);
}
/// @brief Spell check
/// @param start
/// @param len
/// @return
///
void SubsTextEditCtrl::StyleSpellCheck(int start, int len) {
// See if it has a spellchecker
if (!spellchecker) return;
if (!spellchecker.get()) return;
// Results
wxString text = GetText();
@ -737,50 +719,31 @@ void SubsTextEditCtrl::StyleSpellCheck(int start, int len) {
SetUnicodeStyling(text.Length(), 0, 0);
}
/// @brief Set text to a new value
/// @param _text
///
void SubsTextEditCtrl::SetTextTo(const wxString _text) {
// Setup
control->textEditReady = false;
void SubsTextEditCtrl::SetTextTo(wxString text) {
SetEvtHandlerEnabled(false);
Freeze();
wxString text = _text;
text.Replace(_T("\r\n"),_T("\\N"));
//text.Replace(_T("\n\r"),_T("\\N")); // never a valid linebreak
text.Replace(_T("\r"),_T("\\N"));
text.Replace(_T("\n"),_T("\\N"));
// Prepare
text.Replace(L"\r\n",L"\\N");
text.Replace(L"\r",L"\\N");
text.Replace(L"\n",L"\\N");
int from=0,to=0;
GetSelection(&from,&to);
Clear();
// Set text
SetText(text);
// Style
UpdateStyle();
// Restore selection
SetSelectionU(GetReverseUnicodePosition(from),GetReverseUnicodePosition(to));
// Finish
SetEvtHandlerEnabled(true);
Thaw();
control->textEditReady = true;
}
/// @brief Mouse event
/// @param event
/// @return
///
void SubsTextEditCtrl::OnMouseEvent(wxMouseEvent &event) {
// Right click
if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) {
if (control->grid->GetActiveLine() != 0) {
if (grid->GetActiveLine() != 0) {
int pos = PositionFromPoint(event.GetPosition());
ShowPopupMenu(pos);
return;
@ -791,44 +754,30 @@ void SubsTextEditCtrl::OnMouseEvent(wxMouseEvent &event) {
GetParent()->GetEventHandler()->ProcessEvent(event);
}
/// @brief Show popup menu
/// @param activePos
///
void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
// Menu
wxMenu menu;
// Position
if (activePos == -1) activePos = GetCurrentPos();
activePos = GetReverseUnicodePosition(activePos);
// Get current word under cursor
currentWord = GetWordAtPosition(activePos);
currentWordPos = activePos;
// Spell check
//int style = GetStyleAt(activePos);
if (spellchecker && currentWord.Length()) {
// Spelled right?
if (spellchecker.get() && currentWord.Length()) {
bool rightSpelling = spellchecker->CheckWord(currentWord);
// Set font
wxFont font;
font.SetWeight(wxFONTWEIGHT_BOLD);
// Get suggestions
sugs.Clear();
sugs = spellchecker->GetSuggestions(currentWord);
int nSugs = sugs.Count();
// Spelled wrong
if (!rightSpelling) {
// No suggestions
if (!nSugs) menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false);
if (!nSugs) {
menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false);
}
// Build menu
for (int i=0;i<nSugs;i++) {
wxMenuItem *itm = new wxMenuItem(&menu, EDIT_MENU_SUGGESTIONS+i, sugs[i]);
#ifdef __WINDOWS__
@ -839,31 +788,23 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
// Append "add word"
wxString add_to_dict_text(_("Add \"%s\" to dictionary"));
add_to_dict_text.Replace(_T("%s"), currentWord);
add_to_dict_text.Replace(L"%s", currentWord);
menu.Append(EDIT_MENU_ADD_TO_DICT,add_to_dict_text)->Enable(spellchecker->CanAddWord(currentWord));
}
// Spelled right
else {
// No suggestions
if (!nSugs) menu.Append(EDIT_MENU_SUGGESTION,_("No spell checker suggestions"))->Enable(false);
// Has suggestions
if (!nSugs) {
menu.Append(EDIT_MENU_SUGGESTION,_("No spell checker suggestions"))->Enable(false);
}
else {
// Build list
wxMenu *subMenu = new wxMenu();
for (int i=0;i<nSugs;i++) subMenu->Append(EDIT_MENU_SUGGESTIONS+i,sugs[i]);
menu.Append(-1,wxString::Format(_("Spell checker suggestions for \"%s\""),currentWord.c_str()), subMenu);
}
// Separator
//if (!thesaurus) menu.AppendSeparator();
}
// Language list
wxArrayString langs = spellchecker->GetLanguageList(); // This probably should be cached...
// Current language
wxArrayString langs = spellchecker->GetLanguageList(); // This probably should be cached...
wxString curLang = lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString());
// Languages
@ -891,7 +832,7 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
}
// Thesaurus
if (thesaurus && currentWord.Length()) {
if (thesaurus.get() && currentWord.Length()) {
// Get results
ThesaurusEntryArray result;
thesaurus->Lookup(currentWord,result);
@ -904,9 +845,7 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
}
}
// Has suggestions
if (result.size()) {
// Set font
wxFont font;
font.SetStyle(wxFONTSTYLE_ITALIC);
@ -938,18 +877,14 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
// Thesaurus menu
wxString thes_suggestion_text(_("Thesaurus suggestions for \"%s\""));
thes_suggestion_text.Replace(_T("%s"), currentWord);
thes_suggestion_text.Replace(L"%s", currentWord);
menu.Append(-1,thes_suggestion_text,thesMenu);
}
// No suggestions
if (!result.size()) menu.Append(EDIT_MENU_THESAURUS,_("No thesaurus suggestions"))->Enable(false);
// Language list
wxArrayString langs = thesaurus->GetLanguageList(); // This probably should be cached...
// Current language
wxString curLang = lagi_wxString(OPT_GET("Tool/Thesaurus/Language")->GetString());
// Languages
@ -977,8 +912,6 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
}
// Standard actions
menu.Append(EDIT_MENU_UNDO,_("&Undo"))->Enable(CanUndo());
menu.AppendSeparator();
menu.Append(EDIT_MENU_CUT,_("Cu&t"))->Enable(GetSelectionStart()-GetSelectionEnd() != 0);
menu.Append(EDIT_MENU_COPY,_("&Copy"))->Enable(GetSelectionStart()-GetSelectionEnd() != 0);
menu.Append(EDIT_MENU_PASTE,_("&Paste"))->Enable(CanPaste());
@ -990,139 +923,49 @@ void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
menu.Append(EDIT_MENU_SPLIT_PRESERVE,_("Split at cursor (preserve times)"));
menu.Append(EDIT_MENU_SPLIT_ESTIMATE,_("Split at cursor (estimate times)"));
// Pop the menu
PopupMenu(&menu);
}
/// @brief Split line preserving times
/// @param event
///
void SubsTextEditCtrl::OnSplitLinePreserve (wxCommandEvent &event) {
void SubsTextEditCtrl::OnSplitLinePreserve (wxCommandEvent &) {
int from,to;
GetSelection(&from, &to);
from = GetReverseUnicodePosition(from);
to = GetReverseUnicodePosition(to);
// Call SplitLine() with the text currently in the editbox.
// This makes sure we split what the user sees, not the committed line.
control->grid->SplitLine(control->grid->GetDialogueIndex(control->grid->GetActiveLine()),from,0,GetText());
grid->SplitLine(grid->GetActiveLine(),from,0);
}
/// @brief Split line estimating times
/// @param event
///
void SubsTextEditCtrl::OnSplitLineEstimate (wxCommandEvent &event) {
void SubsTextEditCtrl::OnSplitLineEstimate (wxCommandEvent &) {
int from,to;
GetSelection(&from, &to);
from = GetReverseUnicodePosition(from);
to = GetReverseUnicodePosition(to);
// Call SplitLine() with the text currently in the editbox.
// This makes sure we split what the user sees, not the committed line.
control->grid->SplitLine(control->grid->GetDialogueIndex(control->grid->GetActiveLine()),from,1,GetText());
grid->SplitLine(grid->GetActiveLine(),from,1);
}
/// @brief Cut
/// @param event
///
void SubsTextEditCtrl::OnCut(wxCommandEvent &event) {
Cut();
}
/// @brief Copy
/// @param event
///
void SubsTextEditCtrl::OnCopy(wxCommandEvent &event) {
Copy();
}
/// @brief Paste
/// @param event
///
void SubsTextEditCtrl::OnPaste(wxCommandEvent &event) {
Paste();
}
/// @brief Undo
/// @param event
///
void SubsTextEditCtrl::OnUndo(wxCommandEvent &event) {
Undo();
}
/// @brief Select All
/// @param event
///
void SubsTextEditCtrl::OnSelectAll(wxCommandEvent &event) {
SelectAll();
}
/// @brief Add word to dictionary
/// @param event
///
void SubsTextEditCtrl::OnAddToDictionary(wxCommandEvent &event) {
if (spellchecker) spellchecker->AddWord(currentWord);
void SubsTextEditCtrl::OnAddToDictionary(wxCommandEvent &) {
if (spellchecker.get()) spellchecker->AddWord(currentWord);
UpdateStyle();
SetFocus();
}
/// @brief Use suggestion
/// @param event
///
void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) {
// Get suggestion
wxString suggestion = sugs[event.GetId()-EDIT_MENU_SUGGESTIONS];
// Get boundaries of text being replaced
int start,end;
GetBoundsOfWordAtPosition(currentWordPos,start,end);
// Replace
wxString text = GetText();
SetText(text.Left(MAX(0,start)) + suggestion + text.Mid(end+1));
// Set selection
SetSelectionU(start,start+suggestion.Length());
SetFocus();
}
/// @brief Use thesaurus suggestion
/// @param event
///
void SubsTextEditCtrl::OnUseThesaurusSuggestion(wxCommandEvent &event) {
// Get suggestion
wxString suggestion = thesSugs[event.GetId()-EDIT_MENU_THESAURUS_SUGS];
wxString suggestion;
int sugIdx = event.GetId() - EDIT_MENU_THESAURUS_SUGS;
if (sugIdx >= 0) {
suggestion = thesSugs[sugIdx];
}
else {
suggestion = sugs[event.GetId() - EDIT_MENU_SUGGESTIONS];
}
// Stripe suggestion of parenthesis
int pos = suggestion.Find(_T("("));
int pos = suggestion.Find(L"(");
if (pos != wxNOT_FOUND) {
suggestion = suggestion.Left(pos-1);
}
// Get boundaries of text being replaced
int start,end;
GetBoundsOfWordAtPosition(currentWordPos,start,end);
// Replace
wxString text = GetText();
SetText(text.Left(MAX(0,start)) + suggestion + text.Mid(end+1));
@ -1131,13 +974,7 @@ void SubsTextEditCtrl::OnUseThesaurusSuggestion(wxCommandEvent &event) {
SetFocus();
}
/// @brief Set dictionary language
/// @param event
///
void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
// Get language list
wxArrayString langs = spellchecker->GetLanguageList();
// Set dictionary
@ -1147,17 +984,10 @@ void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
spellchecker->SetLanguage(lang);
OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(lang));
// Update styling
UpdateStyle();
}
/// @brief Set thesaurus language
/// @param event
///
void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
// Get language list
wxArrayString langs = thesaurus->GetLanguageList();
// Set language
@ -1167,8 +997,5 @@ void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
thesaurus->SetLanguage(lang);
OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(lang));
// Update styling
UpdateStyle();
}

View File

@ -34,19 +34,16 @@
/// @ingroup main_ui
///
#ifndef AGI_PRE
#include <memory>
#endif
////////////
// Includes
#include "scintilla_text_ctrl.h"
#include "spellchecker_manager.h"
#include "thesaurus.h"
//////////////
// Prototypes
class SpellChecker;
class SubsEditBox;
class SubtitlesGrid;
class Thesaurus;
/// DOCME
/// @class SubsTextEditCtrl
@ -54,13 +51,13 @@ class SubsEditBox;
///
/// DOCME
class SubsTextEditCtrl : public ScintillaTextCtrl {
private:
/// DOCME
std::auto_ptr<SpellChecker> spellchecker;
/// DOCME
SpellChecker *spellchecker;
std::auto_ptr<Thesaurus> thesaurus;
/// DOCME
Thesaurus *thesaurus;
SubtitlesGrid *grid;
/// DOCME
@ -87,87 +84,21 @@ private:
void OnMouseEvent(wxMouseEvent &event);
void OnSplitLinePreserve(wxCommandEvent &event);
void OnSplitLineEstimate(wxCommandEvent &event);
void OnCut(wxCommandEvent &event);
void OnCopy(wxCommandEvent &event);
void OnPaste(wxCommandEvent &event);
void OnUndo(wxCommandEvent &event);
void OnSelectAll(wxCommandEvent &event);
void OnAddToDictionary(wxCommandEvent &event);
void OnUseSuggestion(wxCommandEvent &event);
void OnUseThesaurusSuggestion(wxCommandEvent &event);
void OnSetDicLanguage(wxCommandEvent &event);
void OnSetThesLanguage(wxCommandEvent &event);
void OnLoseFocus(wxFocusEvent &event);
public:
/// DOCME
SubsEditBox *control;
SubsTextEditCtrl(wxWindow* parent, wxWindowID id, const wxString& value = _T(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr);
SubsTextEditCtrl(wxWindow* parent, wxSize size, long style, SubtitlesGrid *grid);
~SubsTextEditCtrl();
void SetTextTo(const wxString text);
void SetTextTo(wxString text);
void UpdateStyle(int start=0,int length=-1);
void StyleSpellCheck(int start=0,int length=-1);
void UpdateCallTip();
void UpdateCallTip(wxStyledTextEvent &);
void SetStyles();
DECLARE_EVENT_TABLE()
};
///////
// IDs
enum {
/// DOCME
EDIT_MENU_SPLIT_PRESERVE = 1400,
/// DOCME
EDIT_MENU_SPLIT_ESTIMATE,
/// DOCME
EDIT_MENU_CUT,
/// DOCME
EDIT_MENU_COPY,
/// DOCME
EDIT_MENU_PASTE,
/// DOCME
EDIT_MENU_UNDO,
/// DOCME
EDIT_MENU_SELECT_ALL,
/// DOCME
EDIT_MENU_ADD_TO_DICT,
/// DOCME
EDIT_MENU_SUGGESTION,
/// DOCME
EDIT_MENU_SUGGESTIONS,
/// DOCME
EDIT_MENU_THESAURUS = 1450,
/// DOCME
EDIT_MENU_THESAURUS_SUGS,
/// DOCME
EDIT_MENU_DIC_LANGUAGE = 1600,
/// DOCME
EDIT_MENU_DIC_LANGS,
/// DOCME
EDIT_MENU_THES_LANGUAGE = 1700,
/// DOCME
EDIT_MENU_THES_LANGS
};

View File

@ -88,8 +88,6 @@ BEGIN_EVENT_TABLE(SubtitlesGrid, BaseGrid)
EVT_MENU_RANGE(MENU_SHOW_COL,MENU_SHOW_COL+15,SubtitlesGrid::OnShowColMenu)
END_EVENT_TABLE()
/// @brief Constructor
/// @param parentFr
/// @param parent
@ -98,31 +96,22 @@ END_EVENT_TABLE()
/// @param size
/// @param style
/// @param name
///
SubtitlesGrid::SubtitlesGrid(FrameMain* parentFr, wxWindow *parent, wxWindowID id, AssFile *subs, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: BaseGrid(parent,id,pos,size,style,name)
, ass(subs)
{
// Vars
byFrame = false;
editBox = NULL;
parentFrame = parentFr;
}
/// @brief Destructor
///
SubtitlesGrid::~SubtitlesGrid() {
ClearMaps();
}
/// @brief Popup menu
/// @param alternate
/// @return
///
void SubtitlesGrid::OnPopupMenu(bool alternate) {
// Alternate
if (alternate) {
@ -212,11 +201,8 @@ void SubtitlesGrid::OnPopupMenu(bool alternate) {
}
}
/// @brief Process a show/hide column event
/// @param event
///
void SubtitlesGrid::OnShowColMenu(wxCommandEvent &event) {
int item = event.GetId()-MENU_SHOW_COL;
showCol[item] = !showCol[item];
@ -229,12 +215,8 @@ void SubtitlesGrid::OnShowColMenu(wxCommandEvent &event) {
Refresh(false);
}
/// @brief Process keyboard events
/// @param event
/// @return
///
void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
// Get key
#ifdef __APPLE__
@ -322,103 +304,70 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
event.Skip();
}
///////////////////////
// Duplicate selection
void SubtitlesGrid::OnDuplicate (wxCommandEvent &WXUNUSED(&event)) {
void SubtitlesGrid::OnDuplicate (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
DuplicateLines(sels.front(),sels.back());
EndBatch();
}
//////////////////////////////////////////////
// Duplicate selection and shift by one frame
void SubtitlesGrid::OnDuplicateNextFrame (wxCommandEvent &WXUNUSED(&event)) {
void SubtitlesGrid::OnDuplicateNextFrame (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
DuplicateLines(sels.front(),sels.back(),true);
EndBatch();
}
/// @brief Call swap
/// @param event
///
void SubtitlesGrid::OnSwap (wxCommandEvent &event) {
void SubtitlesGrid::OnSwap (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
SwapLines(sels.front(),sels.back());
EndBatch();
}
/// @brief Call join (concatenate)
/// @param event
///
void SubtitlesGrid::OnJoinConcat (wxCommandEvent &event) {
void SubtitlesGrid::OnJoinConcat (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
JoinLines(sels.front(),sels.back(),true);
EndBatch();
}
/// @brief Call join (replace)
/// @param event
///
void SubtitlesGrid::OnJoinReplace (wxCommandEvent &event) {
void SubtitlesGrid::OnJoinReplace (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
JoinLines(sels.front(),sels.back(),false);
EndBatch();
}
/// @brief Adjoin lines
/// @param event
///
void SubtitlesGrid::OnAdjoin (wxCommandEvent &event) {
void SubtitlesGrid::OnAdjoin (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
AdjoinLines(sels.front(),sels.back(),true);
EndBatch();
}
/// @brief DOCME
/// @param event
///
void SubtitlesGrid::OnAdjoin2 (wxCommandEvent &event) {
void SubtitlesGrid::OnAdjoin2 (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
AdjoinLines(sels.front(),sels.back(),false);
EndBatch();
}
/// @brief Call join as karaoke
/// @param event
///
void SubtitlesGrid::OnJoinAsKaraoke (wxCommandEvent &event) {
void SubtitlesGrid::OnJoinAsKaraoke (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
JoinAsKaraoke(sels.front(),sels.back());
EndBatch();
}
/// @brief Call split by karaoke
/// @param event
///
void SubtitlesGrid::OnSplitByKaraoke (wxCommandEvent &event) {
void SubtitlesGrid::OnSplitByKaraoke (wxCommandEvent &) {
BeginBatch();
wxArrayInt sels = GetSelection();
bool didSplit = false;
@ -432,12 +381,8 @@ void SubtitlesGrid::OnSplitByKaraoke (wxCommandEvent &event) {
EndBatch();
}
/// @brief Call insert before
/// @param event
///
void SubtitlesGrid::OnInsertBefore (wxCommandEvent &event) {
void SubtitlesGrid::OnInsertBefore (wxCommandEvent &) {
BeginBatch();
// Find line
int n = GetFirstSelRow();
@ -466,12 +411,8 @@ void SubtitlesGrid::OnInsertBefore (wxCommandEvent &event) {
EndBatch();
}
/// @brief Call insert after
/// @param event
///
void SubtitlesGrid::OnInsertAfter (wxCommandEvent &event) {
void SubtitlesGrid::OnInsertAfter (wxCommandEvent &) {
BeginBatch();
// Find line
int n = GetFirstSelRow();
@ -498,12 +439,8 @@ void SubtitlesGrid::OnInsertAfter (wxCommandEvent &event) {
EndBatch();
}
/// @brief Call insert before with video
/// @param event
///
void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &) {
BeginBatch();
// Find line
int n = GetFirstSelRow();
@ -522,12 +459,8 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
EndBatch();
}
/// @brief Call insert after with video
/// @param event
///
void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &) {
BeginBatch();
// Find line
int n = GetFirstSelRow();
@ -546,75 +479,51 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
EndBatch();
}
///////////////////////////////
// Copy selection to clipboard
void SubtitlesGrid::OnCopyLines (wxCommandEvent &WXUNUSED(&event)) {
/// Copy selection to clipboard
void SubtitlesGrid::OnCopyLines (wxCommandEvent &) {
CopyLines(GetSelection());
}
///////////////////////////////
// Cuts selection to clipboard
void SubtitlesGrid::OnCutLines (wxCommandEvent &WXUNUSED(&event)) {
/// Cuts selection to clipboard
void SubtitlesGrid::OnCutLines (wxCommandEvent &) {
CutLines(GetSelection());
}
////////////////////////
// Paste from clipboard
void SubtitlesGrid::OnPasteLines (wxCommandEvent &WXUNUSED(&event)) {
/// Paste from clipboard
void SubtitlesGrid::OnPasteLines (wxCommandEvent &) {
PasteLines(GetFirstSelRow());
}
///////////////////////////////
// Copy selection to clipboard
void SubtitlesGrid::OnDeleteLines (wxCommandEvent &WXUNUSED(&event)) {
/// Copy selection to clipboard
void SubtitlesGrid::OnDeleteLines (wxCommandEvent &) {
BeginBatch();
DeleteLines(GetSelection());
EndBatch();
}
/// @brief Set start to video pos
/// @param event
///
void SubtitlesGrid::OnSetStartToVideo(wxCommandEvent &event) {
void SubtitlesGrid::OnSetStartToVideo(wxCommandEvent &) {
BeginBatch();
SetSubsToVideo(true);
EndBatch();
}
/// @brief Set end to video pos
/// @param event
///
void SubtitlesGrid::OnSetEndToVideo(wxCommandEvent &event) {
void SubtitlesGrid::OnSetEndToVideo(wxCommandEvent &) {
BeginBatch();
SetSubsToVideo(false);
EndBatch();
}
/// @brief Set video pos to start
/// @param event
///
void SubtitlesGrid::OnSetVideoToStart(wxCommandEvent &event) {
void SubtitlesGrid::OnSetVideoToStart(wxCommandEvent &) {
BeginBatch();
SetVideoToSubs(true);
EndBatch();
}
/// @brief Set video pos to end
/// @param event
///
void SubtitlesGrid::OnSetVideoToEnd(wxCommandEvent &event) {
void SubtitlesGrid::OnSetVideoToEnd(wxCommandEvent &) {
BeginBatch();
SetVideoToSubs(false);
EndBatch();
@ -718,14 +627,8 @@ void SubtitlesGrid::OnRecombine(wxCommandEvent &) {
SetActiveLine(activeLine);
}
/// @brief Export audio clip of line
/// @param event
/// @return
///
void SubtitlesGrid::OnAudioClip(wxCommandEvent &event) {
void SubtitlesGrid::OnAudioClip(wxCommandEvent &) {
int64_t num_samples,start=0,end=0,temp;
AudioDisplay *audioDisplay = parentFrame->audioBox->audioDisplay;
AudioProvider *provider = audioDisplay->provider;
@ -805,7 +708,6 @@ void SubtitlesGrid::OnAudioClip(wxCommandEvent &event) {
/// @brief Clears grid and sets it to default
/// @param _ass
///
void SubtitlesGrid::LoadDefault () {
ass->LoadDefault();
ClearMaps();
@ -824,13 +726,9 @@ void SubtitlesGrid::UpdateMaps(bool preserve_selected_rows) {
}
}
/// @brief Swaps two lines
/// @param n1
/// @param n2
/// @return
///
void SubtitlesGrid::SwapLines(int n1,int n2) {
AssDialogue *dlg1 = GetDialogue(n1);
AssDialogue *dlg2 = GetDialogue(n2);
@ -842,14 +740,11 @@ void SubtitlesGrid::SwapLines(int n1,int n2) {
CommitChanges();
}
/// @brief Insert a line
/// @param line
/// @param n
/// @param after
/// @param update
///
void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) {
AssDialogue *rel_line = GetDialogue(n + (after?1:0));
entryIter pos = std::find(ass->Line.begin(), ass->Line.end(), rel_line);
@ -864,11 +759,6 @@ void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) {
}
}
/// @brief Copy lines to clipboard
/// @param target
///
void SubtitlesGrid::CopyLines(wxArrayInt target) {
// Prepare text
wxString data = _T("");
@ -889,11 +779,6 @@ void SubtitlesGrid::CopyLines(wxArrayInt target) {
}
}
/// @brief Cut to clipboard
/// @param target
///
void SubtitlesGrid::CutLines(wxArrayInt target) {
BeginBatch();
CopyLines(target);
@ -901,18 +786,14 @@ void SubtitlesGrid::CutLines(wxArrayInt target) {
EndBatch();
}
/// @brief Paste lines from clipboard
/// @brief Paste lines from clipboard
/// @param n
/// @param pasteOver
/// @return
///
void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
BeginBatch();
// Prepare text
wxString data = _T("");
wxString data;
// Read from clipboard
if (wxTheClipboard->Open()) {
@ -941,7 +822,7 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
curdiag = new AssDialogue(curdata);
}
catch (...) {
// Line didn't parse correcly, assume it's plain text that
// Line didn't parse correctly, assume it's plain text that
// should be pasted in the Text field only
curdiag = new AssDialogue();
curdiag->Text = curdata;
@ -972,7 +853,6 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
if (pasteOverOptions[5]) target->Margin[0] = curdiag->Margin[0];
if (pasteOverOptions[6]) target->Margin[1] = curdiag->Margin[1];
if (pasteOverOptions[7]) target->Margin[2] = curdiag->Margin[2];
//if (pasteOverOptions[8]) target->Margin[3] = curdiag->Margin[3];
if (pasteOverOptions[8]) target->Effect = curdiag->Effect;
if (pasteOverOptions[9]) target->Text = curdiag->Text;
}
@ -1004,17 +884,9 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
}
}
}
// Done
EndBatch();
}
/// @brief Delete selected lines
/// @param target
/// @param flagModified
///
void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
entryIter before_first = std::find_if(ass->Line.begin(), ass->Line.end(), cast<AssDialogue*>()); --before_first;
int old_active_line_index = GetDialogueIndex(GetActiveLine());
@ -1048,18 +920,10 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
}
}
/// @brief Joins selected lines
/// @param n1
/// @param n2
/// @param concat
///
void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) {
// Initialize
int min_ms = 0x0FFFFFFF;
int max_ms = -1;
wxString finalText = _T("");
int min_ms = INT_MAX;
int max_ms = INT_MIN;
wxString finalText;
// Collect data
AssDialogue *cur;
@ -1110,14 +974,6 @@ void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) {
SelectRow(n1);
}
/// @brief Adjoins selected lines
/// @param n1
/// @param n2
/// @param setStart
/// @return
///
void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) {
// Set start
if (setStart) {
@ -1143,19 +999,11 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) {
}
}
// Commit
ass->Commit(_("adjoin"));
CommitChanges();
}
/// @brief Joins selected lines as karaoke
/// @param n1
/// @param n2
///
void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) {
// Initialize
wxString finalText = _T("");
// Collect data
@ -1202,13 +1050,6 @@ void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) {
SelectRow(n1);
}
/// @brief Duplicate lines
/// @param n1
/// @param n2
/// @param nextFrame
///
void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
AssDialogue *cur;
bool update = false;
@ -1239,91 +1080,41 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
SetActiveLine(GetDialogue(n1+step));
}
/// @brief Shifts line by time
/// @param n
/// @param len
/// @param type
///
/// Where type =
/// - 0: Start + End
/// - 1: Start
/// - 2: End
void SubtitlesGrid::ShiftLineByTime(int n,int len,int type) {
assert(type >= 0 && type <= 2);
AssDialogue *cur = GetDialogue(n);
if (type != 2) cur->Start.SetMS(cur->Start.GetMS() + len);
if (type != 1) cur->End.SetMS(cur->End.GetMS() + len);
}
/// @brief Shifts line by Frame
/// @param n
/// @param len
/// @param type
///
/// @see ShiftLineByTime()
void SubtitlesGrid::ShiftLineByFrames(int n,int len,int type) {
assert(type >= 0 && type <= 2);
AssDialogue *cur = GetDialogue(n);
if (type != 2) cur->Start.SetMS(context->TimeAtFrame(len + context->FrameAtTime(cur->Start.GetMS(),agi::vfr::START),agi::vfr::START));
if (type != 1) cur->End.SetMS(context->TimeAtFrame(len + context->FrameAtTime(cur->End.GetMS(),agi::vfr::END),agi::vfr::END));
}
void SubtitlesGrid::SplitLine(AssDialogue *n1,int pos,bool estimateTimes) {
AssDialogue *n2 = new AssDialogue(*n1);
InsertLine(n2,GetDialogueIndex(n1),true,false);
/// @brief Split line
/// @param n
/// @param pos
/// @param mode
/// @param textIn
/// @return
///
void SubtitlesGrid::SplitLine(int n,int pos,int mode,wxString textIn) {
// Split
AssDialogue *n1,*n2;
// No textIn? Get saved text
if (textIn.IsEmpty()) {
n1 = GetDialogue(n);
n2 = new AssDialogue(n1->GetEntryData());
}
// Otherwise use textIn
else {
n1 = GetDialogue(n);
n1->Text = textIn;
n2 = new AssDialogue(n1->GetEntryData());
}
InsertLine(n2,n,true,false);
// Modify text
wxString orig = n1->Text;
n1->Text = orig.Left(pos).Trim(true); // Trim off trailing whitespace
n2->Text = orig.Mid(pos).Trim(false); // Trim off leading whitespace
// Modify time
if (mode == 1) {
if (estimateTimes) {
double splitPos = double(pos)/orig.Length();
int splitTime = (int)((n1->End.GetMS() - n1->Start.GetMS())*splitPos) + n1->Start.GetMS();
n1->End.SetMS(splitTime);
n2->Start.SetMS(splitTime);
}
// Update editbox and audio
//editBox->SetToLine(n);
// Commit
ass->Commit(_("split"));
CommitChanges();
CommitChanges(false);
}
/// @brief Returns true if changes were made. DOES NOT FLAG AS MODIFIED OR COMMIT CHANGES timed as the syllables. Splits the line into as many new lines as there are karaoke syllables, --------------------- Split line by karaoke
/// @param lineNumber
/// @return
///
bool SubtitlesGrid::SplitLineByKaraoke(int lineNumber) {
AssDialogue *line = GetDialogue(lineNumber);
@ -1363,29 +1154,20 @@ bool SubtitlesGrid::SplitLineByKaraoke(int lineNumber) {
return true;
}
/// @brief This will save the work .ass and refresh it -------------- Commit changes
/// @param force
/// @param videoOnly
///
void SubtitlesGrid::CommitChanges(bool force,bool videoOnly) {
if (context->IsLoaded() || force) {
// Check if it's playing
void SubtitlesGrid::CommitChanges(bool ebox, bool video, bool autosave) {
if (video && context->IsLoaded()) {
bool playing = false;
if (context->IsPlaying()) {
playing = true;
context->Stop();
}
// Update video
if (context->IsLoaded()) context->Refresh();
context->Refresh();
// Resume play
if (playing) context->Play();
}
if (!videoOnly) {
if (autosave) {
// Autosave if option is enabled
if (OPT_GET("App/Auto/Save on Every Change")->GetBool()) {
if (ass->IsModified() && !ass->filename.IsEmpty()) parentFrame->SaveSubtitles(false);
@ -1396,12 +1178,11 @@ void SubtitlesGrid::CommitChanges(bool force,bool videoOnly) {
SetColumnWidths();
Refresh(false);
}
if (ebox) {
editBox->Update(false, false);
}
}
/// @brief Set start to video pos
/// @param start
/// @return
///
void SubtitlesGrid::SetSubsToVideo(bool start) {
if (!context->IsLoaded()) return;
@ -1410,18 +1191,16 @@ void SubtitlesGrid::SetSubsToVideo(bool start) {
// Update selection
wxArrayInt sel = GetSelection();
AssDialogue *cur;
int modified =0;
bool modified = false;
for (size_t i=0;i<sel.Count();i++) {
cur = GetDialogue(sel[i]);
AssDialogue *cur = GetDialogue(sel[i]);
if (cur) {
modified++;
modified = true;
if (start) cur->Start.SetMS(ms);
else cur->End.SetMS(ms);
}
}
// Commit
if (modified) {
ass->Commit(_("timing"));
CommitChanges();
@ -1429,12 +1208,6 @@ void SubtitlesGrid::SetSubsToVideo(bool start) {
}
}
/// @brief Set video pos to start/end
/// @param start
/// @return
///
void SubtitlesGrid::SetVideoToSubs(bool start) {
wxArrayInt sel = GetSelection();
if (sel.Count() == 0) return;
@ -1468,8 +1241,6 @@ std::vector<int> SubtitlesGrid::GetAbsoluteSelection() {
return result;
}
/// @brief Update list of selected lines from absolute selection
/// @param selection
///
@ -1490,5 +1261,3 @@ void SubtitlesGrid::SetSelectionFromAbsolute(std::vector<int> &selection) {
SetSelectedSet(newsel);
}

View File

@ -56,7 +56,6 @@ class SubsEditBox;
class FrameMain;
class AudioDisplay;
/// DOCME
typedef std::list<AssEntry*>::iterator entryIter;
/// DOCME
@ -95,127 +94,120 @@ private:
void OnShowColMenu(wxCommandEvent &event);
public:
/// DOCME
/// Currently open file
AssFile *ass;
SubtitlesGrid(FrameMain* parentFrame,wxWindow *parent, wxWindowID id, AssFile *subs, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxPanelNameStr);
~SubtitlesGrid();
void LoadDefault();
void CommitChanges(bool force=false,bool videoOnly=false);
/// @brief Commit changes and update the current file
/// @param ebox Update the edit box
/// @param video Update the video display
/// @param complete Autosave (if enabled) and update other things which care about the file
void CommitChanges(bool ebox = true, bool video = true, bool complete = true);
void UpdateMaps(bool preserve_selected_rows = false);
/// @brief Jump to the start/end time of the current subtitle line
/// @param start Start vs. End time
void SetVideoToSubs(bool start);
/// @brief Set the start/end time of the current subtitle line to the current frame
/// @param start Start vs. End time
void SetSubsToVideo(bool start);
/// @brief Join the selected lines
/// @param n1 First line to join
/// @param n2 Last line to join
/// @param concat Concatenate the lines rather than discarding all past the first
void JoinLines(int first,int last,bool concat=true);
/// @brief Join selected lines as karaoke, with their relative times used for syllable lengths
/// @param n1 First line to join
/// @param n2 Last line to join
void JoinAsKaraoke(int first,int last);
/// @brief Adjoins selected lines, setting each line's start time to the previous line's end time
/// @param n1 First line to adjoin
/// @param n2 Last line to adjoin
/// @param setStart Set the start times (rather than end times)
void AdjoinLines(int first,int last,bool setStart);
void SplitLine(int lineNumber,int splitPosition,int mode,wxString splitText = _T(""));
/// @brief Split line at the given position
/// @param line Line to split
/// @param pos Position in line
/// @param estimateTimes Adjust the times based on the lengths of the halves
void SplitLine(AssDialogue *line,int splitPosition,bool estimateTimes);
/// @brief Split a line into as many new lines as there are karaoke syllables, timed as the syllables
/// @param lineNumber Line to split
/// @return Were changes made?
///
/// DOES NOT FLAG AS MODIFIED OR COMMIT CHANGES
bool SplitLineByKaraoke(int lineNumber);
/// @brief Duplicate lines
/// @param n1 First frame to duplicate
/// @param n2 Last frame to duplicate
/// @param nextFrame Set the new lines to start and end on the next frame
void DuplicateLines(int first,int last,bool nextFrame=false);
void SwapLines(int line1,int line2);
/// @brief Shift line by time
/// @param n Line to shift
/// @param len ms to shift by
/// @param type 0: Start + End; 1: Start; 2: End
void ShiftLineByTime(int lineNumber,int len,int type);
/// @brief Shift line by frames
/// @param n Line to shift
/// @param len frames to shift by
/// @param type 0: Start + End; 1: Start; 2: End
void ShiftLineByFrames(int lineNumber,int len,int type);
void InsertLine(AssDialogue *line,int position,bool insertAfter,bool update=true);
/// @brief Delete selected lines
/// @param target Lines to delete
/// @param flagModified Commit the file afterwards
void DeleteLines(wxArrayInt lines, bool flagModified=true);
/// @brief Copy to clipboard
/// @param target Lines to copy
void CopyLines(wxArrayInt lines);
/// @brief Cut to clipboard
/// @param target Lines to cut
void CutLines(wxArrayInt lines);
void PasteLines(int pos,bool over=false);
/// Retrieve a list of selected lines in the actual ASS file (i.e. not as displayed in the grid but as represented in the file)
std::vector<int> GetAbsoluteSelection();
/// @brief Update list of selected lines from absolute selection
/// @param selection Sorted list of selections
void SetSelectionFromAbsolute(std::vector<int> &selection);
DECLARE_EVENT_TABLE()
};
///////
// IDs
/// Menu event IDs
enum {
/// DOCME
MENU_GRID_START = 1200,
/// DOCME
MENU_INSERT_BEFORE,
/// DOCME
MENU_INSERT_AFTER,
/// DOCME
MENU_INSERT_BEFORE_VIDEO,
/// DOCME
MENU_INSERT_AFTER_VIDEO,
/// DOCME
MENU_SWAP,
/// DOCME
MENU_DUPLICATE,
/// DOCME
MENU_DUPLICATE_NEXT_FRAME,
/// DOCME
MENU_SPLIT_BY_KARAOKE,
/// DOCME
MENU_COPY,
/// DOCME
MENU_PASTE,
/// DOCME
MENU_CUT,
/// DOCME
MENU_DELETE,
/// DOCME
MENU_JOIN_CONCAT,
/// DOCME
MENU_JOIN_REPLACE,
/// DOCME
MENU_ADJOIN,
/// DOCME
MENU_ADJOIN2,
/// DOCME
MENU_JOIN_AS_KARAOKE,
/// DOCME
MENU_RECOMBINE,
/// DOCME
MENU_SET_START_TO_VIDEO,
/// DOCME
MENU_SET_END_TO_VIDEO,
/// DOCME
MENU_SET_VIDEO_TO_START,
/// DOCME
MENU_SET_VIDEO_TO_END,
/// DOCME
MENU_GRID_END,
/// DOCME
MENU_AUDIOCLIP,
/// DOCME
MENU_SHOW_COL = 1250 // Don't put anything after this
};

View File

@ -102,10 +102,8 @@ wxTextCtrl(parent,id,value,pos,size,TimeEditWindowStyle | style,validator,name)
ready = true;
byFrame = false;
isEnd = false;
modified = false;
showModified = false;
Connect(wxEVT_COMMAND_TEXT_UPDATED,wxCommandEventHandler(TimeEdit::OnModified));
Connect(wxEVT_KILL_FOCUS,wxFocusEventHandler(TimeEdit::OnKillFocus));
Bind(wxEVT_COMMAND_TEXT_UPDATED, &TimeEdit::OnModified, this);
}
BEGIN_EVENT_TABLE(TimeEdit, wxTextCtrl)
@ -119,52 +117,41 @@ END_EVENT_TABLE()
/// @param event
void TimeEdit::OnModified(wxCommandEvent &event) {
event.Skip();
if (!ready) return;
Modified();
}
/// @brief Modified function
/// @param byUser
void TimeEdit::Modified(bool byUser) {
void TimeEdit::Modified() {
if (!ready) return;
ready = false;
if (byFrame) Update();
else UpdateTime(byUser);
else UpdateTime(true);
// Colour
if (showModified && !modified) {
SetBackgroundColour(lagi_wxColour(OPT_GET("Colour/Background/Modified")->GetColour()));
}
modified = true;
ready = true;
}
/// @brief Set time and update stuff
/// @param ms
/// @param setModified
///
void TimeEdit::SetTime(int ms,bool setModified) {
int oldMs = time.GetMS();
time.SetMS(ms);
UpdateText();
if (setModified && oldMs != ms) Modified(false);
void TimeEdit::SetTime(AssTime newTime) {
if (newTime != time) {
time = newTime;
UpdateText();
}
}
/// @brief Toggles between set by frame and time
/// @param enable
void TimeEdit::SetByFrame(bool enable) {
if (enable == byFrame) return;
void TimeEdit::SetByFrame(bool enableByFrame) {
if (enableByFrame == byFrame) return;
// By frames
if (enable) {
if (enableByFrame) {
if (VideoContext::Get()->IsLoaded()) {
byFrame = true;
UpdateText();
}
}
// By actual time
else {
byFrame = false;
UpdateText();
@ -172,44 +159,32 @@ void TimeEdit::SetByFrame(bool enable) {
}
/// @brief Update text to reflect time value
///
void TimeEdit::UpdateText() {
ready = false;
if (byFrame) {
int frame_n = VideoContext::Get()->FrameAtTime(time.GetMS(),isEnd ? agi::vfr::END : agi::vfr::START);
SetValue(wxString::Format(_T("%i"),frame_n));
ChangeValue(wxString::Format("%i", frame_n));
}
else SetValue(time.GetASSFormated());
else ChangeValue(time.GetASSFormated());
ready = true;
}
/// @brief Update
///
void TimeEdit::Update() {
// Update frame
if (byFrame) {
long temp;
GetValue().ToLong(&temp);
time.SetMS(VideoContext::Get()->TimeAtFrame(temp,isEnd ? agi::vfr::END : agi::vfr::START));
SetTime(VideoContext::Get()->TimeAtFrame(temp,isEnd ? agi::vfr::END : agi::vfr::START));
}
// Update time if not on insertion mode
else if (!OPT_GET("Subtitle/Time Edit/Insert Mode")->GetBool()) {
UpdateTime();
SetValue(time.GetASSFormated());
}
// Update modified status
if (modified && showModified) {
SetBackgroundColour(wxNullColour);
Refresh();
}
modified = false;
}
/// @brief Reads value from a text control and update it
/// @param byUser
///
void TimeEdit::UpdateTime(bool byUser) {
bool insertion = OPT_GET("Subtitle/Time Edit/Insert Mode")->GetBool();
wxString text = GetValue();
@ -235,14 +210,13 @@ void TimeEdit::UpdateTime(bool byUser) {
// Update time
time.ParseASS(text);
if (insertion) {
SetValue(time.GetASSFormated());
ChangeValue(time.GetASSFormated());
SetSelection(start,end);
}
}
/// @brief Key pressed
/// @param event
///
void TimeEdit::OnKeyDown(wxKeyEvent &event) {
// Get key ID
int key = event.GetKeyCode();
@ -281,19 +255,6 @@ void TimeEdit::OnKeyDown(wxKeyEvent &event) {
}
}
/// @brief Focus lost
/// @param event
///
void TimeEdit::OnKillFocus(wxFocusEvent &event) {
if (!byFrame && !OPT_GET("Subtitle/Time Edit/Insert Mode")->GetBool()) {
if (time.GetASSFormated() != GetValue()) {
UpdateTime();
SetValue(time.GetASSFormated());
}
}
event.Skip();
}
///// Mouse/copy/paste events down here /////
/// @brief Mouse event
@ -315,9 +276,7 @@ void TimeEdit::OnMouseEvent(wxMouseEvent &event) {
}
/// @brief Menu Copy
/// @param event
///
void TimeEdit::OnCopy(wxCommandEvent &event) {
void TimeEdit::OnCopy(wxCommandEvent &) {
SetFocus();
SetSelection(0,GetValue().Length());
CopyTime();
@ -325,18 +284,14 @@ void TimeEdit::OnCopy(wxCommandEvent &event) {
}
/// @brief Menu Paste
/// @param event
///
void TimeEdit::OnPaste(wxCommandEvent &event) {
void TimeEdit::OnPaste(wxCommandEvent &) {
SetFocus();
PasteTime();
Refresh();
}
/// @brief Copy to clipboard
///
void TimeEdit::CopyTime() {
// Frame
if (byFrame) {
Copy();
return;
@ -350,9 +305,7 @@ void TimeEdit::CopyTime() {
}
/// @brief Paste from clipboard
///
void TimeEdit::PasteTime() {
// Frame
if (byFrame) {
Paste();
return;

View File

@ -52,17 +52,12 @@
///
class TimeEdit : public wxTextCtrl {
private:
/// DOCME
bool byFrame;
/// DOCME
bool ready;
/// DOCME
bool modified;
void Modified(bool byUser=true);
void UpdateText();
void CopyTime();
void PasteTime();
@ -70,20 +65,14 @@ private:
/// DOCME
void UpdateTime(bool byUser=true);
/// DOCME
/// DOCME
void OnModified(wxCommandEvent &event);
void OnMouseEvent(wxMouseEvent &event);
void OnKeyDown(wxKeyEvent &event);
void OnCopy(wxCommandEvent &event);
void OnPaste(wxCommandEvent &event);
void OnKillFocus(wxFocusEvent &event);
/// @brief DOCME
///
void Modified();
public:
/// DOCME
@ -94,34 +83,16 @@ public:
/// DOCME
/// DOCME
bool showModified;
TimeEdit(wxWindow* parent, wxWindowID id, const wxString& value = _T(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr);
void SetByFrame(bool enable);
void SetTime(int ms,bool setModified=false);
void SetTime(AssTime time);
void Update();
/// @brief DOCME
/// @return
///
bool HasBeenModified() { return modified; }
DECLARE_EVENT_TABLE()
};
///////
// IDs
enum {
/// DOCME
Time_Edit_Copy = 1320,
/// DOCME
Time_Edit_Paste
};

View File

@ -60,6 +60,7 @@
#include "ass_time.h"
#include "audio_display.h"
#include "compat.h"
#include "export_visible_lines.h"
#include "keyframe.h"
#include <libaegisub/access.h>
#include "main.h"
@ -98,6 +99,7 @@ VideoContext::VideoContext()
, arType(0)
, hasSubtitles(false)
, playAudioOnStep(OPT_GET("Audio/Plays When Stepping Video"))
, singleFrame(false)
, grid(NULL)
, audio(NULL)
, VFR_Input(videoFPS)
@ -245,8 +247,17 @@ void VideoContext::UpdateDisplays(bool full, bool seek) {
}
}
void VideoContext::Refresh () {
void VideoContext::Refresh(bool full) {
if (subsProvider.get()) {
if (full) {
AssLimitToVisibleFilter::SetFrame(-1);
singleFrame = false;
}
else {
AssLimitToVisibleFilter::SetFrame(frame_n);
singleFrame = true;
}
AssExporter exporter(grid->ass);
exporter.AddAutoFilters();
try {
@ -267,6 +278,10 @@ void VideoContext::JumpToFrame(int n) {
frame_n = n;
if (singleFrame) {
Refresh(true);
}
UpdateDisplays(false, true);
static agi::OptionValue* highlight = OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame");
@ -401,8 +416,8 @@ void VideoContext::PlayLine() {
// Set variables
isPlaying = true;
startFrame = FrameAtTime(curline->Start.GetMS(),agi::vfr::START);
endFrame = FrameAtTime(curline->End.GetMS(),agi::vfr::END);
startFrame = FrameAtTime(grid->GetActiveLine()->Start.GetMS(),agi::vfr::START);
endFrame = FrameAtTime(grid->GetActiveLine()->End.GetMS(),agi::vfr::END);
// Jump to start
playNextFrame = startFrame;

View File

@ -151,6 +151,8 @@ private:
agi::vfr::Framerate videoFPS;
agi::vfr::Framerate ovrFPS;
bool singleFrame;
public:
/// DOCME
SubtitlesGrid *grid;
@ -231,7 +233,9 @@ public:
void JumpToTime(int ms, agi::vfr::Time end = agi::vfr::START);
/// @brief Refresh the subtitle provider
void Refresh();
/// @param full Send the entire subtitle file to the renderer rather than
/// just the lines visible on the current frame
void Refresh(bool full = false);
/// @brief Update the video display
/// @param full Recalculate size and slider lengths

View File

@ -51,7 +51,6 @@
#include "ass_override.h"
#include "ass_style.h"
#include "ass_time.h"
#include "export_visible_lines.h"
#include "main.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
@ -155,8 +154,6 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
}
// end drag
else {
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
dragging = false;
// mouse didn't move, fiddle with selection
@ -197,8 +194,6 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
}
// end hold
else {
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
holding = false;
CommitHold();
Commit(true);
@ -234,7 +229,6 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
dragging = true;
parent->CaptureMouse();
if (realTime) AssLimitToVisibleFilter::SetFrame(frameNumber);
}
}
// start hold
@ -249,7 +243,6 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
if (curDiag && InitializeHold()) {
holding = true;
parent->CaptureMouse();
if (realTime) AssLimitToVisibleFilter::SetFrame(frameNumber);
}
}
}
@ -267,9 +260,7 @@ void VisualTool<FeatureType>::Commit(bool full, wxString message) {
}
grid->ass->Commit(message);
}
grid->CommitChanges(false,!full);
if (full)
grid->editBox->Update(false, true);
grid->CommitChanges(full);
externalChange = true;
}

View File

@ -47,6 +47,7 @@
#include "base_grid.h"
#include "gl_wrap.h"
#include "selection_controller.h"
class VideoDisplay;
class AssDialogue;

View File

@ -41,7 +41,6 @@
#include "ass_dialogue.h"
#include "ass_file.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_display.h"

View File

@ -37,7 +37,6 @@
#include "ass_file.h"
#include "gl_text.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "video_context.h"
#include "video_display.h"

View File

@ -38,7 +38,6 @@
#include "ass_dialogue.h"
#include "ass_file.h"
#include "libresrc/libresrc.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"

View File

@ -41,7 +41,6 @@
#include "ass_dialogue.h"
#include "ass_file.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"

View File

@ -41,7 +41,6 @@
#include "ass_dialogue.h"
#include "ass_file.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"

View File

@ -41,7 +41,6 @@
#include "ass_dialogue.h"
#include "ass_file.h"
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
#include "video_context.h"