X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b8b0e4022e105e102b5c7044638972a3fef38dc1..f51723055aa4334a355a19e87bb2b478b4204d15:/src/stc/stc.cpp.in diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 3a415e1f85..2d23345d91 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////// // Name: stc.cpp -// Purpose: A wxWindows implementation of Scintilla. This class is the +// Purpose: A wxWidgets implementation of Scintilla. This class is the // one meant to be used directly by wx applications. It does not // derive directly from the Scintilla classes, but instead // delegates most things to the real Scintilla class. @@ -15,115 +15,154 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// -#include +/* + IMPORTANT: src/stc/stc.cpp is generated by src/stc/gen_iface.py from + src/stc/stc.cpp.in, don't edit stc.cpp file as your changes will be + lost after the next regeneration, edit stc.cpp.in and rerun the + gen_iface.py script instead! + + Parts of this file generated by the script are found in between + the special "{{{" and "}}}" markers, the rest of it is copied + verbatim from src.h.in. + */ + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_STC #include "wx/stc/stc.h" +#include "wx/stc/private.h" + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif // WX_PRECOMP + +#include + +#include "wx/tokenzr.h" +#include "wx/mstream.h" +#include "wx/image.h" +#include "wx/file.h" + #include "ScintillaWX.h" -#include +//---------------------------------------------------------------------- -// The following code forces a reference to all of the Scintilla lexers. -// If we don't do something like this, then the linker tends to "optimize" -// them away. (eric@sourcegear.com) +const char wxSTCNameStr[] = "stcwindow"; -int wxForceScintillaLexers(void) -{ - extern LexerModule lmAda; - extern LexerModule lmAVE; - extern LexerModule lmConf; - extern LexerModule lmCPP; - extern LexerModule lmNncrontab; - extern LexerModule lmEiffel; - extern LexerModule lmHTML; - extern LexerModule lmLISP; - extern LexerModule lmLua; - extern LexerModule lmBatch; // In LexOthers.cxx - extern LexerModule lmPascal; - extern LexerModule lmPerl; - extern LexerModule lmPython; - extern LexerModule lmRuby; - extern LexerModule lmSQL; - extern LexerModule lmVB; - - if ( &lmAda - && &lmAVE - && &lmConf - && &lmCPP - && &lmNncrontab - && &lmEiffel - && &lmHTML - && &lmLISP - && &lmLua - && &lmBatch - && &lmPascal - && &lmPerl - && &lmPython - && &lmRuby - && &lmSQL - && &lmVB ) - { - return 1; - } - else - { - return 0; - } +#ifdef MAKELONG +#undef MAKELONG +#endif + +#define MAKELONG(a, b) ((a) | ((b) << 16)) + + +static long wxColourAsLong(const wxColour& co) { + return (((long)co.Blue() << 16) | + ((long)co.Green() << 8) | + ((long)co.Red())); } -//---------------------------------------------------------------------- +static wxColour wxColourFromLong(long c) { + wxColour clr; + clr.Set((unsigned char)(c & 0xff), + (unsigned char)((c >> 8) & 0xff), + (unsigned char)((c >> 16) & 0xff)); + return clr; +} -const wxChar* wxSTCNameStr = "stcwindow"; -DEFINE_EVENT_TYPE( wxEVT_STC_CHANGE ) -DEFINE_EVENT_TYPE( wxEVT_STC_STYLENEEDED ) -DEFINE_EVENT_TYPE( wxEVT_STC_CHARADDED ) -DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTREACHED ) -DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTLEFT ) -DEFINE_EVENT_TYPE( wxEVT_STC_ROMODIFYATTEMPT ) -DEFINE_EVENT_TYPE( wxEVT_STC_KEY ) -DEFINE_EVENT_TYPE( wxEVT_STC_DOUBLECLICK ) -DEFINE_EVENT_TYPE( wxEVT_STC_UPDATEUI ) -DEFINE_EVENT_TYPE( wxEVT_STC_MODIFIED ) -DEFINE_EVENT_TYPE( wxEVT_STC_MACRORECORD ) -DEFINE_EVENT_TYPE( wxEVT_STC_MARGINCLICK ) -DEFINE_EVENT_TYPE( wxEVT_STC_NEEDSHOWN ) -DEFINE_EVENT_TYPE( wxEVT_STC_POSCHANGED ) -DEFINE_EVENT_TYPE( wxEVT_STC_PAINTED ) -DEFINE_EVENT_TYPE( wxEVT_STC_USERLISTSELECTION ) -DEFINE_EVENT_TYPE( wxEVT_STC_URIDROPPED ) -DEFINE_EVENT_TYPE( wxEVT_STC_DWELLSTART ) -DEFINE_EVENT_TYPE( wxEVT_STC_DWELLEND ) +static wxColour wxColourFromSpec(const wxString& spec) { + // spec should be a colour name or "#RRGGBB" + if (spec.GetChar(0) == wxT('#')) { + + long red, green, blue; + red = green = blue = 0; + spec.Mid(1,2).ToLong(&red, 16); + spec.Mid(3,2).ToLong(&green, 16); + spec.Mid(5,2).ToLong(&blue, 16); + return wxColour((unsigned char)red, + (unsigned char)green, + (unsigned char)blue); + } + else + return wxColour(spec); +} + +//---------------------------------------------------------------------- +wxDEFINE_EVENT( wxEVT_STC_CHANGE, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_STYLENEEDED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_CHARADDED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_SAVEPOINTREACHED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_SAVEPOINTLEFT, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_ROMODIFYATTEMPT, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_KEY, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_DOUBLECLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_UPDATEUI, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_MODIFIED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_MACRORECORD, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_MARGINCLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_NEEDSHOWN, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_PAINTED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_USERLISTSELECTION, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_URIDROPPED, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_DWELLSTART, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_DWELLEND, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_START_DRAG, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_DRAG_OVER, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_DO_DROP, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_ZOOM, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_HOTSPOT_CLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_HOTSPOT_DCLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_CALLTIP_CLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent ); +wxDEFINE_EVENT( wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent ); BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) EVT_PAINT (wxStyledTextCtrl::OnPaint) EVT_SCROLLWIN (wxStyledTextCtrl::OnScrollWin) + EVT_SCROLL (wxStyledTextCtrl::OnScroll) EVT_SIZE (wxStyledTextCtrl::OnSize) EVT_LEFT_DOWN (wxStyledTextCtrl::OnMouseLeftDown) -#ifdef __WXMSW__ // Let Scintilla see the double click as a second click EVT_LEFT_DCLICK (wxStyledTextCtrl::OnMouseLeftDown) -#endif EVT_MOTION (wxStyledTextCtrl::OnMouseMove) EVT_LEFT_UP (wxStyledTextCtrl::OnMouseLeftUp) +#if defined(__WXGTK__) || defined(__WXMAC__) + EVT_RIGHT_UP (wxStyledTextCtrl::OnMouseRightUp) +#else EVT_CONTEXT_MENU (wxStyledTextCtrl::OnContextMenu) +#endif EVT_MOUSEWHEEL (wxStyledTextCtrl::OnMouseWheel) + EVT_MIDDLE_UP (wxStyledTextCtrl::OnMouseMiddleUp) EVT_CHAR (wxStyledTextCtrl::OnChar) EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown) EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus) EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus) EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged) EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground) - EVT_MENU_RANGE (-1, -1, wxStyledTextCtrl::OnMenu) - EVT_LISTBOX_DCLICK (-1, wxStyledTextCtrl::OnListBox) + EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu) + EVT_LISTBOX_DCLICK (wxID_ANY, wxStyledTextCtrl::OnListBox) END_EVENT_TABLE() IMPLEMENT_CLASS(wxStyledTextCtrl, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxStyledTextEvent, wxCommandEvent) +#ifdef LINK_LEXERS +// forces the linking of the lexer modules +int Scintilla_LinkLexers(); +#endif + //---------------------------------------------------------------------- // Constructor and Destructor @@ -132,14 +171,49 @@ wxStyledTextCtrl::wxStyledTextCtrl(wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, - const wxString& name) : - wxControl(parent, id, pos, size, - style | wxVSCROLL | wxHSCROLL | wxWANTS_CHARS | wxCLIP_CHILDREN, - wxDefaultValidator, name) + const wxString& name) +{ + m_swx = NULL; + Create(parent, id, pos, size, style, name); +} + + +bool wxStyledTextCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { + style |= wxVSCROLL | wxHSCROLL; + if (!wxControl::Create(parent, id, pos, size, + style | wxWANTS_CHARS | wxCLIP_CHILDREN, + wxDefaultValidator, name)) + return false; + +#ifdef LINK_LEXERS + Scintilla_LinkLexers(); +#endif m_swx = new ScintillaWX(this); m_stopWatch.Start(); - m_lastKeyDownConsumed = FALSE; + m_lastKeyDownConsumed = false; + m_lastWheelTimestamp = 0; + m_vScrollBar = NULL; + m_hScrollBar = NULL; +#if wxUSE_UNICODE + // Put Scintilla into unicode (UTF-8) mode + SetCodePage(wxSTC_CP_UTF8); +#endif + + SetInitialSize(size); + + // Reduces flicker on GTK+/X11 + SetBackgroundStyle(wxBG_STYLE_CUSTOM); + + // Make sure it can take the focus + SetCanFocus(true); + + return true; } @@ -150,50 +224,38 @@ wxStyledTextCtrl::~wxStyledTextCtrl() { //---------------------------------------------------------------------- -long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) { - +wxIntPtr wxStyledTextCtrl::SendMsg(int msg, wxUIntPtr wp, wxIntPtr lp) const +{ return m_swx->WndProc(msg, wp, lp); } +//---------------------------------------------------------------------- -#ifdef MAKELONG -#undef MAKELONG -#endif - -#define MAKELONG(a, b) ((a) | ((b) << 16)) - - -static long wxColourAsLong(const wxColour& co) { - return (((long)co.Blue() << 16) | - ((long)co.Green() << 8) | - ((long)co.Red())); -} - -static wxColour wxColourFromLong(long c) { - wxColour clr; - clr.Set(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff); - return clr; +// Set the vertical scrollbar to use instead of the ont that's built-in. +void wxStyledTextCtrl::SetVScrollBar(wxScrollBar* bar) { + m_vScrollBar = bar; + if (bar != NULL) { + // ensure that the built-in scrollbar is not visible + SetScrollbar(wxVERTICAL, 0, 0, 0); + } } -static wxColour wxColourFromSpec(const wxString& spec) { - // spec should be #RRGGBB - char* junk; - int red = strtol(spec.Mid(1,2), &junk, 16); - int green = strtol(spec.Mid(3,2), &junk, 16); - int blue = strtol(spec.Mid(5,2), &junk, 16); - return wxColour(red, green, blue); +// Set the horizontal scrollbar to use instead of the ont that's built-in. +void wxStyledTextCtrl::SetHScrollBar(wxScrollBar* bar) { + m_hScrollBar = bar; + if (bar != NULL) { + // ensure that the built-in scrollbar is not visible + SetScrollbar(wxHORIZONTAL, 0, 0, 0); + } } - //---------------------------------------------------------------------- -// BEGIN generated section. The following code is automatically generated -// by gen_iface.py from the contents of Scintilla.iface. Do not edit -// this file. Edit stc.cpp.in or gen_iface.py instead and regenerate. +// Generated methods implementation section {{{ %(METHOD_IMPS)s -// END of generated section +//}}} //---------------------------------------------------------------------- @@ -209,8 +271,8 @@ int wxStyledTextCtrl::GetCurrentLine() { // // bold turns on bold // italic turns on italics -// fore:#RRGGBB sets the foreground colour -// back:#RRGGBB sets the background colour +// fore:[name or #RRGGBB] sets the foreground colour +// back:[name or #RRGGBB] sets the background colour // face:[facename] sets the font face name to use // size:[num] sets the font size in points // eol turns on eol filling @@ -218,68 +280,199 @@ int wxStyledTextCtrl::GetCurrentLine() { // void wxStyledTextCtrl::StyleSetSpec(int styleNum, const wxString& spec) { - wxStringTokenizer tkz(spec, ","); + wxStringTokenizer tkz(spec, wxT(",")); while (tkz.HasMoreTokens()) { wxString token = tkz.GetNextToken(); wxString option = token.BeforeFirst(':'); wxString val = token.AfterFirst(':'); - if (option == "bold") + if (option == wxT("bold")) StyleSetBold(styleNum, true); - else if (option == "italic") + else if (option == wxT("italic")) StyleSetItalic(styleNum, true); - else if (option == "underline") + else if (option == wxT("underline")) StyleSetUnderline(styleNum, true); - else if (option == "eol") + else if (option == wxT("eol")) StyleSetEOLFilled(styleNum, true); - else if (option == "size") { + else if (option == wxT("size")) { long points; if (val.ToLong(&points)) StyleSetSize(styleNum, points); } - else if (option == "face") + else if (option == wxT("face")) StyleSetFaceName(styleNum, val); - else if (option == "fore") + else if (option == wxT("fore")) StyleSetForeground(styleNum, wxColourFromSpec(val)); - else if (option == "back") + else if (option == wxT("back")) StyleSetBackground(styleNum, wxColourFromSpec(val)); } } +// Get the font of a style +wxFont wxStyledTextCtrl::StyleGetFont(int style) { + wxFont font; + font.SetPointSize(StyleGetSize(style)); + font.SetFaceName(StyleGetFaceName(style)); + if( StyleGetBold(style) ) + font.SetWeight(wxFONTWEIGHT_BOLD); + else + font.SetWeight(wxFONTWEIGHT_NORMAL); + + if( StyleGetItalic(style) ) + font.SetStyle(wxFONTSTYLE_ITALIC); + else + font.SetStyle(wxFONTSTYLE_NORMAL); + + return font; +} + + // Set style size, face, bold, italic, and underline attributes from // a wxFont's attributes. void wxStyledTextCtrl::StyleSetFont(int styleNum, wxFont& font) { - int size = font.GetPointSize(); - wxString faceName = font.GetFaceName(); - bool bold = font.GetWeight() == wxBOLD; - bool italic = font.GetStyle() != wxNORMAL; - bool under = font.GetUnderlined(); - - // TODO: add encoding/charset mapping - StyleSetFontAttr(styleNum, size, faceName, bold, italic, under); +#ifdef __WXGTK__ + // Ensure that the native font is initialized + int x, y; + GetTextExtent(wxT("X"), &x, &y, NULL, NULL, &font); +#endif + int size = font.GetPointSize(); + wxString faceName = font.GetFaceName(); + bool bold = font.GetWeight() == wxBOLD; + bool italic = font.GetStyle() != wxNORMAL; + bool under = font.GetUnderlined(); + wxFontEncoding encoding = font.GetEncoding(); + + StyleSetFontAttr(styleNum, size, faceName, bold, italic, under, encoding); } // Set all font style attributes at once. void wxStyledTextCtrl::StyleSetFontAttr(int styleNum, int size, const wxString& faceName, bool bold, bool italic, - bool underline) { + bool underline, + wxFontEncoding encoding) { StyleSetSize(styleNum, size); StyleSetFaceName(styleNum, faceName); StyleSetBold(styleNum, bold); StyleSetItalic(styleNum, italic); StyleSetUnderline(styleNum, underline); + StyleSetFontEncoding(styleNum, encoding); +} + - // TODO: add encoding/charset mapping +// Set the character set of the font in a style. Converts the Scintilla +// character set values to a wxFontEncoding. +void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet) +{ + wxFontEncoding encoding; + + // Translate the Scintilla characterSet to a wxFontEncoding + switch (characterSet) { + default: + case wxSTC_CHARSET_ANSI: + case wxSTC_CHARSET_DEFAULT: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_BALTIC: + encoding = wxFONTENCODING_ISO8859_13; + break; + + case wxSTC_CHARSET_CHINESEBIG5: + encoding = wxFONTENCODING_CP950; + break; + + case wxSTC_CHARSET_EASTEUROPE: + encoding = wxFONTENCODING_ISO8859_2; + break; + + case wxSTC_CHARSET_GB2312: + encoding = wxFONTENCODING_CP936; + break; + + case wxSTC_CHARSET_GREEK: + encoding = wxFONTENCODING_ISO8859_7; + break; + + case wxSTC_CHARSET_HANGUL: + encoding = wxFONTENCODING_CP949; + break; + + case wxSTC_CHARSET_MAC: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_OEM: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_RUSSIAN: + encoding = wxFONTENCODING_KOI8; + break; + + case wxSTC_CHARSET_SHIFTJIS: + encoding = wxFONTENCODING_CP932; + break; + + case wxSTC_CHARSET_SYMBOL: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_TURKISH: + encoding = wxFONTENCODING_ISO8859_9; + break; + + case wxSTC_CHARSET_JOHAB: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_HEBREW: + encoding = wxFONTENCODING_ISO8859_8; + break; + + case wxSTC_CHARSET_ARABIC: + encoding = wxFONTENCODING_ISO8859_6; + break; + + case wxSTC_CHARSET_VIETNAMESE: + encoding = wxFONTENCODING_DEFAULT; + break; + + case wxSTC_CHARSET_THAI: + encoding = wxFONTENCODING_ISO8859_11; + break; + + case wxSTC_CHARSET_CYRILLIC: + encoding = wxFONTENCODING_ISO8859_5; + break; + + case wxSTC_CHARSET_8859_15: + encoding = wxFONTENCODING_ISO8859_15;; + break; + } + + // We just have Scintilla track the wxFontEncoding for us. It gets used + // in Font::Create in PlatWX.cpp. We add one to the value so that the + // effective wxFONENCODING_DEFAULT == SC_SHARSET_DEFAULT and so when + // Scintilla internally uses SC_CHARSET_DEFAULT we will translate it back + // to wxFONENCODING_DEFAULT in Font::Create. + SendMsg(SCI_STYLESETCHARACTERSET, style, encoding+1); +} + + +// Set the font encoding to be used by a style. +void wxStyledTextCtrl::StyleSetFontEncoding(int style, wxFontEncoding encoding) +{ + SendMsg(SCI_STYLESETCHARACTERSET, style, encoding+1); } @@ -296,15 +489,6 @@ void wxStyledTextCtrl::SetMargins(int left, int right) { } -// Retrieve the start and end positions of the current selection. -void wxStyledTextCtrl::GetSelection(int* startPos, int* endPos) { - if (startPos != NULL) - *startPos = SendMsg(SCI_GETSELECTIONSTART); - if (endPos != NULL) - *endPos = SendMsg(SCI_GETSELECTIONEND); -} - - // Retrieve the point in the window where a position is displayed. wxPoint wxStyledTextCtrl::PointFromPosition(int pos) { int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos); @@ -324,15 +508,204 @@ void wxStyledTextCtrl::ScrollToColumn(int column) { } +#if wxUSE_TEXTCTRL +bool wxStyledTextCtrl::DoSaveFile(const wxString& filename, int WXUNUSED(fileType)) +#else +bool wxStyledTextCtrl::SaveFile(const wxString& filename) +#endif +{ + wxFile file(filename, wxFile::write); + + if (!file.IsOpened()) + return false; + + bool success = file.Write(GetText(), *wxConvCurrent); + + if (success) + SetSavePoint(); + + return success; +} + +#if wxUSE_TEXTCTRL +bool wxStyledTextCtrl::DoLoadFile(const wxString& filename, int WXUNUSED(fileType)) +#else +bool wxStyledTextCtrl::LoadFile(const wxString& filename) +#endif +{ + bool success = false; + wxFile file(filename, wxFile::read); + + if (file.IsOpened()) + { + wxString contents; + // get the file size (assume it is not huge file...) + ssize_t len = (ssize_t)file.Length(); + + if (len > 0) + { +#if wxUSE_UNICODE + wxMemoryBuffer buffer(len+1); + success = (file.Read(buffer.GetData(), len) == len); + if (success) { + ((char*)buffer.GetData())[len] = 0; + contents = wxString(buffer, *wxConvCurrent, len); + } +#else + wxString buffer; + success = (file.Read(wxStringBuffer(buffer, len), len) == len); + contents = buffer; +#endif + } + else + { + if (len == 0) + success = true; // empty file is ok + else + success = false; // len == wxInvalidOffset + } + + if (success) + { + SetText(contents); + EmptyUndoBuffer(); + SetSavePoint(); + } + } + + return success; +} + + +#if wxUSE_DRAG_AND_DROP +wxDragResult wxStyledTextCtrl::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) { + return m_swx->DoDragOver(x, y, def); +} + + +bool wxStyledTextCtrl::DoDropText(long x, long y, const wxString& data) { + return m_swx->DoDropText(x, y, data); +} +#endif + + +void wxStyledTextCtrl::SetUseAntiAliasing(bool useAA) { + m_swx->SetUseAntiAliasing(useAA); +} + +bool wxStyledTextCtrl::GetUseAntiAliasing() { + return m_swx->GetUseAntiAliasing(); +} + + + + + +void wxStyledTextCtrl::AddTextRaw(const char* text) +{ + SendMsg(SCI_ADDTEXT, strlen(text), (sptr_t)text); +} + +void wxStyledTextCtrl::InsertTextRaw(int pos, const char* text) +{ + SendMsg(SCI_INSERTTEXT, pos, (sptr_t)text); +} + +wxCharBuffer wxStyledTextCtrl::GetCurLineRaw(int* linePos) +{ + int len = LineLength(GetCurrentLine()); + if (!len) { + if (linePos) *linePos = 0; + wxCharBuffer empty; + return empty; + } + + wxCharBuffer buf(len); + int pos = SendMsg(SCI_GETCURLINE, len, (sptr_t)buf.data()); + if (linePos) *linePos = pos; + return buf; +} + +wxCharBuffer wxStyledTextCtrl::GetLineRaw(int line) +{ + int len = LineLength(line); + if (!len) { + wxCharBuffer empty; + return empty; + } + + wxCharBuffer buf(len); + SendMsg(SCI_GETLINE, line, (sptr_t)buf.data()); + return buf; +} + +wxCharBuffer wxStyledTextCtrl::GetSelectedTextRaw() +{ + long start; + long end; + + GetSelection(&start, &end); + int len = end - start; + if (!len) { + wxCharBuffer empty; + return empty; + } + + wxCharBuffer buf(len); + SendMsg(SCI_GETSELTEXT, 0, (sptr_t)buf.data()); + return buf; +} + +wxCharBuffer wxStyledTextCtrl::GetTextRangeRaw(int startPos, int endPos) +{ + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + int len = endPos - startPos; + if (!len) { + wxCharBuffer empty; + return empty; + } + + wxCharBuffer buf(len); + TextRange tr; + tr.lpstrText = buf.data(); + tr.chrg.cpMin = startPos; + tr.chrg.cpMax = endPos; + SendMsg(SCI_GETTEXTRANGE, 0, (sptr_t)&tr); + return buf; +} + +void wxStyledTextCtrl::SetTextRaw(const char* text) +{ + SendMsg(SCI_SETTEXT, 0, (sptr_t)text); +} + +wxCharBuffer wxStyledTextCtrl::GetTextRaw() +{ + int len = GetTextLength(); + wxCharBuffer buf(len); // adds 1 for NUL automatically + SendMsg(SCI_GETTEXT, len + 1, (sptr_t)buf.data()); + return buf; +} + +void wxStyledTextCtrl::AppendTextRaw(const char* text) +{ + SendMsg(SCI_APPENDTEXT, strlen(text), (sptr_t)text); +} + + + + //---------------------------------------------------------------------- // Event handlers -void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) { +void wxStyledTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(evt)) { wxPaintDC dc(this); - wxRegion region = GetUpdateRegion(); - - m_swx->DoPaint(&dc, region.GetBox()); + m_swx->DoPaint(&dc, GetUpdateRegion().GetBox()); } void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) { @@ -342,80 +715,141 @@ void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) { m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition()); } -void wxStyledTextCtrl::OnSize(wxSizeEvent& evt) { - wxSize sz = GetClientSize(); - m_swx->DoSize(sz.x, sz.y); +void wxStyledTextCtrl::OnScroll(wxScrollEvent& evt) { + wxScrollBar* sb = wxDynamicCast(evt.GetEventObject(), wxScrollBar); + if (sb) { + if (sb->IsVertical()) + m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition()); + else + m_swx->DoHScroll(evt.GetEventType(), evt.GetPosition()); + } +} + +void wxStyledTextCtrl::OnSize(wxSizeEvent& WXUNUSED(evt)) { + if (m_swx) { + wxSize sz = GetClientSize(); + m_swx->DoSize(sz.x, sz.y); + } } void wxStyledTextCtrl::OnMouseLeftDown(wxMouseEvent& evt) { + SetFocus(); wxPoint pt = evt.GetPosition(); - m_swx->DoButtonDown(Point(pt.x, pt.y), m_stopWatch.Time(), + m_swx->DoLeftButtonDown(Point(pt.x, pt.y), m_stopWatch.Time(), evt.ShiftDown(), evt.ControlDown(), evt.AltDown()); } void wxStyledTextCtrl::OnMouseMove(wxMouseEvent& evt) { wxPoint pt = evt.GetPosition(); - m_swx->DoButtonMove(Point(pt.x, pt.y)); + m_swx->DoLeftButtonMove(Point(pt.x, pt.y)); } void wxStyledTextCtrl::OnMouseLeftUp(wxMouseEvent& evt) { wxPoint pt = evt.GetPosition(); - m_swx->DoButtonUp(Point(pt.x, pt.y), m_stopWatch.Time(), + m_swx->DoLeftButtonUp(Point(pt.x, pt.y), m_stopWatch.Time(), evt.ControlDown()); } -void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) { +void wxStyledTextCtrl::OnMouseRightUp(wxMouseEvent& evt) { wxPoint pt = evt.GetPosition(); - ScreenToClient(&pt.x, &pt.y); m_swx->DoContextMenu(Point(pt.x, pt.y)); } -void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt) { - m_swx->DoMouseWheel(evt.GetWheelRotation(), - evt.GetWheelDelta(), - evt.GetLinesPerAction(), - evt.ControlDown()); +void wxStyledTextCtrl::OnMouseMiddleUp(wxMouseEvent& evt) { + wxPoint pt = evt.GetPosition(); + m_swx->DoMiddleButtonUp(Point(pt.x, pt.y)); } +void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) { + wxPoint pt = evt.GetPosition(); + ScreenToClient(&pt.x, &pt.y); + /* + Show context menu at event point if it's within the window, + or at caret location if not + */ + wxHitTest ht = this->HitTest(pt); + if (ht != wxHT_WINDOW_INSIDE) { + pt = this->PointFromPosition(this->GetCurrentPos()); + } + m_swx->DoContextMenu(Point(pt.x, pt.y)); +} -void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) { - long key = evt.KeyCode(); -// printf("OnChar key:%%d consumed:%%d ctrl:%%d alt:%%d\n", -// key, m_lastKeyDownConsumed, evt.ControlDown(), evt.AltDown()); +void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt) +{ + // prevent having an event queue with wheel events that cannot be processed + // reasonably fast (see ticket #9057) + if ( m_lastWheelTimestamp <= evt.GetTimestamp() ) + { + m_lastWheelTimestamp = m_stopWatch.Time(); + m_swx->DoMouseWheel(evt.GetWheelRotation(), + evt.GetWheelDelta(), + evt.GetLinesPerAction(), + evt.ControlDown(), + evt.IsPageScroll()); + m_lastWheelTimestamp = m_stopWatch.Time() - m_lastWheelTimestamp; + m_lastWheelTimestamp += evt.GetTimestamp(); + } +} - // AltGr keys??? - // \|@#¬[]{}?£$~ ã,õ,Ã,Õ, ñ, Ñ - // On (some?) non-US keyboards the AltGr key is required to enter some +void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) { + // On (some?) non-US PC keyboards the AltGr key is required to enter some // common characters. It comes to us as both Alt and Ctrl down so we need // to let the char through in that case, otherwise if only ctrl or only // alt let's skip it. bool ctrl = evt.ControlDown(); +#ifdef __WXMAC__ + // On the Mac the Alt key is just a modifier key (like Shift) so we need + // to allow the char events to be processed when Alt is pressed. + // TODO: Should we check MetaDown instead in this case? + bool alt = false; +#else bool alt = evt.AltDown(); - bool skip = (ctrl || alt && ! (ctrl && alt)); +#endif + bool skip = ((ctrl || alt) && ! (ctrl && alt)); - if (key <= 0xff && !iscntrl(key) && !m_lastKeyDownConsumed && !skip) { - m_swx->DoAddChar(key); - return; +#if wxUSE_UNICODE + // apparently if we don't do this, Unicode keys pressed after non-char + // ASCII ones (e.g. Enter, Tab) are not taken into account (patch 1615989) + if (m_lastKeyDownConsumed && evt.GetUnicodeKey() > 255) + m_lastKeyDownConsumed = false; +#endif + + if (!m_lastKeyDownConsumed && !skip) { +#if wxUSE_UNICODE + int key = evt.GetUnicodeKey(); + bool keyOk = true; + + // if the unicode key code is not really a unicode character (it may + // be a function key or etc., the platforms appear to always give us a + // small value in this case) then fallback to the ascii key code but + // don't do anything for function keys or etc. + if (key <= 127) { + key = evt.GetKeyCode(); + keyOk = (key <= 127); + } + if (keyOk) { + m_swx->DoAddChar(key); + return; + } +#else + int key = evt.GetKeyCode(); + if (key <= WXK_START || key > WXK_COMMAND) { + m_swx->DoAddChar(key); + return; + } +#endif } + evt.Skip(); } void wxStyledTextCtrl::OnKeyDown(wxKeyEvent& evt) { - long key = evt.KeyCode(); - bool shift = evt.ShiftDown(), - ctrl = evt.ControlDown(), - alt = evt.AltDown(); - - int processed = m_swx->DoKeyDown(key, shift, ctrl, alt, &m_lastKeyDownConsumed); - -// printf("key: %%d shift: %%d ctrl: %%d alt: %%d processed: %%d consumed: %%d\n", -// key, shift, ctrl, alt, processed, m_lastKeyDownConsumed); - + int processed = m_swx->DoKeyDown(evt, &m_lastKeyDownConsumed); if (!processed && !m_lastKeyDownConsumed) evt.Skip(); } @@ -423,20 +857,22 @@ void wxStyledTextCtrl::OnKeyDown(wxKeyEvent& evt) { void wxStyledTextCtrl::OnLoseFocus(wxFocusEvent& evt) { m_swx->DoLoseFocus(); + evt.Skip(); } void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) { m_swx->DoGainFocus(); + evt.Skip(); } -void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& evt) { +void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) { m_swx->DoSysColourChange(); } -void wxStyledTextCtrl::OnEraseBackground(wxEraseEvent& evt) { +void wxStyledTextCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) { // do nothing to help avoid flashing } @@ -447,24 +883,48 @@ void wxStyledTextCtrl::OnMenu(wxCommandEvent& evt) { } -void wxStyledTextCtrl::OnListBox(wxCommandEvent& evt) { +void wxStyledTextCtrl::OnListBox(wxCommandEvent& WXUNUSED(evt)) { m_swx->DoOnListBox(); } +void wxStyledTextCtrl::OnIdle(wxIdleEvent& evt) { + m_swx->DoOnIdle(evt); +} + + +wxSize wxStyledTextCtrl::DoGetBestSize() const +{ + // What would be the best size for a wxSTC? + // Just give a reasonable minimum until something else can be figured out. + return wxSize(200,100); +} + + //---------------------------------------------------------------------- // Turn notifications from Scintilla into events void wxStyledTextCtrl::NotifyChange() { wxStyledTextEvent evt(wxEVT_STC_CHANGE, GetId()); + evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); } + +static void SetEventText(wxStyledTextEvent& evt, const char* text, + size_t length) { + if(!text) return; + + evt.SetText(stc2wx(text, length)); +} + + void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { SCNotification& scn = *_scn; wxStyledTextEvent evt(0, GetId()); + evt.SetEventObject(this); evt.SetPosition(scn.position); evt.SetKey(scn.ch); evt.SetModifiers(scn.modifiers); @@ -505,8 +965,7 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { case SCN_MODIFIED: evt.SetEventType(wxEVT_STC_MODIFIED); evt.SetModificationType(scn.modificationType); - if (scn.text) - evt.SetText(wxString(scn.text, scn.length)); + SetEventText(evt, scn.text, scn.length); evt.SetLength(scn.length); evt.SetLinesAdded(scn.linesAdded); evt.SetLine(scn.line); @@ -531,23 +990,27 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetLength(scn.length); break; - case SCN_POSCHANGED: - evt.SetEventType(wxEVT_STC_POSCHANGED); - break; - case SCN_PAINTED: evt.SetEventType(wxEVT_STC_PAINTED); break; + case SCN_AUTOCSELECTION: + evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION); + evt.SetListType(scn.listType); + SetEventText(evt, scn.text, strlen(scn.text)); + evt.SetPosition(scn.lParam); + break; + case SCN_USERLISTSELECTION: evt.SetEventType(wxEVT_STC_USERLISTSELECTION); evt.SetListType(scn.listType); - evt.SetText(scn.text); + SetEventText(evt, scn.text, strlen(scn.text)); + evt.SetPosition(scn.lParam); break; case SCN_URIDROPPED: evt.SetEventType(wxEVT_STC_URIDROPPED); - evt.SetText(scn.text); + SetEventText(evt, scn.text, strlen(scn.text)); break; case SCN_DWELLSTART: @@ -562,6 +1025,30 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetY(scn.y); break; + case SCN_ZOOM: + evt.SetEventType(wxEVT_STC_ZOOM); + break; + + case SCN_HOTSPOTCLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK); + break; + + case SCN_HOTSPOTDOUBLECLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK); + break; + + case SCN_CALLTIPCLICK: + evt.SetEventType(wxEVT_STC_CALLTIP_CLICK); + break; + + case SCN_INDICATORCLICK: + evt.SetEventType(wxEVT_STC_INDICATOR_CLICK); + break; + + case SCN_INDICATORRELEASE: + evt.SetEventType(wxEVT_STC_INDICATOR_RELEASE); + break; + default: return; } @@ -570,7 +1057,6 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { } - //---------------------------------------------------------------------- //---------------------------------------------------------------------- //---------------------------------------------------------------------- @@ -594,39 +1080,49 @@ wxStyledTextEvent::wxStyledTextEvent(wxEventType commandType, int id) m_listType = 0; m_x = 0; m_y = 0; + m_dragAllowMove = false; +#if wxUSE_DRAG_AND_DROP + m_dragResult = wxDragNone; +#endif } bool wxStyledTextEvent::GetShift() const { return (m_modifiers & SCI_SHIFT) != 0; } bool wxStyledTextEvent::GetControl() const { return (m_modifiers & SCI_CTRL) != 0; } bool wxStyledTextEvent::GetAlt() const { return (m_modifiers & SCI_ALT) != 0; } -void wxStyledTextEvent::CopyObject(wxObject& obj) const { - wxCommandEvent::CopyObject(obj); - - wxStyledTextEvent* o = (wxStyledTextEvent*)&obj; - o->m_position = m_position; - o->m_key = m_key; - o->m_modifiers = m_modifiers; - o->m_modificationType = m_modificationType; - o->m_text = m_text; - o->m_length = m_length; - o->m_linesAdded = m_linesAdded; - o->m_line = m_line; - o->m_foldLevelNow = m_foldLevelNow; - o->m_foldLevelPrev = m_foldLevelPrev; - - o->m_margin = m_margin; - - o->m_message = m_message; - o->m_wParam = m_wParam; - o->m_lParam = m_lParam; - - o->m_listType = m_listType; - o->m_x = m_x; - o->m_y = m_y; +wxStyledTextEvent::wxStyledTextEvent(const wxStyledTextEvent& event): + wxCommandEvent(event) +{ + m_position = event.m_position; + m_key = event.m_key; + m_modifiers = event.m_modifiers; + m_modificationType = event.m_modificationType; + m_text = event.m_text; + m_length = event.m_length; + m_linesAdded = event.m_linesAdded; + m_line = event.m_line; + m_foldLevelNow = event.m_foldLevelNow; + m_foldLevelPrev = event.m_foldLevelPrev; + + m_margin = event.m_margin; + + m_message = event.m_message; + m_wParam = event.m_wParam; + m_lParam = event.m_lParam; + + m_listType = event.m_listType; + m_x = event.m_x; + m_y = event.m_y; + + m_dragText = event.m_dragText; + m_dragAllowMove =event.m_dragAllowMove; +#if wxUSE_DRAG_AND_DROP + m_dragResult = event.m_dragResult; +#endif } //---------------------------------------------------------------------- //---------------------------------------------------------------------- +#endif // wxUSE_STC