2006-12-24 22:52:54 +01:00
|
|
|
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
2006-12-24 22:52:54 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// $Id$
|
|
|
|
|
|
|
|
/// @file subs_edit_ctrl.cpp
|
|
|
|
/// @brief Main subtitle editing text control
|
|
|
|
/// @ingroup main_ui
|
|
|
|
///
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2009-09-10 15:06:40 +02:00
|
|
|
#ifndef AGI_PRE
|
2010-07-20 05:11:11 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <functional>
|
|
|
|
#else
|
|
|
|
#include <tr1/functional>
|
|
|
|
#endif
|
2007-01-01 05:53:55 +01:00
|
|
|
#include <wx/intl.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ass_dialogue.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "compat.h"
|
|
|
|
#include "main.h"
|
2010-08-02 08:31:38 +02:00
|
|
|
#include "include/aegisub/spellchecker.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "subs_edit_box.h"
|
2010-07-20 05:11:11 +02:00
|
|
|
#include "subs_edit_ctrl.h"
|
2006-12-25 06:43:00 +01:00
|
|
|
#include "subs_grid.h"
|
2010-07-20 05:11:11 +02:00
|
|
|
#include "thesaurus.h"
|
2006-12-25 06:43:00 +01:00
|
|
|
#include "utils.h"
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
/// 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
|
|
|
|
};
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
|
|
|
/// @brief Edit box constructor
|
|
|
|
/// @param parent
|
|
|
|
/// @param id
|
|
|
|
/// @param value
|
|
|
|
/// @param pos
|
|
|
|
/// @param wsize
|
|
|
|
/// @param style
|
|
|
|
/// @param validator
|
|
|
|
/// @param name
|
|
|
|
/// @return
|
|
|
|
///
|
2010-07-20 05:11:11 +02:00
|
|
|
SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, SubtitlesGrid *grid)
|
|
|
|
: ScintillaTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wsize, style)
|
2010-08-02 08:31:38 +02:00
|
|
|
, spellchecker(SpellCheckerFactory::GetSpellChecker())
|
2010-07-20 05:11:11 +02:00
|
|
|
, thesaurus(Thesaurus::GetThesaurus())
|
|
|
|
, grid(grid)
|
2006-12-24 22:52:54 +01:00
|
|
|
{
|
|
|
|
// Set properties
|
2007-04-22 01:16:38 +02:00
|
|
|
SetWrapMode(wxSTC_WRAP_WORD);
|
2006-12-24 22:52:54 +01:00
|
|
|
SetMarginWidth(1,0);
|
2006-12-25 22:56:56 +01:00
|
|
|
UsePopUp(false);
|
2007-01-03 22:49:13 +01:00
|
|
|
SetStyles();
|
2006-12-25 04:42:44 +01:00
|
|
|
|
|
|
|
// Set hotkeys
|
2007-04-22 01:16:38 +02:00
|
|
|
CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_SCMOD_CTRL);
|
|
|
|
CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_SCMOD_NORM);
|
|
|
|
CmdKeyClear(wxSTC_KEY_TAB,wxSTC_SCMOD_NORM);
|
|
|
|
CmdKeyClear(wxSTC_KEY_TAB,wxSTC_SCMOD_SHIFT);
|
|
|
|
CmdKeyClear('D',wxSTC_SCMOD_CTRL);
|
|
|
|
CmdKeyClear('L',wxSTC_SCMOD_CTRL);
|
|
|
|
CmdKeyClear('L',wxSTC_SCMOD_CTRL | wxSTC_SCMOD_SHIFT);
|
|
|
|
CmdKeyClear('T',wxSTC_SCMOD_CTRL);
|
|
|
|
CmdKeyClear('T',wxSTC_SCMOD_CTRL | wxSTC_SCMOD_SHIFT);
|
|
|
|
CmdKeyClear('U',wxSTC_SCMOD_CTRL);
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2007-01-02 19:09:56 +01:00
|
|
|
// Prototypes for call tips
|
2007-01-02 19:15:17 +01:00
|
|
|
tipProtoN = -1;
|
2010-07-20 05:11:11 +02:00
|
|
|
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);
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
SubsTextEditCtrl::~SubsTextEditCtrl() {
|
|
|
|
}
|
|
|
|
|
2007-04-22 01:16:38 +02:00
|
|
|
BEGIN_EVENT_TABLE(SubsTextEditCtrl,wxStyledTextCtrl)
|
2007-01-02 06:00:55 +01:00
|
|
|
EVT_MOUSE_EVENTS(SubsTextEditCtrl::OnMouseEvent)
|
2007-01-14 00:34:04 +01:00
|
|
|
EVT_KILL_FOCUS(SubsTextEditCtrl::OnLoseFocus)
|
2007-01-02 06:00:55 +01:00
|
|
|
|
|
|
|
EVT_MENU(EDIT_MENU_SPLIT_PRESERVE,SubsTextEditCtrl::OnSplitLinePreserve)
|
|
|
|
EVT_MENU(EDIT_MENU_SPLIT_ESTIMATE,SubsTextEditCtrl::OnSplitLineEstimate)
|
|
|
|
EVT_MENU(EDIT_MENU_ADD_TO_DICT,SubsTextEditCtrl::OnAddToDictionary)
|
|
|
|
EVT_MENU_RANGE(EDIT_MENU_SUGGESTIONS,EDIT_MENU_THESAURUS-1,SubsTextEditCtrl::OnUseSuggestion)
|
2010-07-20 05:11:11 +02:00
|
|
|
EVT_MENU_RANGE(EDIT_MENU_THESAURUS_SUGS,EDIT_MENU_DIC_LANGUAGE-1,SubsTextEditCtrl::OnUseSuggestion)
|
2007-01-02 06:00:55 +01:00
|
|
|
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()
|
|
|
|
|
2007-01-14 00:34:04 +01:00
|
|
|
void SubsTextEditCtrl::OnLoseFocus(wxFocusEvent &event) {
|
|
|
|
CallTipCancel();
|
|
|
|
event.Skip();
|
|
|
|
}
|
|
|
|
|
2007-01-03 22:49:13 +01:00
|
|
|
void SubsTextEditCtrl::SetStyles() {
|
|
|
|
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
2009-12-27 20:49:27 +01:00
|
|
|
font.SetEncoding(wxFONTENCODING_DEFAULT); // this solves problems with some fonts not working properly
|
2010-05-21 03:13:36 +02:00
|
|
|
wxString fontname = lagi_wxString(OPT_GET("Subtitle/Edit Box/Font Face")->GetString());
|
2010-07-20 05:11:11 +02:00
|
|
|
if (!fontname.empty()) font.SetFaceName(fontname);
|
2010-05-21 03:13:36 +02:00
|
|
|
int size = OPT_GET("Subtitle/Edit Box/Font Size")->GetInt();
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Normal style
|
|
|
|
StyleSetFont(0,font);
|
|
|
|
StyleSetSize(0,size);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(0,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Normal")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Brackets style
|
|
|
|
StyleSetFont(1,font);
|
|
|
|
StyleSetSize(1,size);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(1,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Brackets")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Slashes/Parenthesis/Comma style
|
|
|
|
StyleSetFont(2,font);
|
|
|
|
StyleSetSize(2,size);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(2,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Slashes")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Tags style
|
|
|
|
StyleSetFont(3,font);
|
|
|
|
StyleSetSize(3,size);
|
|
|
|
StyleSetBold(3,true);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(3,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Highlight Tags")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Error style
|
|
|
|
StyleSetFont(4,font);
|
|
|
|
StyleSetSize(4,size);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(4,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Error")->GetColour()));
|
|
|
|
StyleSetBackground(4,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Background/Error")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Tag Parameters style
|
|
|
|
StyleSetFont(5,font);
|
|
|
|
StyleSetSize(5,size);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(5,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Parameters")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
|
|
|
// Line breaks style
|
|
|
|
StyleSetFont(6,font);
|
|
|
|
StyleSetSize(6,size);
|
|
|
|
StyleSetBold(6,true);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(6,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Line Break")->GetColour()));
|
2007-01-03 22:49:13 +01:00
|
|
|
|
2007-08-06 16:29:43 +02:00
|
|
|
// Karaoke template code block style
|
|
|
|
StyleSetFont(7,font);
|
|
|
|
StyleSetSize(7,size);
|
|
|
|
StyleSetBold(7,true);
|
|
|
|
//StyleSetItalic(7,true);
|
2010-05-21 03:13:36 +02:00
|
|
|
StyleSetForeground(7,lagi_wxColour(OPT_GET("Colour/Subtitle/Syntax/Karaoke Template")->GetColour()));
|
2007-08-06 16:29:43 +02:00
|
|
|
|
2007-01-03 22:49:13 +01:00
|
|
|
// Misspelling indicator
|
2007-04-22 01:16:38 +02:00
|
|
|
IndicatorSetStyle(0,wxSTC_INDIC_SQUIGGLE);
|
2007-01-03 22:49:13 +01:00
|
|
|
IndicatorSetForeground(0,wxColour(255,0,0));
|
|
|
|
}
|
|
|
|
|
2006-12-24 22:52:54 +01:00
|
|
|
void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
|
2010-05-21 03:13:36 +02:00
|
|
|
if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return;
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2007-08-29 00:52:23 +02:00
|
|
|
// Check if it's a template line
|
2010-07-20 05:11:11 +02:00
|
|
|
AssDialogue *diag = grid->GetActiveLine();
|
2007-08-29 00:52:23 +02:00
|
|
|
bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("template"));
|
2007-09-12 01:22:26 +02:00
|
|
|
//bool templateCodeLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("code"));
|
2007-08-29 00:52:23 +02:00
|
|
|
|
|
|
|
// Template code lines get Lua highlighting instead of ASS highlighting
|
|
|
|
// This is broken and needs some extra work
|
|
|
|
/*if (templateCodeLine) {
|
|
|
|
SetLexer(wxSTC_LEX_LUA);
|
|
|
|
Colourise(start, start+_length);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
SetLexer(wxSTC_LEX_CONTAINER);
|
2007-08-29 00:54:25 +02:00
|
|
|
}*/
|
2007-08-29 00:52:23 +02:00
|
|
|
|
2006-12-24 22:52:54 +01:00
|
|
|
// Set variables
|
|
|
|
wxString text = GetText();
|
2006-12-24 23:46:20 +01:00
|
|
|
int end = start + _length;
|
|
|
|
if (_length < 0) end = text.Length();
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2007-01-02 03:33:42 +01:00
|
|
|
// Flags
|
|
|
|
bool numMode = false; // everything is considered a number/parameter until this is unset
|
|
|
|
bool drawingMode = false; // for \p1 -> \p0 stuff
|
|
|
|
|
2006-12-24 22:52:54 +01:00
|
|
|
// Begin styling
|
2006-12-25 04:42:44 +01:00
|
|
|
StartStyling(0,255);
|
2007-08-06 16:29:43 +02:00
|
|
|
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?
|
2006-12-24 22:52:54 +01:00
|
|
|
wxChar curChar = 0;
|
|
|
|
wxChar prevChar = 0;
|
2006-12-25 06:43:00 +01:00
|
|
|
wxChar nextChar = 0;
|
2006-12-24 22:52:54 +01:00
|
|
|
|
|
|
|
// Loop through
|
2006-12-24 23:46:20 +01:00
|
|
|
for (int i=start;i<end;i++) {
|
2006-12-24 22:52:54 +01:00
|
|
|
// Current/previous characters
|
|
|
|
prevChar = curChar;
|
|
|
|
curChar = text[i];
|
2006-12-25 06:43:00 +01:00
|
|
|
if (i<end-1) nextChar = text[i+1];
|
|
|
|
else nextChar = 0;
|
2006-12-24 22:52:54 +01:00
|
|
|
|
|
|
|
// Erroneous
|
|
|
|
if (depth < 0 || depth > 1) {
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
2006-12-24 22:52:54 +01:00
|
|
|
ran = 0;
|
|
|
|
curStyle = 4;
|
2007-01-02 03:24:23 +01:00
|
|
|
numMode = false;
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start override block
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == '{' && depth >= 0) {
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
2006-12-24 22:52:54 +01:00
|
|
|
ran = 0;
|
|
|
|
depth++;
|
|
|
|
if (depth == 1) curStyle = 1;
|
|
|
|
else curStyle = 4;
|
2007-01-02 03:24:23 +01:00
|
|
|
numMode = false;
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// End override block
|
2010-07-20 05:11:11 +02:00
|
|
|
else if (curChar == '}' && depth <= 1) {
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
2006-12-24 22:52:54 +01:00
|
|
|
ran = 0;
|
|
|
|
depth--;
|
|
|
|
if (depth == 0) curStyle = 1;
|
|
|
|
else curStyle = 4;
|
2007-01-02 03:24:23 +01:00
|
|
|
numMode = false;
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
|
2007-08-06 16:29:43 +02:00
|
|
|
// Karaoke template block
|
2010-07-20 05:11:11 +02:00
|
|
|
else if (templateLine && curChar == '!') {
|
2007-08-06 16:29:43 +02:00
|
|
|
// 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;
|
2010-07-20 05:11:11 +02:00
|
|
|
while (endPos < end && text[endPos] != '!')
|
2007-08-06 16:29:43 +02:00
|
|
|
endPos++;
|
|
|
|
SetUnicodeStyling(curPos,endPos-curPos+1,7);
|
|
|
|
curPos = endPos+1;
|
|
|
|
i = endPos+0;
|
|
|
|
}
|
|
|
|
// Karaoke template variable
|
2010-07-20 05:11:11 +02:00
|
|
|
else if (templateLine && curChar == '$') {
|
2007-08-06 16:29:43 +02:00
|
|
|
// Apply previous style
|
|
|
|
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];
|
2010-07-20 05:11:11 +02:00
|
|
|
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_')
|
2007-08-06 16:29:43 +02:00
|
|
|
endPos++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SetUnicodeStyling(curPos,endPos-curPos,7);
|
|
|
|
curPos = endPos;
|
|
|
|
i = curPos-1;
|
|
|
|
}
|
|
|
|
|
2006-12-24 22:52:54 +01:00
|
|
|
// Outside
|
2006-12-25 06:43:00 +01:00
|
|
|
else if (depth == 0) {
|
2007-01-02 03:24:23 +01:00
|
|
|
// Reset number mode
|
|
|
|
numMode = false;
|
|
|
|
|
2006-12-25 06:43:00 +01:00
|
|
|
// Is \n, \N or \h?
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == L'\\' && (nextChar == 'n' || nextChar == 'N' || nextChar == 'h')) {
|
2006-12-25 06:43:00 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
2006-12-26 02:30:30 +01:00
|
|
|
curPos += ran;
|
2006-12-25 06:43:00 +01:00
|
|
|
ran = 1;
|
|
|
|
curStyle = 6;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Normal text
|
|
|
|
else if (curStyle != 0) {
|
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
|
|
|
ran = 0;
|
2007-01-02 03:33:42 +01:00
|
|
|
if (drawingMode) curStyle = 6;
|
|
|
|
else curStyle = 0;
|
2006-12-25 06:43:00 +01:00
|
|
|
}
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inside
|
|
|
|
else if (depth == 1) {
|
|
|
|
// Special character
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == L'\\' || curChar == '(' || curChar == ')' || curChar == ',') {
|
2006-12-24 22:52:54 +01:00
|
|
|
if (curStyle != 2) {
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
2006-12-24 22:52:54 +01:00
|
|
|
ran = 0;
|
|
|
|
curStyle = 2;
|
2007-01-02 03:24:23 +01:00
|
|
|
numMode = false;
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-02 03:24:23 +01:00
|
|
|
else {
|
|
|
|
// Number
|
2010-07-20 05:11:11 +02:00
|
|
|
if (prevChar != L'\\' && (numMode || (curChar >= '0' && curChar <= '9') || curChar == '.' || curChar == '&' || curChar == '+' || curChar == '-' || (curChar == 'H' && prevChar == '&'))) {
|
2007-01-02 03:24:23 +01:00
|
|
|
if (curStyle != 5) {
|
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
|
|
|
ran = 0;
|
|
|
|
curStyle = 5;
|
|
|
|
numMode = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tag name
|
|
|
|
else if (curStyle != 3) {
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
|
|
|
curPos += ran;
|
2006-12-24 22:52:54 +01:00
|
|
|
ran = 0;
|
2007-01-02 03:24:23 +01:00
|
|
|
curStyle = 3;
|
|
|
|
|
|
|
|
// Set parameter if it's \fn or \r
|
|
|
|
int tagLen = 0;
|
2010-07-20 05:11:11 +02:00
|
|
|
if (text.Mid(curPos,2) == L"fn") tagLen = 2;
|
|
|
|
else if (text.Mid(curPos,1) == L"r") tagLen = 1;
|
2007-01-02 03:24:23 +01:00
|
|
|
if (tagLen) {
|
|
|
|
numMode = true;
|
|
|
|
ran = tagLen-1;
|
|
|
|
i+=ran;
|
|
|
|
}
|
2007-01-02 03:33:42 +01:00
|
|
|
|
|
|
|
// Set drawing mode if it's \p
|
2010-07-20 05:11:11 +02:00
|
|
|
if (text.Mid(curPos,1) == L"p") {
|
2007-01-02 03:33:42 +01:00
|
|
|
if (curPos+2 < (signed) text.Length()) {
|
2007-01-02 06:00:55 +01:00
|
|
|
// Disable
|
2007-01-02 03:33:42 +01:00
|
|
|
wxChar nextNext = text[curPos+2];
|
2010-07-20 05:11:11 +02:00
|
|
|
if ((nextNext == L'\\' || nextNext == '}') && nextChar == '0') drawingMode = false;
|
2007-01-02 06:00:55 +01:00
|
|
|
|
|
|
|
// Enable
|
2010-07-20 05:11:11 +02:00
|
|
|
if (nextChar >= '1' && nextChar <= '9') {
|
2007-01-02 06:00:55 +01:00
|
|
|
for(int testPos = curPos+2;testPos < (signed) text.Length();testPos++) {
|
|
|
|
nextNext = text[testPos];
|
2010-07-20 05:11:11 +02:00
|
|
|
if (nextNext == L'\\' || nextNext == '}') {
|
2007-01-02 06:00:55 +01:00
|
|
|
drawingMode = true;
|
|
|
|
break;
|
|
|
|
}
|
2010-07-20 05:11:11 +02:00
|
|
|
if (nextNext < '0' || nextNext > '9') break;
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
2007-01-02 03:33:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Increase ran length
|
|
|
|
ran++;
|
|
|
|
}
|
2006-12-25 04:42:44 +01:00
|
|
|
SetUnicodeStyling(curPos,ran,curStyle);
|
2006-12-24 23:46:20 +01:00
|
|
|
StyleSpellCheck(start,_length);
|
2010-07-20 05:11:11 +02:00
|
|
|
wxStyledTextEvent evt;
|
|
|
|
UpdateCallTip(evt);
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
|
|
|
/// @brief Update call tip
|
2010-07-20 05:11:11 +02:00
|
|
|
void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
|
2010-05-21 03:13:36 +02:00
|
|
|
if (!OPT_GET("App/Call Tips")->GetBool()) return;
|
2007-01-02 23:10:45 +01:00
|
|
|
|
2007-01-02 06:00:55 +01:00
|
|
|
// Get position and text
|
|
|
|
const unsigned int pos = GetReverseUnicodePosition(GetCurrentPos());
|
|
|
|
wxString text = GetText();
|
|
|
|
|
2007-01-02 19:09:56 +01:00
|
|
|
// Find the start and end of current tag
|
2007-01-02 06:00:55 +01:00
|
|
|
wxChar curChar = 0;
|
2007-01-02 19:09:56 +01:00
|
|
|
wxChar prevChar = 0;
|
2007-01-02 06:00:55 +01:00
|
|
|
int depth = 0;
|
|
|
|
int inDepth = 0;
|
|
|
|
int tagStart = -1;
|
|
|
|
int tagEnd = -1;
|
2007-01-02 19:09:56 +01:00
|
|
|
for (unsigned int i=0;i<text.Length()+1;i++) {
|
2007-01-02 06:00:55 +01:00
|
|
|
// Get character
|
2007-01-02 19:09:56 +01:00
|
|
|
if (i<text.Length()) curChar = text[i];
|
|
|
|
else curChar = 0;
|
2007-01-02 06:00:55 +01:00
|
|
|
|
|
|
|
// Change depth
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == '{') {
|
2007-01-02 06:00:55 +01:00
|
|
|
depth++;
|
|
|
|
continue;
|
|
|
|
}
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == '}') {
|
2007-01-02 06:00:55 +01:00
|
|
|
depth--;
|
2007-01-02 19:09:56 +01:00
|
|
|
if (i >= pos && depth == 0) {
|
|
|
|
tagEnd = i-1;
|
2007-01-02 06:00:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Outside
|
|
|
|
if (depth == 0) {
|
|
|
|
tagStart = -1;
|
|
|
|
if (i == pos) break;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inside overrides
|
|
|
|
if (depth == 1) {
|
|
|
|
// Inner depth
|
|
|
|
if (tagStart != -1) {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == '(') inDepth++;
|
|
|
|
else if (curChar == ')') inDepth--;
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Not inside parenthesis
|
|
|
|
if (inDepth == 0) {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (prevChar == L'\\') {
|
2007-01-02 06:00:55 +01:00
|
|
|
// Found start
|
|
|
|
if (i <= pos) tagStart = i;
|
|
|
|
|
|
|
|
// Found end
|
|
|
|
else {
|
2007-01-02 19:09:56 +01:00
|
|
|
tagEnd = i-2;
|
2007-01-02 06:00:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-01-02 19:09:56 +01:00
|
|
|
|
|
|
|
// Previous character
|
|
|
|
prevChar = curChar;
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate length
|
|
|
|
int len;
|
|
|
|
if (tagEnd != -1) len = tagEnd - tagStart + 1;
|
|
|
|
else len = text.Length() - tagStart;
|
|
|
|
|
|
|
|
// No tag available
|
2007-01-02 19:09:56 +01:00
|
|
|
int textLen = text.Length();
|
|
|
|
unsigned int posInTag = pos - tagStart;
|
2007-04-04 22:42:44 +02:00
|
|
|
if (tagStart+len > textLen || len <= 0 || tagStart < 0) {
|
2007-01-02 06:00:55 +01:00
|
|
|
CallTipCancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Current tag
|
|
|
|
wxString tag = text.Mid(tagStart,len);
|
|
|
|
|
|
|
|
// Metrics in tag
|
|
|
|
int tagCommas = 0;
|
|
|
|
int tagParenthesis = 0;
|
|
|
|
int parN = 0;
|
|
|
|
int parPos = -1;
|
|
|
|
bool gotName = false;
|
|
|
|
wxString tagName = tag;
|
|
|
|
for (unsigned int i=0;i<tag.Length();i++) {
|
|
|
|
wxChar curChar = tag[i];
|
2007-01-02 19:09:56 +01:00
|
|
|
bool isEnd = false;
|
2007-01-02 06:00:55 +01:00
|
|
|
|
|
|
|
// Commas
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == ',') {
|
2007-01-02 06:00:55 +01:00
|
|
|
tagCommas++;
|
|
|
|
parN++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parenthesis
|
2010-07-20 05:11:11 +02:00
|
|
|
else if (curChar == '(') {
|
2007-01-02 19:09:56 +01:00
|
|
|
tagParenthesis++;
|
|
|
|
parN++;
|
|
|
|
}
|
2010-07-20 05:11:11 +02:00
|
|
|
else if (curChar == ')') {
|
2007-01-02 06:00:55 +01:00
|
|
|
tagParenthesis++;
|
|
|
|
parN++;
|
2007-01-02 19:09:56 +01:00
|
|
|
isEnd = true;
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tag name
|
|
|
|
if (parN == 1 && !gotName) {
|
|
|
|
tagName = tag.Left(i);
|
|
|
|
gotName = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parameter it's on
|
2007-01-02 19:09:56 +01:00
|
|
|
if (i == posInTag) {
|
|
|
|
parPos = parN;
|
2010-07-20 05:11:11 +02:00
|
|
|
if (curChar == ',' || curChar == '(' || curChar == ')') {
|
2007-01-02 19:09:56 +01:00
|
|
|
parPos--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (isEnd) {
|
|
|
|
parN = 1000;
|
|
|
|
break;
|
|
|
|
}
|
2007-01-02 06:00:55 +01:00
|
|
|
}
|
|
|
|
if (parPos == -1) parPos = parN;
|
|
|
|
|
|
|
|
// Tag name
|
|
|
|
if (tagName.IsEmpty()) {
|
|
|
|
CallTipCancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find matching prototype
|
|
|
|
wxString useProto;
|
2007-01-02 19:09:56 +01:00
|
|
|
wxString cleanProto;
|
|
|
|
wxString protoName;
|
2007-01-24 04:54:32 +01:00
|
|
|
int protoN = 0;
|
2007-01-02 19:09:56 +01:00
|
|
|
bool semiProto = false;
|
2007-01-02 06:00:55 +01:00
|
|
|
for (unsigned int i=0;i<proto.Count();i++) {
|
2007-01-02 19:09:56 +01:00
|
|
|
// Get prototype name
|
2010-07-20 05:11:11 +02:00
|
|
|
int div = proto[i].Find(';');
|
2007-01-02 19:09:56 +01:00
|
|
|
if (div != wxNOT_FOUND) protoName = proto[i].Left(div);
|
|
|
|
else {
|
2010-07-20 05:11:11 +02:00
|
|
|
div = proto[i].Find('(');
|
2007-01-02 19:09:56 +01:00
|
|
|
protoName = proto[i].Left(div);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fix name
|
|
|
|
semiProto = false;
|
|
|
|
cleanProto = proto[i];
|
2010-07-20 05:11:11 +02:00
|
|
|
if (cleanProto.Freq(';') > 0) {
|
|
|
|
cleanProto.Replace(L";","");
|
2007-01-02 19:09:56 +01:00
|
|
|
semiProto = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prototype match
|
|
|
|
wxString temp;
|
|
|
|
if (semiProto) temp = tagName.Left(protoName.Length());
|
|
|
|
else temp = tagName;
|
|
|
|
if (protoName == temp) {
|
|
|
|
// Parameter count match
|
2010-07-20 05:11:11 +02:00
|
|
|
if (proto[i].Freq(',') >= tagCommas) {
|
2007-01-02 19:09:56 +01:00
|
|
|
// Found
|
2007-01-02 06:00:55 +01:00
|
|
|
useProto = proto[i];
|
2007-01-02 19:15:17 +01:00
|
|
|
protoN = i;
|
2007-01-02 06:00:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No matching prototype
|
|
|
|
if (useProto.IsEmpty()) {
|
|
|
|
CallTipCancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-01-02 19:09:56 +01:00
|
|
|
// Parameter number for tags without "(),"
|
|
|
|
if (semiProto && parPos == 0 && posInTag >= protoName.Length()) parPos = 1;
|
|
|
|
|
2007-01-02 06:00:55 +01:00
|
|
|
// Highlight start/end
|
|
|
|
int highStart = useProto.Length();
|
|
|
|
int highEnd = -1;
|
|
|
|
parN = 0;
|
2007-01-02 19:09:56 +01:00
|
|
|
int delta = 0;
|
2007-01-02 06:00:55 +01:00
|
|
|
for (unsigned int i=0;i<useProto.Length();i++) {
|
|
|
|
wxChar curChar = useProto[i];
|
2010-07-20 05:11:11 +02:00
|
|
|
if (i == 0 || curChar == ',' || curChar == ';' || curChar == '(' || curChar == ')') {
|
|
|
|
if (curChar == ';') delta++;
|
2007-01-02 19:09:56 +01:00
|
|
|
if (parN == parPos) highStart = i+1-delta;
|
2007-01-02 06:00:55 +01:00
|
|
|
else if (parN == parPos+1) highEnd = i;
|
|
|
|
parN++;
|
|
|
|
}
|
|
|
|
}
|
2007-01-02 19:09:56 +01:00
|
|
|
if (highStart <= 1) highStart = 0;
|
2007-01-02 06:00:55 +01:00
|
|
|
if (highEnd == -1) highEnd = useProto.Length();
|
|
|
|
|
|
|
|
// Calltip is over
|
2007-01-24 04:54:32 +01:00
|
|
|
if (highStart == (signed) useProto.Length()) {
|
2007-01-02 06:00:55 +01:00
|
|
|
CallTipCancel();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show calltip
|
2007-01-02 19:15:17 +01:00
|
|
|
if (!CallTipActive() || tipProtoN != protoN) CallTipShow(GetUnicodePosition(tagStart),cleanProto);
|
|
|
|
tipProtoN = protoN;
|
2007-01-02 06:00:55 +01:00
|
|
|
CallTipSetHighlight(highStart,highEnd);
|
2006-12-24 23:46:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void SubsTextEditCtrl::StyleSpellCheck(int start, int len) {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (!spellchecker.get()) return;
|
2006-12-24 23:46:20 +01:00
|
|
|
|
2007-04-14 17:26:46 +02:00
|
|
|
// Results
|
2006-12-24 23:46:20 +01:00
|
|
|
wxString text = GetText();
|
2007-04-14 17:26:46 +02:00
|
|
|
IntPairVector results;
|
|
|
|
GetWordBoundaries(text,results,start,(len == -1) ? len : start+len);
|
2006-12-24 23:46:20 +01:00
|
|
|
|
|
|
|
// Style
|
2007-04-14 17:26:46 +02:00
|
|
|
int count = results.size();
|
2006-12-24 23:46:20 +01:00
|
|
|
for (int i=0;i<count;i++) {
|
|
|
|
// Get current word
|
2007-04-14 17:26:46 +02:00
|
|
|
int s = results[i].first;
|
|
|
|
int e = results[i].second;
|
|
|
|
wxString curWord = text.Mid(s,e-s);
|
2006-12-24 23:46:20 +01:00
|
|
|
|
|
|
|
// Check if it's valid
|
|
|
|
if (!spellchecker->CheckWord(curWord)) {
|
2006-12-25 04:42:44 +01:00
|
|
|
// Get length before it
|
2007-04-14 17:26:46 +02:00
|
|
|
int utf8len = GetUnicodePosition(s);
|
2006-12-25 04:42:44 +01:00
|
|
|
|
|
|
|
// Set styling
|
|
|
|
StartStyling(utf8len,32);
|
2007-04-14 17:26:46 +02:00
|
|
|
SetUnicodeStyling(s,e-s,32);
|
|
|
|
}
|
|
|
|
}
|
2008-06-01 05:44:41 +02:00
|
|
|
|
|
|
|
// It seems like wxStyledTextCtrl wants you to finish styling at the end of the text.
|
|
|
|
// I don't really understand why, it's not documented anywhere I can find, but this fixes bug #595.
|
|
|
|
StartUnicodeStyling(text.Length(), 0);
|
|
|
|
SetUnicodeStyling(text.Length(), 0, 0);
|
2007-04-14 17:26:46 +02:00
|
|
|
}
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
void SubsTextEditCtrl::SetTextTo(wxString text) {
|
|
|
|
SetEvtHandlerEnabled(false);
|
2006-12-24 22:52:54 +01:00
|
|
|
Freeze();
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
text.Replace(L"\r\n",L"\\N");
|
|
|
|
text.Replace(L"\r",L"\\N");
|
|
|
|
text.Replace(L"\n",L"\\N");
|
|
|
|
|
2006-12-24 22:52:54 +01:00
|
|
|
int from=0,to=0;
|
|
|
|
GetSelection(&from,&to);
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
SetText(text);
|
|
|
|
UpdateStyle();
|
|
|
|
|
|
|
|
// Restore selection
|
2006-12-26 02:20:58 +01:00
|
|
|
SetSelectionU(GetReverseUnicodePosition(from),GetReverseUnicodePosition(to));
|
2006-12-24 22:52:54 +01:00
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
SetEvtHandlerEnabled(true);
|
2006-12-24 22:52:54 +01:00
|
|
|
Thaw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsTextEditCtrl::OnMouseEvent(wxMouseEvent &event) {
|
|
|
|
if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (grid->GetActiveLine() != 0) {
|
2006-12-25 06:43:00 +01:00
|
|
|
int pos = PositionFromPoint(event.GetPosition());
|
|
|
|
ShowPopupMenu(pos);
|
2006-12-24 22:52:54 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
event.Skip();
|
2009-06-12 01:30:33 +02:00
|
|
|
GetParent()->GetEventHandler()->ProcessEvent(event);
|
2006-12-24 22:52:54 +01:00
|
|
|
}
|
2006-12-25 06:43:00 +01:00
|
|
|
|
|
|
|
void SubsTextEditCtrl::ShowPopupMenu(int activePos) {
|
|
|
|
wxMenu menu;
|
|
|
|
|
|
|
|
if (activePos == -1) activePos = GetCurrentPos();
|
2006-12-26 02:08:46 +01:00
|
|
|
activePos = GetReverseUnicodePosition(activePos);
|
2006-12-25 06:43:00 +01:00
|
|
|
|
2006-12-25 22:56:56 +01:00
|
|
|
currentWord = GetWordAtPosition(activePos);
|
|
|
|
currentWordPos = activePos;
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
if (spellchecker.get() && currentWord.Length()) {
|
2006-12-26 00:10:23 +01:00
|
|
|
bool rightSpelling = spellchecker->CheckWord(currentWord);
|
|
|
|
|
2006-12-25 06:52:29 +01:00
|
|
|
wxFont font;
|
|
|
|
font.SetWeight(wxFONTWEIGHT_BOLD);
|
|
|
|
|
2006-12-25 22:56:56 +01:00
|
|
|
sugs.Clear();
|
|
|
|
sugs = spellchecker->GetSuggestions(currentWord);
|
|
|
|
int nSugs = sugs.Count();
|
2006-12-25 06:43:00 +01:00
|
|
|
|
2006-12-26 00:10:23 +01:00
|
|
|
if (!rightSpelling) {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (!nSugs) {
|
|
|
|
menu.Append(EDIT_MENU_SUGGESTION,_("No correction suggestions"))->Enable(false);
|
|
|
|
}
|
2006-12-25 06:52:29 +01:00
|
|
|
|
2007-01-03 23:05:43 +01:00
|
|
|
for (int i=0;i<nSugs;i++) {
|
2010-01-10 17:15:31 +01:00
|
|
|
wxMenuItem *itm = new wxMenuItem(&menu, EDIT_MENU_SUGGESTIONS+i, sugs[i]);
|
2009-07-25 20:45:30 +02:00
|
|
|
#ifdef __WINDOWS__
|
2007-01-03 23:05:43 +01:00
|
|
|
itm->SetFont(font);
|
|
|
|
#endif
|
2010-01-10 17:15:31 +01:00
|
|
|
menu.Append(itm);
|
2007-01-03 23:05:43 +01:00
|
|
|
}
|
2006-12-26 00:10:23 +01:00
|
|
|
|
|
|
|
// Append "add word"
|
2010-01-21 01:24:59 +01:00
|
|
|
wxString add_to_dict_text(_("Add \"%s\" to dictionary"));
|
2010-07-20 05:11:11 +02:00
|
|
|
add_to_dict_text.Replace(L"%s", currentWord);
|
2010-01-21 01:24:59 +01:00
|
|
|
menu.Append(EDIT_MENU_ADD_TO_DICT,add_to_dict_text)->Enable(spellchecker->CanAddWord(currentWord));
|
2006-12-26 00:10:23 +01:00
|
|
|
}
|
|
|
|
// Spelled right
|
|
|
|
else {
|
2010-07-20 05:11:11 +02:00
|
|
|
if (!nSugs) {
|
|
|
|
menu.Append(EDIT_MENU_SUGGESTION,_("No spell checker suggestions"))->Enable(false);
|
|
|
|
}
|
2006-12-26 00:10:23 +01:00
|
|
|
else {
|
|
|
|
// Build list
|
|
|
|
wxMenu *subMenu = new wxMenu();
|
|
|
|
for (int i=0;i<nSugs;i++) subMenu->Append(EDIT_MENU_SUGGESTIONS+i,sugs[i]);
|
2007-01-03 22:51:09 +01:00
|
|
|
menu.Append(-1,wxString::Format(_("Spell checker suggestions for \"%s\""),currentWord.c_str()), subMenu);
|
2006-12-26 00:10:23 +01:00
|
|
|
}
|
|
|
|
}
|
2007-01-02 00:47:09 +01:00
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
wxArrayString langs = spellchecker->GetLanguageList(); // This probably should be cached...
|
2010-05-21 03:13:36 +02:00
|
|
|
wxString curLang = lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString());
|
2007-01-02 00:47:09 +01:00
|
|
|
|
|
|
|
// Languages
|
|
|
|
wxMenu *languageMenu = new wxMenu();
|
|
|
|
wxMenuItem *cur;
|
|
|
|
wxString name;
|
|
|
|
const wxLanguageInfo *info;
|
|
|
|
|
|
|
|
// Insert "Disable"
|
|
|
|
cur = languageMenu->AppendCheckItem(EDIT_MENU_DIC_LANGS,_("Disable"));
|
|
|
|
if (curLang.IsEmpty()) cur->Check();
|
|
|
|
|
|
|
|
// Each language found
|
|
|
|
for (unsigned int i=0;i<langs.Count();i++) {
|
|
|
|
info = wxLocale::FindLanguageInfo(langs[i]);
|
|
|
|
if (info) name = info->Description;
|
|
|
|
else name = langs[i];
|
|
|
|
cur = languageMenu->AppendCheckItem(EDIT_MENU_DIC_LANGS+i+1,name);
|
|
|
|
if (langs[i] == curLang) cur->Check();
|
2007-01-01 05:53:55 +01:00
|
|
|
}
|
2007-01-02 00:47:09 +01:00
|
|
|
|
|
|
|
// Append language list
|
2007-01-03 22:51:09 +01:00
|
|
|
menu.Append(-1,_("Spell checker language"), languageMenu);
|
2007-01-01 05:53:55 +01:00
|
|
|
menu.AppendSeparator();
|
2006-12-25 22:56:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Thesaurus
|
2010-07-20 05:11:11 +02:00
|
|
|
if (thesaurus.get() && currentWord.Length()) {
|
2006-12-25 23:21:44 +01:00
|
|
|
// Get results
|
|
|
|
ThesaurusEntryArray result;
|
|
|
|
thesaurus->Lookup(currentWord,result);
|
|
|
|
|
|
|
|
// Compile list
|
2006-12-25 22:56:56 +01:00
|
|
|
thesSugs.Clear();
|
2006-12-25 23:21:44 +01:00
|
|
|
for (unsigned int i=0;i<result.size();i++) {
|
|
|
|
for (unsigned int j=0;j<result[i].words.Count();j++) {
|
|
|
|
thesSugs.Add(result[i].words[j]);
|
|
|
|
}
|
|
|
|
}
|
2006-12-25 22:56:56 +01:00
|
|
|
|
2006-12-25 23:52:21 +01:00
|
|
|
if (result.size()) {
|
|
|
|
wxFont font;
|
|
|
|
font.SetStyle(wxFONTSTYLE_ITALIC);
|
|
|
|
|
2006-12-26 00:10:23 +01:00
|
|
|
// Create thesaurus menu
|
|
|
|
wxMenu *thesMenu = new wxMenu();
|
2006-12-25 23:21:44 +01:00
|
|
|
|
2006-12-26 00:10:23 +01:00
|
|
|
// Build menu
|
|
|
|
int curThesEntry = 0;
|
|
|
|
for (unsigned int i=0;i<result.size();i++) {
|
|
|
|
// Single word, insert directly
|
|
|
|
if (result[i].words.Count() == 1) {
|
|
|
|
thesMenu->Append(EDIT_MENU_THESAURUS_SUGS+curThesEntry,result[i].name);
|
2006-12-25 23:21:44 +01:00
|
|
|
curThesEntry++;
|
|
|
|
}
|
|
|
|
|
2006-12-26 00:10:23 +01:00
|
|
|
// Multiple, create submenu
|
|
|
|
else {
|
|
|
|
// Insert entries
|
|
|
|
wxMenu *subMenu = new wxMenu();
|
|
|
|
for (unsigned int j=0;j<result[i].words.Count();j++) {
|
|
|
|
subMenu->Append(EDIT_MENU_THESAURUS_SUGS+curThesEntry,result[i].words[j]);
|
|
|
|
curThesEntry++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert submenu
|
2007-01-03 22:51:09 +01:00
|
|
|
thesMenu->Append(-1, result[i].name, subMenu);
|
2006-12-26 00:10:23 +01:00
|
|
|
}
|
2006-12-25 23:21:44 +01:00
|
|
|
}
|
2006-12-26 00:10:23 +01:00
|
|
|
|
|
|
|
// Thesaurus menu
|
2010-01-21 01:24:59 +01:00
|
|
|
wxString thes_suggestion_text(_("Thesaurus suggestions for \"%s\""));
|
2010-07-20 05:11:11 +02:00
|
|
|
thes_suggestion_text.Replace(L"%s", currentWord);
|
2010-01-21 01:24:59 +01:00
|
|
|
menu.Append(-1,thes_suggestion_text,thesMenu);
|
|
|
|
|
2006-12-25 23:21:44 +01:00
|
|
|
}
|
2006-12-25 22:56:56 +01:00
|
|
|
|
2006-12-25 23:21:44 +01:00
|
|
|
if (!result.size()) menu.Append(EDIT_MENU_THESAURUS,_("No thesaurus suggestions"))->Enable(false);
|
2006-12-25 22:56:56 +01:00
|
|
|
|
2007-01-01 06:15:05 +01:00
|
|
|
wxArrayString langs = thesaurus->GetLanguageList(); // This probably should be cached...
|
2010-05-21 03:13:36 +02:00
|
|
|
wxString curLang = lagi_wxString(OPT_GET("Tool/Thesaurus/Language")->GetString());
|
2007-01-02 00:47:09 +01:00
|
|
|
|
|
|
|
// Languages
|
|
|
|
wxMenu *languageMenu = new wxMenu();
|
|
|
|
wxMenuItem *cur;
|
|
|
|
wxString name;
|
|
|
|
const wxLanguageInfo *info;
|
|
|
|
|
|
|
|
// Insert "Disable"
|
|
|
|
cur = languageMenu->AppendCheckItem(EDIT_MENU_THES_LANGS,_("Disable"));
|
|
|
|
if (curLang.IsEmpty()) cur->Check();
|
|
|
|
|
|
|
|
// Each language found
|
|
|
|
for (unsigned int i=0;i<langs.Count();i++) {
|
|
|
|
info = wxLocale::FindLanguageInfo(langs[i]);
|
|
|
|
if (info) name = info->Description;
|
|
|
|
else name = langs[i];
|
|
|
|
cur = languageMenu->AppendCheckItem(EDIT_MENU_THES_LANGS+i+1,name);
|
|
|
|
if (langs[i] == curLang) cur->Check();
|
2007-01-01 06:15:05 +01:00
|
|
|
}
|
|
|
|
|
2007-01-02 00:47:09 +01:00
|
|
|
// Append language list
|
2007-01-03 22:51:09 +01:00
|
|
|
menu.Append(-1, _("Thesaurus language"), languageMenu);
|
2006-12-25 22:56:56 +01:00
|
|
|
menu.AppendSeparator();
|
2006-12-25 06:43:00 +01:00
|
|
|
}
|
|
|
|
|
2006-12-25 06:52:29 +01:00
|
|
|
// Standard actions
|
|
|
|
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());
|
|
|
|
menu.AppendSeparator();
|
|
|
|
menu.Append(EDIT_MENU_SELECT_ALL,_("Select &All"));
|
|
|
|
|
|
|
|
// Split
|
|
|
|
menu.AppendSeparator();
|
|
|
|
menu.Append(EDIT_MENU_SPLIT_PRESERVE,_("Split at cursor (preserve times)"));
|
|
|
|
menu.Append(EDIT_MENU_SPLIT_ESTIMATE,_("Split at cursor (estimate times)"));
|
|
|
|
|
2006-12-25 06:43:00 +01:00
|
|
|
PopupMenu(&menu);
|
|
|
|
}
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
void SubsTextEditCtrl::OnSplitLinePreserve (wxCommandEvent &) {
|
2006-12-25 06:43:00 +01:00
|
|
|
int from,to;
|
|
|
|
GetSelection(&from, &to);
|
2006-12-26 02:30:30 +01:00
|
|
|
from = GetReverseUnicodePosition(from);
|
2010-07-20 05:11:11 +02:00
|
|
|
grid->SplitLine(grid->GetActiveLine(),from,0);
|
2006-12-25 06:43:00 +01:00
|
|
|
}
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
void SubsTextEditCtrl::OnSplitLineEstimate (wxCommandEvent &) {
|
2006-12-25 06:43:00 +01:00
|
|
|
int from,to;
|
|
|
|
GetSelection(&from, &to);
|
2006-12-26 02:30:30 +01:00
|
|
|
from = GetReverseUnicodePosition(from);
|
2010-07-20 05:11:11 +02:00
|
|
|
grid->SplitLine(grid->GetActiveLine(),from,1);
|
2006-12-25 06:43:00 +01:00
|
|
|
}
|
|
|
|
|
2010-07-20 05:11:11 +02:00
|
|
|
void SubsTextEditCtrl::OnAddToDictionary(wxCommandEvent &) {
|
|
|
|
if (spellchecker.get()) spellchecker->AddWord(currentWord);
|
2008-01-14 03:01:50 +01:00
|
|
|
UpdateStyle();
|
2006-12-25 06:43:00 +01:00
|
|
|
SetFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsTextEditCtrl::OnUseSuggestion(wxCommandEvent &event) {
|
2010-07-20 05:11:11 +02:00
|
|
|
wxString suggestion;
|
|
|
|
int sugIdx = event.GetId() - EDIT_MENU_THESAURUS_SUGS;
|
|
|
|
if (sugIdx >= 0) {
|
|
|
|
suggestion = thesSugs[sugIdx];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
suggestion = sugs[event.GetId() - EDIT_MENU_SUGGESTIONS];
|
|
|
|
}
|
2006-12-25 23:30:11 +01:00
|
|
|
|
|
|
|
// Stripe suggestion of parenthesis
|
2010-07-20 05:11:11 +02:00
|
|
|
int pos = suggestion.Find(L"(");
|
2006-12-25 23:30:11 +01:00
|
|
|
if (pos != wxNOT_FOUND) {
|
|
|
|
suggestion = suggestion.Left(pos-1);
|
|
|
|
}
|
2010-07-20 05:11:11 +02:00
|
|
|
|
2006-12-25 23:21:44 +01:00
|
|
|
// Get boundaries of text being replaced
|
|
|
|
int start,end;
|
|
|
|
GetBoundsOfWordAtPosition(currentWordPos,start,end);
|
|
|
|
|
|
|
|
wxString text = GetText();
|
|
|
|
SetText(text.Left(MAX(0,start)) + suggestion + text.Mid(end+1));
|
|
|
|
|
|
|
|
// Set selection
|
2006-12-26 02:20:58 +01:00
|
|
|
SetSelectionU(start,start+suggestion.Length());
|
2006-12-25 23:21:44 +01:00
|
|
|
SetFocus();
|
|
|
|
}
|
2006-12-26 02:20:58 +01:00
|
|
|
|
2007-01-01 05:53:55 +01:00
|
|
|
void SubsTextEditCtrl::OnSetDicLanguage(wxCommandEvent &event) {
|
|
|
|
wxArrayString langs = spellchecker->GetLanguageList();
|
|
|
|
|
|
|
|
// Set dictionary
|
2007-01-02 00:47:09 +01:00
|
|
|
int index = event.GetId() - EDIT_MENU_DIC_LANGS - 1;
|
|
|
|
wxString lang;
|
|
|
|
if (index >= 0) lang = langs[index];
|
|
|
|
spellchecker->SetLanguage(lang);
|
2010-05-21 03:13:36 +02:00
|
|
|
OPT_SET("Tool/Spell Checker/Language")->SetString(STD_STR(lang));
|
2007-01-01 05:53:55 +01:00
|
|
|
|
|
|
|
UpdateStyle();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsTextEditCtrl::OnSetThesLanguage(wxCommandEvent &event) {
|
|
|
|
wxArrayString langs = thesaurus->GetLanguageList();
|
|
|
|
|
|
|
|
// Set language
|
2007-01-02 00:47:09 +01:00
|
|
|
int index = event.GetId() - EDIT_MENU_THES_LANGS - 1;
|
|
|
|
wxString lang;
|
|
|
|
if (index >= 0) lang = langs[index];
|
|
|
|
thesaurus->SetLanguage(lang);
|
2010-05-21 03:13:36 +02:00
|
|
|
OPT_SET("Tool/Thesaurus/Language")->SetString(STD_STR(lang));
|
2007-01-01 05:53:55 +01:00
|
|
|
|
|
|
|
UpdateStyle();
|
|
|
|
}
|