mirror of https://github.com/odrling/Aegisub
Rewrite the subtitles edit control's syntax highlighting
Simplify and clean up the parsing code to better represent how VSFilter actually handles many odd edge cases as well as making it significantly faster. Use an enum for syntax style IDs rather than magic numbers. Add styles for comments, draw mode and karaoke templater variables rather than reusing other styles and move some hardcoded style information to the config file. Operate on the utf-8 representation of the edit box text rather than a wxString, as it's both faster and simpler. Originally committed to SVN as r5615.
This commit is contained in:
parent
67ab06e830
commit
a25c5c1909
|
@ -91,7 +91,7 @@ void Options::LoadConfig(std::istream& stream) {
|
||||||
LOG_E("option/load") << "json::Exception: " << e.what();
|
LOG_E("option/load") << "json::Exception: " << e.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigVisitor config_visitor(values, std::string(""));
|
ConfigVisitor config_visitor(values, "");
|
||||||
config_root.Accept(config_visitor);
|
config_root.Accept(config_visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,16 +136,42 @@
|
||||||
"Subtitle" : {
|
"Subtitle" : {
|
||||||
"Syntax" : {
|
"Syntax" : {
|
||||||
"Background" : {
|
"Background" : {
|
||||||
"Error" : "rgb(255, 200, 200)"
|
"Brackets" : "",
|
||||||
|
"Comment" : "",
|
||||||
|
"Drawing" : "",
|
||||||
|
"Error" : "rgb(255, 200, 200)",
|
||||||
|
"Karaoke Template" : "",
|
||||||
|
"Karaoke Variable" : "",
|
||||||
|
"Line Break" : "",
|
||||||
|
"Normal" : "",
|
||||||
|
"Parameters" : "",
|
||||||
|
"Slashes" : "",
|
||||||
|
"Tags" : ""
|
||||||
|
},
|
||||||
|
"Bold" : {
|
||||||
|
"Brackets" : false,
|
||||||
|
"Comment" : true,
|
||||||
|
"Drawing" : true,
|
||||||
|
"Error" : false,
|
||||||
|
"Karaoke Template" : true,
|
||||||
|
"Karaoke Variable" : true,
|
||||||
|
"Line Break" : true,
|
||||||
|
"Normal" : false,
|
||||||
|
"Parameters" : false,
|
||||||
|
"Slashes" : false,
|
||||||
|
"Tags" : true
|
||||||
},
|
},
|
||||||
"Brackets" : "rgb(20, 50, 255)",
|
"Brackets" : "rgb(20, 50, 255)",
|
||||||
|
"Comment" : "rgb(0,0,0)",
|
||||||
|
"Drawing" : "rgb(0,0,0)",
|
||||||
"Error" : "rgb(200, 0, 0)",
|
"Error" : "rgb(200, 0, 0)",
|
||||||
"Highlight Tags" : "rgb(90, 90, 90)",
|
|
||||||
"Karaoke Template" : "rgb(128, 0, 192)",
|
"Karaoke Template" : "rgb(128, 0, 192)",
|
||||||
|
"Karaoke Variable" : "rgb(128, 0, 192)",
|
||||||
"Line Break" : "rgb(160, 160, 160)",
|
"Line Break" : "rgb(160, 160, 160)",
|
||||||
"Normal" : "rgb(0,0,0)",
|
"Normal" : "rgb(0,0,0)",
|
||||||
"Parameters" : "rgb(40, 90, 40)",
|
"Parameters" : "rgb(40, 90, 40)",
|
||||||
"Slashes" : "rgb(255, 0, 200)"
|
"Slashes" : "rgb(255, 0, 200)",
|
||||||
|
"Tags" : "rgb(90, 90, 90)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Video Dummy" : {
|
"Video Dummy" : {
|
||||||
|
|
|
@ -75,18 +75,6 @@ enum {
|
||||||
EDIT_MENU_THES_LANGS
|
EDIT_MENU_THES_LANGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// @brief Edit box constructor
|
|
||||||
/// @param parent
|
|
||||||
/// @param id
|
|
||||||
/// @param value
|
|
||||||
/// @param pos
|
|
||||||
/// @param wsize
|
|
||||||
/// @param style
|
|
||||||
/// @param validator
|
|
||||||
/// @param name
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, SubtitlesGrid *grid)
|
SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, SubtitlesGrid *grid)
|
||||||
: ScintillaTextCtrl(parent, wxID_ANY)
|
: ScintillaTextCtrl(parent, wxID_ANY)
|
||||||
, spellchecker(SpellCheckerFactory::GetSpellChecker())
|
, spellchecker(SpellCheckerFactory::GetSpellChecker())
|
||||||
|
@ -186,17 +174,19 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, S
|
||||||
|
|
||||||
OPT_SUB("Subtitle/Edit Box/Font Face", &SubsTextEditCtrl::SetStyles, this);
|
OPT_SUB("Subtitle/Edit Box/Font Face", &SubsTextEditCtrl::SetStyles, this);
|
||||||
OPT_SUB("Subtitle/Edit Box/Font Size", &SubsTextEditCtrl::SetStyles, this);
|
OPT_SUB("Subtitle/Edit Box/Font Size", &SubsTextEditCtrl::SetStyles, this);
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Normal", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Normal");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Brackets", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Comment");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Slashes", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Drawing");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Highlight Tags", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Brackets");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Error", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Slashes");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Background/Error", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Tags");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Parameters", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Error");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Line Break", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Parameters");
|
||||||
OPT_SUB("Colour/Subtitle/Syntax/Karaoke Template", &SubsTextEditCtrl::SetStyles, this);
|
Subscribe("Line Break");
|
||||||
|
Subscribe("Karaoke Template");
|
||||||
|
Subscribe("Karaoke Variable");
|
||||||
|
|
||||||
OPT_SUB("Subtitle/Highlight/Syntax", &SubsTextEditCtrl::UpdateStyle, this, 0, -1);
|
OPT_SUB("Subtitle/Highlight/Syntax", &SubsTextEditCtrl::UpdateStyle, this);
|
||||||
static wxStyledTextEvent evt;
|
static wxStyledTextEvent evt;
|
||||||
OPT_SUB("App/Call Tips", &SubsTextEditCtrl::UpdateCallTip, this, ref(evt));
|
OPT_SUB("App/Call Tips", &SubsTextEditCtrl::UpdateCallTip, this, ref(evt));
|
||||||
}
|
}
|
||||||
|
@ -205,6 +195,12 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, S
|
||||||
SubsTextEditCtrl::~SubsTextEditCtrl() {
|
SubsTextEditCtrl::~SubsTextEditCtrl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubsTextEditCtrl::Subscribe(std::string const& name) {
|
||||||
|
OPT_SUB("Colour/Subtitle/Syntax/" + name, &SubsTextEditCtrl::SetStyles, this);
|
||||||
|
OPT_SUB("Colour/Subtitle/Syntax/Background/" + name, &SubsTextEditCtrl::SetStyles, this);
|
||||||
|
OPT_SUB("Colour/Subtitle/Syntax/Bold/" + name, &SubsTextEditCtrl::SetStyles, this);
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(SubsTextEditCtrl,wxStyledTextCtrl)
|
BEGIN_EVENT_TABLE(SubsTextEditCtrl,wxStyledTextCtrl)
|
||||||
EVT_KILL_FOCUS(SubsTextEditCtrl::OnLoseFocus)
|
EVT_KILL_FOCUS(SubsTextEditCtrl::OnLoseFocus)
|
||||||
|
|
||||||
|
@ -222,279 +218,207 @@ void SubsTextEditCtrl::OnLoseFocus(wxFocusEvent &event) {
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STYLE_NORMAL = 0,
|
||||||
|
STYLE_COMMENT,
|
||||||
|
STYLE_DRAWING,
|
||||||
|
STYLE_OVERRIDE,
|
||||||
|
STYLE_PUNCTUATION,
|
||||||
|
STYLE_TAG,
|
||||||
|
STYLE_ERROR,
|
||||||
|
STYLE_PARAMETER,
|
||||||
|
STYLE_LINE_BREAK,
|
||||||
|
STYLE_KARAOKE_TEMPLATE,
|
||||||
|
STYLE_KARAOKE_VARIABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
void SubsTextEditCtrl::SetStyle(int id, wxFont &font, std::string const& name) {
|
||||||
|
StyleSetFont(id, font);
|
||||||
|
StyleSetBold(id, OPT_GET("Colour/Subtitle/Syntax/Bold/" + name)->GetBool());
|
||||||
|
StyleSetForeground(id, lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/" + name)->GetColour()));
|
||||||
|
const agi::OptionValue *background = OPT_GET("Colour/Subtitle/Syntax/Background/" + name);
|
||||||
|
if (background->GetType() == agi::OptionValue::Type_Colour)
|
||||||
|
StyleSetBackground(id, lagi_wxColour(background->GetColour()));
|
||||||
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::SetStyles() {
|
void SubsTextEditCtrl::SetStyles() {
|
||||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
font.SetEncoding(wxFONTENCODING_DEFAULT); // this solves problems with some fonts not working properly
|
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());
|
wxString fontname = lagi_wxString(OPT_GET("Subtitle/Edit Box/Font Face")->GetString());
|
||||||
if (!fontname.empty()) font.SetFaceName(fontname);
|
if (!fontname.empty()) font.SetFaceName(fontname);
|
||||||
int size = OPT_GET("Subtitle/Edit Box/Font Size")->GetInt();
|
font.SetPointSize(OPT_GET("Subtitle/Edit Box/Font Size")->GetInt());
|
||||||
|
|
||||||
// Normal style
|
SetStyle(STYLE_NORMAL, font, "Normal");
|
||||||
StyleSetFont(0,font);
|
SetStyle(STYLE_COMMENT, font, "Comment");
|
||||||
StyleSetSize(0,size);
|
SetStyle(STYLE_DRAWING, font, "Drawing");
|
||||||
StyleSetForeground(0,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Normal")->GetColour()));
|
SetStyle(STYLE_OVERRIDE, font, "Brackets");
|
||||||
|
SetStyle(STYLE_PUNCTUATION, font, "Slashes");
|
||||||
// Brackets style
|
SetStyle(STYLE_TAG, font, "Tags");
|
||||||
StyleSetFont(1,font);
|
SetStyle(STYLE_ERROR, font, "Error");
|
||||||
StyleSetSize(1,size);
|
SetStyle(STYLE_PARAMETER, font, "Parameters");
|
||||||
StyleSetForeground(1,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Brackets")->GetColour()));
|
SetStyle(STYLE_LINE_BREAK, font, "Line Break");
|
||||||
|
SetStyle(STYLE_KARAOKE_TEMPLATE, font, "Karaoke Template");
|
||||||
// Slashes/Parenthesis/Comma style
|
SetStyle(STYLE_KARAOKE_VARIABLE, font, "Karaoke Variable");
|
||||||
StyleSetFont(2,font);
|
|
||||||
StyleSetSize(2,size);
|
|
||||||
StyleSetForeground(2,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Slashes")->GetColour()));
|
|
||||||
|
|
||||||
// Tags style
|
|
||||||
StyleSetFont(3,font);
|
|
||||||
StyleSetSize(3,size);
|
|
||||||
StyleSetBold(3,true);
|
|
||||||
StyleSetForeground(3,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Highlight Tags")->GetColour()));
|
|
||||||
|
|
||||||
// Error style
|
|
||||||
StyleSetFont(4,font);
|
|
||||||
StyleSetSize(4,size);
|
|
||||||
StyleSetForeground(4,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Error")->GetColour()));
|
|
||||||
StyleSetBackground(4,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Background/Error")->GetColour()));
|
|
||||||
|
|
||||||
// Tag Parameters style
|
|
||||||
StyleSetFont(5,font);
|
|
||||||
StyleSetSize(5,size);
|
|
||||||
StyleSetForeground(5,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Parameters")->GetColour()));
|
|
||||||
|
|
||||||
// Line breaks style
|
|
||||||
StyleSetFont(6,font);
|
|
||||||
StyleSetSize(6,size);
|
|
||||||
StyleSetBold(6,true);
|
|
||||||
StyleSetForeground(6,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Line Break")->GetColour()));
|
|
||||||
|
|
||||||
// Karaoke template code block style
|
|
||||||
StyleSetFont(7,font);
|
|
||||||
StyleSetSize(7,size);
|
|
||||||
StyleSetBold(7,true);
|
|
||||||
//StyleSetItalic(7,true);
|
|
||||||
StyleSetForeground(7,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Karaoke Template")->GetColour()));
|
|
||||||
|
|
||||||
// Misspelling indicator
|
// Misspelling indicator
|
||||||
IndicatorSetStyle(0,wxSTC_INDIC_SQUIGGLE);
|
IndicatorSetStyle(0,wxSTC_INDIC_SQUIGGLE);
|
||||||
IndicatorSetForeground(0,wxColour(255,0,0));
|
IndicatorSetForeground(0,wxColour(255,0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
|
void SubsTextEditCtrl::UpdateStyle() {
|
||||||
StartUnicodeStyling(0,255);
|
StartStyling(0,255);
|
||||||
|
|
||||||
|
std::string text = STD_STR(GetText());
|
||||||
|
|
||||||
if (!OPT_GET("Subtitle/Highlight/Syntax")->GetBool()) {
|
if (!OPT_GET("Subtitle/Highlight/Syntax")->GetBool()) {
|
||||||
SetUnicodeStyling(start, _length, 0);
|
SetStyling(text.size(), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (text.empty()) return;
|
||||||
|
|
||||||
// Check if it's a template line
|
// Check if it's a template line
|
||||||
AssDialogue *diag = grid->GetActiveLine();
|
AssDialogue *diag = grid->GetActiveLine();
|
||||||
bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith("template");
|
bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith("template");
|
||||||
//bool templateCodeLine = diag && diag->Comment && diag->Effect.Lower().StartsWith("code");
|
|
||||||
|
|
||||||
// Template code lines get Lua highlighting instead of ASS highlighting
|
bool in_parens = false;
|
||||||
// This is broken and needs some extra work
|
bool in_unparened_arg = false;
|
||||||
/*if (templateCodeLine) {
|
bool in_draw_mode = false;
|
||||||
SetLexer(wxSTC_LEX_LUA);
|
bool in_ovr = false;
|
||||||
Colourise(start, start+_length);
|
bool in_karaoke_template = false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetLexer(wxSTC_LEX_CONTAINER);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Set variables
|
int range_len = 0;
|
||||||
wxString text = GetText();
|
int style = STYLE_NORMAL;
|
||||||
int end = start + _length;
|
|
||||||
if (_length < 0) end = text.Length();
|
|
||||||
|
|
||||||
// Flags
|
char cur_char = 0;
|
||||||
bool numMode = false; // everything is considered a number/parameter until this is unset
|
char next_char = text[0];
|
||||||
bool drawingMode = false; // for \p1 -> \p0 stuff
|
|
||||||
|
|
||||||
// Begin styling
|
size_t eat_chars = 0;
|
||||||
int ran = 0; // length of current range
|
|
||||||
int depth = 0; // brace nesting depth
|
|
||||||
int curStyle = 0; // style to apply to current range
|
|
||||||
int curPos = 0; // start of current range?
|
|
||||||
wxChar curChar = 0;
|
|
||||||
wxChar prevChar = 0;
|
|
||||||
wxChar nextChar = 0;
|
|
||||||
|
|
||||||
// Loop through
|
for (size_t i = 0; i < text.size(); ++i) {
|
||||||
for (int i=start;i<end;i++) {
|
|
||||||
// Current/previous characters
|
// Current/previous characters
|
||||||
prevChar = curChar;
|
char prev_char = cur_char;
|
||||||
curChar = text[i];
|
cur_char = next_char;
|
||||||
if (i<end-1) nextChar = text[i+1];
|
next_char = i + 1 < text.size() ? text[i + 1] : 0;
|
||||||
else nextChar = 0;
|
|
||||||
|
|
||||||
// Erroneous
|
if (eat_chars > 0) {
|
||||||
if (depth < 0 || depth > 1) {
|
++range_len;
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
--eat_chars;
|
||||||
curPos += ran;
|
continue;
|
||||||
ran = 0;
|
|
||||||
curStyle = 4;
|
|
||||||
numMode = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int new_style = style;
|
||||||
|
|
||||||
// Start override block
|
// Start override block
|
||||||
if (curChar == '{' && depth >= 0) {
|
if (cur_char == '{') {
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
new_style = in_ovr ? STYLE_ERROR : STYLE_OVERRIDE;
|
||||||
curPos += ran;
|
in_ovr = true;
|
||||||
ran = 0;
|
in_parens = false;
|
||||||
depth++;
|
|
||||||
if (depth == 1) curStyle = 1;
|
|
||||||
else curStyle = 4;
|
|
||||||
numMode = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// End override block
|
// End override block
|
||||||
else if (curChar == '}' && depth <= 1) {
|
else if (cur_char == '}') {
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
new_style = in_ovr ? STYLE_OVERRIDE : STYLE_ERROR;
|
||||||
curPos += ran;
|
in_ovr = false;
|
||||||
ran = 0;
|
|
||||||
depth--;
|
|
||||||
if (depth == 0) curStyle = 1;
|
|
||||||
else curStyle = 4;
|
|
||||||
numMode = false;
|
|
||||||
}
|
}
|
||||||
|
// Start karaoke template
|
||||||
// Karaoke template block
|
else if (templateLine && style != STYLE_KARAOKE_TEMPLATE && cur_char == '!') {
|
||||||
else if (templateLine && curChar == '!') {
|
new_style = STYLE_KARAOKE_TEMPLATE;
|
||||||
// Apply previous style
|
in_karaoke_template = true;
|
||||||
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] != '!')
|
|
||||||
endPos++;
|
|
||||||
SetUnicodeStyling(curPos,endPos-curPos+1,7);
|
|
||||||
curPos = endPos+1;
|
|
||||||
i = endPos+0;
|
|
||||||
}
|
}
|
||||||
// Karaoke template variable
|
// End karaoke template
|
||||||
else if (templateLine && curChar == '$') {
|
else if (style == STYLE_KARAOKE_TEMPLATE && cur_char == '!') {
|
||||||
// Apply previous style
|
in_karaoke_template = false;
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
|
||||||
curPos += ran;
|
|
||||||
ran = -1; // such that ran++ later on resets it to 0 !
|
|
||||||
// Eat entire variable
|
|
||||||
int endPos = i+1;
|
|
||||||
while (endPos < end) {
|
|
||||||
wxChar ch = text[endPos];
|
|
||||||
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_')
|
|
||||||
endPos++;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
SetUnicodeStyling(curPos,endPos-curPos,7);
|
// Continue karaoke template
|
||||||
curPos = endPos;
|
else if (in_karaoke_template) {
|
||||||
i = curPos-1;
|
// Do nothing and just continue the karaoke template style
|
||||||
}
|
}
|
||||||
|
// Start karaoke template variable
|
||||||
// Outside
|
else if (templateLine && style != STYLE_KARAOKE_TEMPLATE && cur_char == '$') {
|
||||||
else if (depth == 0) {
|
new_style = STYLE_KARAOKE_VARIABLE;
|
||||||
// Reset number mode
|
}
|
||||||
numMode = false;
|
// Continue karaoke template variable
|
||||||
|
else if (style == STYLE_KARAOKE_VARIABLE && ((cur_char >= 'A' && cur_char <= 'Z') || (cur_char >= 'a' && cur_char <= 'z') || cur_char == '_')) {
|
||||||
|
// Do nothing and just continue the karaoke variable style
|
||||||
|
}
|
||||||
|
// Plain text
|
||||||
|
else if (!in_ovr) {
|
||||||
// Is \n, \N or \h?
|
// Is \n, \N or \h?
|
||||||
if (curChar == '\\' && (nextChar == 'n' || nextChar == 'N' || nextChar == 'h')) {
|
if (cur_char == '\\' && (next_char == 'n' || next_char == 'N' || next_char == 'h')) {
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
new_style = STYLE_LINE_BREAK;
|
||||||
curPos += ran;
|
eat_chars = 1;
|
||||||
ran = 1;
|
|
||||||
curStyle = 6;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
else if (in_draw_mode)
|
||||||
// Normal text
|
new_style = STYLE_DRAWING;
|
||||||
else if (curStyle != 0) {
|
else
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
new_style = STYLE_NORMAL;
|
||||||
curPos += ran;
|
|
||||||
ran = 0;
|
|
||||||
if (drawingMode) curStyle = 6;
|
|
||||||
else curStyle = 0;
|
|
||||||
}
|
}
|
||||||
}
|
// Inside override tag
|
||||||
|
|
||||||
// Inside
|
|
||||||
else if (depth == 1) {
|
|
||||||
// Special character
|
|
||||||
if (curChar == '\\' || curChar == '(' || curChar == ')' || curChar == ',') {
|
|
||||||
if (curStyle != 2) {
|
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
|
||||||
curPos += ran;
|
|
||||||
ran = 0;
|
|
||||||
curStyle = 2;
|
|
||||||
numMode = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// Number
|
// Special character
|
||||||
if (prevChar != '\\' && (numMode || (curChar >= '0' && curChar <= '9') || curChar == '.' || curChar == '&' || curChar == '+' || curChar == '-' || (curChar == 'H' && prevChar == '&'))) {
|
if (cur_char == '\\' || cur_char == '(' || cur_char == ')' || cur_char == ',') {
|
||||||
if (curStyle != 5) {
|
new_style = STYLE_PUNCTUATION;
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
in_unparened_arg = false;
|
||||||
curPos += ran;
|
|
||||||
ran = 0;
|
if (style == STYLE_TAG && cur_char == '(')
|
||||||
curStyle = 5;
|
in_parens = true;
|
||||||
numMode = true;
|
// This is technically wrong for nested tags, but it doesn't
|
||||||
|
// matter as \t doesn't have any arguments after the subtag(s)
|
||||||
|
else if (cur_char == ')')
|
||||||
|
in_parens = false;
|
||||||
}
|
}
|
||||||
|
// Beginning of a tag
|
||||||
|
else if (prev_char == '\\') {
|
||||||
|
new_style = STYLE_TAG;
|
||||||
|
// \r and \fn are special as their argument is an
|
||||||
|
// unparenthesized string
|
||||||
|
if (cur_char == 'r')
|
||||||
|
in_unparened_arg = true;
|
||||||
|
else if (cur_char == 'f' && next_char == 'n') {
|
||||||
|
eat_chars = 1;
|
||||||
|
in_unparened_arg = true;
|
||||||
}
|
}
|
||||||
|
// For \p we need to check if it's entering or leaving draw mode
|
||||||
// Tag name
|
// Luckily draw mode can't be set in the style, so no argument
|
||||||
else if (curStyle != 3) {
|
// always means leave draw mode
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
else if (cur_char == 'p' && (next_char < 'a' || next_char > 'z')) {
|
||||||
curPos += ran;
|
in_draw_mode = false;
|
||||||
ran = 0;
|
for (size_t idx = i + 1; idx < text.size(); ++idx) {
|
||||||
curStyle = 3;
|
char c = text[idx];
|
||||||
|
// I have no idea why one would use leading zeros for
|
||||||
// Set parameter if it's \fn or \r
|
// the scale, but vsfilter allows it
|
||||||
int tagLen = 0;
|
if (c >= '1' && c <= '9')
|
||||||
if (text.Mid(curPos,2) == "fn") tagLen = 2;
|
in_draw_mode = true;
|
||||||
else if (text.Mid(curPos,1) == "r") tagLen = 1;
|
else if (c != '0')
|
||||||
if (tagLen) {
|
|
||||||
numMode = true;
|
|
||||||
ran = tagLen-1;
|
|
||||||
i+=ran;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set drawing mode if it's \p
|
|
||||||
if (text.Mid(curPos,1) == "p") {
|
|
||||||
if (curPos+2 < (signed) text.Length()) {
|
|
||||||
// Disable
|
|
||||||
wxChar nextNext = text[curPos+2];
|
|
||||||
if ((nextNext == '\\' || nextNext == '}') && nextChar == '0') drawingMode = false;
|
|
||||||
|
|
||||||
// Enable
|
|
||||||
if (nextChar >= '1' && nextChar <= '9') {
|
|
||||||
for(int testPos = curPos+2;testPos < (signed) text.Length();testPos++) {
|
|
||||||
nextNext = text[testPos];
|
|
||||||
if (nextNext == '\\' || nextNext == '}') {
|
|
||||||
drawingMode = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nextNext < '0' || nextNext > '9') break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// All tags start with letters or numbers
|
||||||
|
else if (cur_char < '0' || (cur_char > '9' && cur_char < 'A') || (cur_char > 'Z' && cur_char < 'a') || cur_char > 'z')
|
||||||
|
new_style = STYLE_ERROR;
|
||||||
}
|
}
|
||||||
|
else if ((in_parens && style != STYLE_TAG) || in_unparened_arg || (style == STYLE_TAG && ((cur_char < 'A' || cur_char > 'z') || (cur_char > 'Z' && cur_char < 'a')))) {
|
||||||
|
new_style = STYLE_PARAMETER;
|
||||||
}
|
}
|
||||||
|
else if (style != STYLE_TAG && style != STYLE_PARAMETER) {
|
||||||
|
new_style = STYLE_COMMENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase ran length
|
if (new_style != style) {
|
||||||
ran++;
|
SetStyling(range_len, style);
|
||||||
|
style = new_style;
|
||||||
|
range_len = 0;
|
||||||
}
|
}
|
||||||
SetUnicodeStyling(curPos,ran,curStyle);
|
|
||||||
StyleSpellCheck(start,_length);
|
++range_len;
|
||||||
|
}
|
||||||
|
SetStyling(range_len, style);
|
||||||
|
StyleSpellCheck();
|
||||||
wxStyledTextEvent evt;
|
wxStyledTextEvent evt;
|
||||||
UpdateCallTip(evt);
|
UpdateCallTip(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Update call tip
|
/// @brief Update call tip
|
||||||
void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
|
void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
|
||||||
if (!OPT_GET("App/Call Tips")->GetBool()) return;
|
if (!OPT_GET("App/Call Tips")->GetBool()) return;
|
||||||
|
@ -709,13 +633,13 @@ void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
|
||||||
CallTipSetHighlight(highStart,highEnd);
|
CallTipSetHighlight(highStart,highEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::StyleSpellCheck(int start, int len) {
|
void SubsTextEditCtrl::StyleSpellCheck() {
|
||||||
if (!spellchecker.get()) return;
|
if (!spellchecker.get()) return;
|
||||||
|
|
||||||
// Results
|
// Results
|
||||||
wxString text = GetText();
|
wxString text = GetText();
|
||||||
IntPairVector results;
|
IntPairVector results;
|
||||||
GetWordBoundaries(text,results,start,(len == -1) ? len : start+len);
|
GetWordBoundaries(text,results);
|
||||||
|
|
||||||
// Style
|
// Style
|
||||||
int count = results.size();
|
int count = results.size();
|
||||||
|
@ -727,11 +651,7 @@ void SubsTextEditCtrl::StyleSpellCheck(int start, int len) {
|
||||||
|
|
||||||
// Check if it's valid
|
// Check if it's valid
|
||||||
if (!spellchecker->CheckWord(curWord)) {
|
if (!spellchecker->CheckWord(curWord)) {
|
||||||
// Get length before it
|
StartUnicodeStyling(s,32);
|
||||||
int utf8len = GetUnicodePosition(s);
|
|
||||||
|
|
||||||
// Set styling
|
|
||||||
StartStyling(utf8len,32);
|
|
||||||
SetUnicodeStyling(s,e-s,32);
|
SetUnicodeStyling(s,e-s,32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,7 +672,6 @@ void SubsTextEditCtrl::SetTextTo(wxString text) {
|
||||||
|
|
||||||
int from=0,to=0;
|
int from=0,to=0;
|
||||||
GetSelection(&from,&to);
|
GetSelection(&from,&to);
|
||||||
Clear();
|
|
||||||
|
|
||||||
SetText(text);
|
SetText(text);
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
|
@ -999,10 +918,10 @@ void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
|
||||||
|
|
||||||
// Set dictionary
|
// Set dictionary
|
||||||
int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1;
|
int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1;
|
||||||
wxString lang;
|
if (index >= 0) {
|
||||||
if (index >= 0) lang = langs[index];
|
spellchecker->SetLanguage(langs[index]);
|
||||||
spellchecker->SetLanguage(lang);
|
OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(langs[index]));
|
||||||
OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(lang));
|
}
|
||||||
|
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
}
|
}
|
||||||
|
@ -1012,10 +931,10 @@ void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
|
||||||
|
|
||||||
// Set language
|
// Set language
|
||||||
int index = event.GetId() - EDIT_MENU_THES_LANGS - 1;
|
int index = event.GetId() - EDIT_MENU_THES_LANGS - 1;
|
||||||
wxString lang;
|
if (index >= 0) {
|
||||||
if (index >= 0) lang = langs[index];
|
thesaurus->SetLanguage(langs[index]);
|
||||||
thesaurus->SetLanguage(lang);
|
OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(langs[index]));
|
||||||
OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(lang));
|
}
|
||||||
|
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,15 +88,19 @@ class SubsTextEditCtrl : public ScintillaTextCtrl {
|
||||||
void OnSetThesLanguage(wxCommandEvent &event);
|
void OnSetThesLanguage(wxCommandEvent &event);
|
||||||
void OnLoseFocus(wxFocusEvent &event);
|
void OnLoseFocus(wxFocusEvent &event);
|
||||||
|
|
||||||
|
void SetStyle(int id, wxFont &font, std::string const& name);
|
||||||
|
void Subscribe(std::string const& name);
|
||||||
|
|
||||||
|
void StyleSpellCheck();
|
||||||
|
void UpdateCallTip(wxStyledTextEvent &);
|
||||||
|
void SetStyles();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubsTextEditCtrl(wxWindow* parent, wxSize size, long style, SubtitlesGrid *grid);
|
SubsTextEditCtrl(wxWindow* parent, wxSize size, long style, SubtitlesGrid *grid);
|
||||||
~SubsTextEditCtrl();
|
~SubsTextEditCtrl();
|
||||||
|
|
||||||
void SetTextTo(wxString text);
|
void SetTextTo(wxString text);
|
||||||
void UpdateStyle(int start=0,int length=-1);
|
void UpdateStyle();
|
||||||
void StyleSpellCheck(int start=0,int length=-1);
|
|
||||||
void UpdateCallTip(wxStyledTextEvent &);
|
|
||||||
void SetStyles();
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue