diff --git a/contrib/include/wx/stc/stc.h b/contrib/include/wx/stc/stc.h index 096949085a..2ff4a98905 100644 --- a/contrib/include/wx/stc/stc.h +++ b/contrib/include/wx/stc/stc.h @@ -77,6 +77,9 @@ // The SC_CP_UTF8 value can be used to enter Unicode mode. // This is the same value as CP_UTF8 in Windows #define wxSTC_CP_UTF8 65001 + +// The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+. +#define wxSTC_CP_DBCS 1 #define wxSTC_MARKER_MAX 31 #define wxSTC_MARK_CIRCLE 0 #define wxSTC_MARK_ROUNDRECT 1 @@ -107,6 +110,7 @@ #define wxSTC_MARK_BACKGROUND 22 #define wxSTC_MARK_DOTDOTDOT 23 #define wxSTC_MARK_ARROWS 24 +#define wxSTC_MARK_PIXMAP 25 #define wxSTC_MARK_CHARACTER 10000 // Markers used for outlining column. @@ -188,7 +192,17 @@ #define wxSTC_FOLDLEVELBASE 0x400 #define wxSTC_FOLDLEVELWHITEFLAG 0x1000 #define wxSTC_FOLDLEVELHEADERFLAG 0x2000 +#define wxSTC_FOLDLEVELBOXHEADERFLAG 0x4000 +#define wxSTC_FOLDLEVELBOXFOOTERFLAG 0x8000 +#define wxSTC_FOLDLEVELCONTRACTED 0x10000 +#define wxSTC_FOLDLEVELUNINDENT 0x20000 #define wxSTC_FOLDLEVELNUMBERMASK 0x0FFF +#define wxSTC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 +#define wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 +#define wxSTC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 +#define wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010 +#define wxSTC_FOLDFLAG_LEVELNUMBERS 0x0040 +#define wxSTC_FOLDFLAG_BOX 0x0001 #define wxSTC_TIME_FOREVER 10000000 #define wxSTC_WRAP_NONE 0 #define wxSTC_WRAP_WORD 1 @@ -200,7 +214,7 @@ #define wxSTC_EDGE_LINE 1 #define wxSTC_EDGE_BACKGROUND 2 #define wxSTC_CURSORNORMAL -1 -#define wxSTC_CURSORWAIT 3 +#define wxSTC_CURSORWAIT 4 // Constants for use with SetVisiblePolicy, similar to SetCaretPolicy. #define wxSTC_VISIBLE_SLOP 0x01 @@ -308,6 +322,11 @@ #define wxSTC_LEX_BAAN 31 #define wxSTC_LEX_MATLAB 32 #define wxSTC_LEX_SCRIPTOL 33 +#define wxSTC_LEX_ASM 34 +#define wxSTC_LEX_CPPNOCASE 35 +#define wxSTC_LEX_FORTRAN 36 +#define wxSTC_LEX_F77 37 +#define wxSTC_LEX_CSS 38 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a // value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -576,6 +595,7 @@ #define wxSTC_ERR_DIFF_ADDITION 11 #define wxSTC_ERR_DIFF_DELETION 12 #define wxSTC_ERR_DIFF_MESSAGE 13 +#define wxSTC_ERR_PHP 14 // Lexical states for SCLEX_BATCH #define wxSTC_BAT_DEFAULT 0 @@ -622,24 +642,31 @@ #define wxSTC_AVE_COMMENT 1 #define wxSTC_AVE_NUMBER 2 #define wxSTC_AVE_WORD 3 -#define wxSTC_AVE_KEYWORD 4 -#define wxSTC_AVE_STATEMENT 5 #define wxSTC_AVE_STRING 6 #define wxSTC_AVE_ENUM 7 #define wxSTC_AVE_STRINGEOL 8 #define wxSTC_AVE_IDENTIFIER 9 #define wxSTC_AVE_OPERATOR 10 +#define wxSTC_AVE_WORD1 11 +#define wxSTC_AVE_WORD2 12 +#define wxSTC_AVE_WORD3 13 +#define wxSTC_AVE_WORD4 14 +#define wxSTC_AVE_WORD5 15 +#define wxSTC_AVE_WORD6 16 // Lexical states for SCLEX_ADA #define wxSTC_ADA_DEFAULT 0 -#define wxSTC_ADA_COMMENT 1 -#define wxSTC_ADA_NUMBER 2 -#define wxSTC_ADA_WORD 3 -#define wxSTC_ADA_STRING 4 +#define wxSTC_ADA_WORD 1 +#define wxSTC_ADA_IDENTIFIER 2 +#define wxSTC_ADA_NUMBER 3 +#define wxSTC_ADA_DELIMITER 4 #define wxSTC_ADA_CHARACTER 5 -#define wxSTC_ADA_OPERATOR 6 -#define wxSTC_ADA_IDENTIFIER 7 +#define wxSTC_ADA_CHARACTEREOL 6 +#define wxSTC_ADA_STRING 7 #define wxSTC_ADA_STRINGEOL 8 +#define wxSTC_ADA_LABEL 9 +#define wxSTC_ADA_COMMENTLINE 10 +#define wxSTC_ADA_ILLEGAL 11 // Lexical states for SCLEX_BAAN #define wxSTC_BAAN_DEFAULT 0 @@ -720,6 +747,51 @@ #define wxSTC_SCRIPTOL_COMMENTDOCKEYWORDERROR 18 #define wxSTC_SCRIPTOL_COMMENTBASIC 19 +// Lexical states for SCLEX_ASM +#define wxSTC_ASM_DEFAULT 0 +#define wxSTC_ASM_COMMENT 1 +#define wxSTC_ASM_NUMBER 2 +#define wxSTC_ASM_STRING 3 +#define wxSTC_ASM_OPERATOR 4 +#define wxSTC_ASM_IDENTIFIER 5 +#define wxSTC_ASM_CPUINSTRUCTION 6 +#define wxSTC_ASM_MATHINSTRUCTION 7 +#define wxSTC_ASM_REGISTER 8 +#define wxSTC_ASM_DIRECTIVE 9 +#define wxSTC_ASM_DIRECTIVEOPERAND 10 + +// Lexical states for SCLEX_FORTRAN +#define wxSTC_F_DEFAULT 0 +#define wxSTC_F_COMMENT 1 +#define wxSTC_F_NUMBER 2 +#define wxSTC_F_STRING1 3 +#define wxSTC_F_STRING2 4 +#define wxSTC_F_STRINGEOL 5 +#define wxSTC_F_OPERATOR 6 +#define wxSTC_F_IDENTIFIER 7 +#define wxSTC_F_WORD 8 +#define wxSTC_F_WORD2 9 +#define wxSTC_F_WORD3 10 +#define wxSTC_F_PREPROCESSOR 11 +#define wxSTC_F_OPERATOR2 12 +#define wxSTC_F_LABEL 13 +#define wxSTC_F_CONTINUATION 14 + +// Lexical states for SCLEX_CSS +#define wxSTC_CSS_DEFAULT 0 +#define wxSTC_CSS_TAG 1 +#define wxSTC_CSS_CLASS 2 +#define wxSTC_CSS_PSEUDOCLASS 3 +#define wxSTC_CSS_UNKNOWN_PSEUDOCLASS 4 +#define wxSTC_CSS_OPERATOR 5 +#define wxSTC_CSS_IDENTIFIER 6 +#define wxSTC_CSS_UNKNOWN_IDENTIFIER 7 +#define wxSTC_CSS_VALUE 8 +#define wxSTC_CSS_COMMENT 9 +#define wxSTC_CSS_ID 10 +#define wxSTC_CSS_IMPORTANT 11 +#define wxSTC_CSS_DIRECTIVE 12 + //----------------------------------------- // Commands that can be bound to keystrokes @@ -867,6 +939,9 @@ // Switch the current line with the previous. #define wxSTC_CMD_LINETRANSPOSE 2339 +// Duplicate the current line. +#define wxSTC_CMD_LINEDUPLICATE 2404 + // Transform the selection to lower case. #define wxSTC_CMD_LOWERCASE 2340 @@ -1091,8 +1166,8 @@ public: // Set the symbol used for a particular marker number, // and optionally the fore and background colours. void MarkerDefine(int markerNumber, int markerSymbol, - const wxColour& foreground = wxNullColour, - const wxColour& background = wxNullColour); + const wxColour& foreground = wxNullColour, + const wxColour& background = wxNullColour); // Set the foreground colour used for a particular marker number. void MarkerSetForeground(int markerNumber, const wxColour& fore); @@ -1118,6 +1193,9 @@ public: // Find the previous line before lineStart that includes a marker in mask. int MarkerPrevious(int lineStart, int markerMask); + // Define a marker from a bitmap + void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp); + // Set a margin to be either numeric or symbolic. void SetMarginType(int margin, int marginType); @@ -1339,6 +1417,19 @@ public: // after the inserted text upon completion. bool AutoCompGetDropRestOfWord(); + // Register an image for use in autocompletion lists. + void RegisterImage(int type, const wxBitmap& bmp); + + // Clear all the registered images. + void ClearRegisteredImages(); + + // Retrieve the auto-completion list type-separator character. + int AutoCompGetTypeSeparator(); + + // Change the type-separator character in the string setting up an auto-completion list. + // Default is '?' but can be changed if items contain '?'. + void AutoCompSetTypeSeparator(int separatorCharacter); + // Set the number of spaces used for one level of indentation. void SetIndent(int indentSize); @@ -1427,14 +1518,14 @@ public: // On Windows, will draw the document into a display context such as a printer. int FormatRange(bool doDraw, - int startPos, - int endPos, - wxDC* draw, - wxDC* target, // Why does it use two? Can they be the same? - wxRect renderRect, - wxRect pageRect); + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect); - // Retrieve the line at the top of the display. + // Retrieve the display line at the top of the display. int GetFirstVisibleLine(); // Retrieve the contents of a line. @@ -1630,7 +1721,7 @@ public: // Ensure a particular line is visible by expanding any header line hiding it. void EnsureVisible(int line); - // Set some debugging options for folding. + // Set some style options for folding. void SetFoldFlags(int flags); // Ensure a particular line is visible by expanding any header line hiding it. @@ -1696,6 +1787,40 @@ public: // Retrieve the height of a particular line of text in pixels. int TextHeight(int line); + // Show or hide the vertical scroll bar. + void SetUseVerticalScrollBar(bool show); + + // Is the vertical scroll bar visible? + bool GetUseVerticalScrollBar(); + + // Append a string to the end of the document without changing the selection. + void AppendText(int length, const wxString& text); + + // Is drawing done in two phases with backgrounds drawn before foregrounds? + bool GetTwoPhaseDraw(); + + // In twoPhaseDraw mode, drawing is performed in two phases, first the background + // and then the foreground. This avoids chopping off characters that overlap the next run. + void SetTwoPhaseDraw(bool twoPhase); + + // Make the target range start and end be the same as the selection range start and end. + void TargetFromSelection(); + + // Join the lines in the target. + // This is an experimental feature and may be changed or removed. + void LinesJoin(); + + // Split the lines in the target into lines that are less wide than pixelWidth + // where possible. + void LinesSplit(int pixelWidth); + + // Set the colours used as a chequerboard pattern in the fold margin + void SetFoldMarginColour(bool useSetting, const wxColour& back); + void SetFoldMarginHiColour(bool useSetting, const wxColour& fore); + + // Duplicate the current line. + void LineDuplicate(); + // Move caret to first position on display line. void HomeDisplay(); @@ -1860,6 +1985,9 @@ public: void SetXOffset(int newOffset); int GetXOffset(); + // Set the last x chosen value to be the caret x position + void ChooseCaretX(); + // Set the way the caret is kept visible when going sideway. // The exclusion zone is given in pixels. void SetXCaretPolicy(int caretPolicy, int caretSlop); @@ -1868,6 +1996,12 @@ public: // The exclusion zone is given in lines. void SetYCaretPolicy(int caretPolicy, int caretSlop); + // Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE). + void SetPrintWrapMode(int mode); + + // Is printing line wrapped. + int GetPrintWrapMode(); + // Start notifying the container of all key presses and commands. void StartRecord(); diff --git a/contrib/src/stc/Makefile.in b/contrib/src/stc/Makefile.in index 042da17f87..8ae30ee15c 100644 --- a/contrib/src/stc/Makefile.in +++ b/contrib/src/stc/Makefile.in @@ -34,14 +34,17 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ KeyMap.o \ KeyWords.o \ LexAVE.o \ + LexAda.o \ + LexAsm.o \ LexBaan.o \ LexBullant.o \ LexMatlab.o \ - LexAda.o \ LexCPP.o \ LexConf.o \ LexCrontab.o \ + LexCSS.o \ LexEiffel.o \ + LexFortran.o \ LexHTML.o \ LexLisp.o \ LexLua.o \ @@ -61,6 +64,8 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ UniConversion.o \ ViewStyle.o \ WindowAccessor.o \ + XPM.o \ + DEPFILES=$(OBJECTS:.o=.d) diff --git a/contrib/src/stc/PlatWX.cpp b/contrib/src/stc/PlatWX.cpp index d80aef709f..a9a1d2b444 100644 --- a/contrib/src/stc/PlatWX.cpp +++ b/contrib/src/stc/PlatWX.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include "Platform.h" @@ -213,42 +215,44 @@ public: SurfaceImpl(); ~SurfaceImpl(); - void Init(); - void Init(SurfaceID sid); - void InitPixMap(int width, int height, Surface *surface_); + virtual void Init(); + virtual void Init(SurfaceID sid); + virtual void InitPixMap(int width, int height, Surface *surface_); - void Release(); - bool Initialised(); - void PenColour(ColourAllocated fore); - int LogPixelsY(); - int DeviceHeightFont(int points); - void MoveTo(int x_, int y_); - void LineTo(int x_, int y_); - void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); - void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void FillRectangle(PRectangle rc, ColourAllocated back); - void FillRectangle(PRectangle rc, Surface &surfacePattern); - void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void Copy(PRectangle rc, Point from, Surface &surfaceSource); + virtual void Release(); + virtual bool Initialised(); + virtual void PenColour(ColourAllocated fore); + virtual int LogPixelsY(); + virtual int DeviceHeightFont(int points); + virtual void MoveTo(int x_, int y_); + virtual void LineTo(int x_, int y_); + virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); + virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); + virtual void FillRectangle(PRectangle rc, ColourAllocated back); + virtual void FillRectangle(PRectangle rc, Surface &surfacePattern); + virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); + virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource); - void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); - void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); - void MeasureWidths(Font &font_, const char *s, int len, int *positions); - int WidthText(Font &font_, const char *s, int len); - int WidthChar(Font &font_, char ch); - int Ascent(Font &font_); - int Descent(Font &font_); - int InternalLeading(Font &font_); - int ExternalLeading(Font &font_); - int Height(Font &font_); - int AverageCharWidth(Font &font_); + virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore); + virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions); + virtual int WidthText(Font &font_, const char *s, int len); + virtual int WidthChar(Font &font_, char ch); + virtual int Ascent(Font &font_); + virtual int Descent(Font &font_); + virtual int InternalLeading(Font &font_); + virtual int ExternalLeading(Font &font_); + virtual int Height(Font &font_); + virtual int AverageCharWidth(Font &font_); - int SetPalette(Palette *pal, bool inBackGround); - void SetClip(PRectangle rc); - void FlushCachedState(); + virtual int SetPalette(Palette *pal, bool inBackGround); + virtual void SetClip(PRectangle rc); + virtual void FlushCachedState(); - void SetUnicodeMode(bool unicodeMode_); + virtual void SetUnicodeMode(bool unicodeMode_); + virtual void SetDBCSMode(int codePage); void BrushColour(ColourAllocated back); void SetFont(Font &font_); @@ -265,24 +269,6 @@ SurfaceImpl::~SurfaceImpl() { Release(); } -void SurfaceImpl::Release() { - if (bitmap) { - ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap); - delete bitmap; - bitmap = 0; - } - if (hdcOwned) { - delete hdc; - hdc = 0; - hdcOwned = false; - } -} - - -bool SurfaceImpl::Initialised() { - return hdc != 0; -} - void SurfaceImpl::Init() { #if 0 Release(); @@ -311,6 +297,26 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) { ((wxMemoryDC*)hdc)->SelectObject(*bitmap); } + +void SurfaceImpl::Release() { + if (bitmap) { + ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap); + delete bitmap; + bitmap = 0; + } + if (hdcOwned) { + delete hdc; + hdc = 0; + hdcOwned = false; + } +} + + +bool SurfaceImpl::Initialised() { + return hdc != 0; +} + + void SurfaceImpl::PenColour(ColourAllocated fore) { hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID)); } @@ -398,7 +404,7 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase, SetFont(font); hdc->SetTextForeground(wxColourFromCA(fore)); hdc->SetTextBackground(wxColourFromCA(back)); - FillRectangle(rc, back); + //FillRectangle(rc, back); // ybase is where the baseline should be, but wxWin uses the upper left // corner, so I need to calculate the real position for the text... @@ -411,21 +417,27 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase, SetFont(font); hdc->SetTextForeground(wxColourFromCA(fore)); hdc->SetTextBackground(wxColourFromCA(back)); - FillRectangle(rc, back); + //FillRectangle(rc, back); hdc->SetClippingRegion(wxRectFromPRectangle(rc)); // see comments above hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent); - hdc->DestroyClippingRegion(); } -int SurfaceImpl::WidthText(Font &font, const char *s, int len) { - SetFont(font); - int w; - int h; - hdc->GetTextExtent(stc2wx(s, len), &w, &h); - return w; +void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase, + const char *s, int len, + ColourAllocated fore) { + + SetFont(font); + hdc->SetTextForeground(wxColourFromCA(fore)); + hdc->SetBackgroundMode(wxTRANSPARENT); + + // ybase is where the baseline should be, but wxWin uses the upper left + // corner, so I need to calculate the real position for the text... + hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent); + + hdc->SetBackgroundMode(wxSOLID); } @@ -450,7 +462,7 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio // Instead of a running total, remeasure from the begining of the // text for each character's position. This is because with AA fonts // on OS X widths can be fractions of pixels wide when more than one - // are drawn together, so the sum of all character widths is not necessariy + // are drawn together, so the sum of all character widths is not necessarily // (and probably not) the same as the whole string width. int* tpos = new int[len]; size_t i; @@ -491,6 +503,16 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio } +int SurfaceImpl::WidthText(Font &font, const char *s, int len) { + SetFont(font); + int w; + int h; + + hdc->GetTextExtent(stc2wx(s, len), &w, &h); + return w; +} + + int SurfaceImpl::WidthChar(Font &font, char ch) { SetFont(font); int w; @@ -561,6 +583,11 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { #endif } +void SurfaceImpl::SetDBCSMode(int codePage) { + // dbcsMode = codePage == SC_CP_DBCS; +} + + Surface *Surface::Allocate() { return new SurfaceImpl; } @@ -668,14 +695,52 @@ void Window::SetTitle(const char *s) { //---------------------------------------------------------------------- // Helper classes for ListBox +const int IconWidth = 16; -#if 1 // defined(__WXMAC__) -class wxSTCListBoxWin : public wxListBox { + +// This is a simple subclass of wxLIstView that just resets focus to the +// parent when it gets it. +class wxSTCListBox : public wxListView { public: - wxSTCListBoxWin(wxWindow* parent, wxWindowID id) - : wxListBox(parent, id, wxDefaultPosition, wxSize(0,0), - 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER) { - SetCursor(wxCursor(wxCURSOR_ARROW)); + wxSTCListBox(wxWindow* parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style) + : wxListView(parent, id, pos, size, style) + {} + + void OnFocus(wxFocusEvent& event) { + GetParent()->SetFocus(); + event.Skip(); + } + +private: + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(wxSTCListBox, wxListView) + EVT_SET_FOCUS( wxSTCListBox::OnFocus) +END_EVENT_TABLE() + + + + +// A window to place the wxSTCListBox upon +class wxSTCListBoxWin : public wxWindow { +private: + wxListView* lv; + CallBackAction doubleClickAction; + void* doubleClickActionData; +public: + wxSTCListBoxWin(wxWindow* parent, wxWindowID id) : + wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxNO_BORDER ) + { + + SetBackgroundColour(*wxBLUE); + lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize, + wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER); + lv->SetCursor(wxCursor(wxCURSOR_ARROW)); + lv->InsertColumn(0, wxEmptyString); + lv->InsertColumn(1, wxEmptyString); Hide(); } @@ -684,184 +749,286 @@ public: event.Skip(); } - wxListBox* GetLB() { return this; } - -private: - DECLARE_EVENT_TABLE() -}; - - -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox) - EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus) -END_EVENT_TABLE() - - - -#else - - -class wxSTCListBox : public wxListBox { -public: - wxSTCListBox(wxWindow* parent, wxWindowID id) - : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize, - 0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER | wxWANTS_CHARS) - {} - - void OnKeyDown(wxKeyEvent& event) { - // Give the key events to the STC. It will then update - // the listbox as needed. - GetGrandParent()->GetEventHandler()->ProcessEvent(event); - } - -private: - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox) - EVT_KEY_DOWN(wxSTCListBox::OnKeyDown) - EVT_CHAR(wxSTCListBox::OnKeyDown) -END_EVENT_TABLE() - - - -#undef wxSTC_USE_POPUP -#define wxSTC_USE_POPUP 0 // wxPopupWindow just doesn't work well in this case... - -// A window to place the listbox upon. If wxPopupWindow is supported then -// that will be used so the listbox can extend beyond the client area of the -// wxSTC if needed. -#if wxUSE_POPUPWIN && wxSTC_USE_POPUP -#include -#define wxSTCListBoxWinBase wxPopupWindow -#define param2 wxBORDER_NONE // popup's 2nd param is flags -#else -#define wxSTCListBoxWinBase wxWindow -#define param2 -1 // wxWindow's 2nd param is ID -#endif - -class wxSTCListBoxWin : public wxSTCListBoxWinBase { -public: - wxSTCListBoxWin(wxWindow* parent, wxWindowID id) - : wxSTCListBoxWinBase(parent, param2) { - lb = new wxSTCListBox(this, id); - lb->SetCursor(wxCursor(wxCURSOR_ARROW)); - lb->SetFocus(); - } - void OnSize(wxSizeEvent& event) { - lb->SetSize(GetSize()); + // reset the column widths + wxSize sz = GetClientSize(); + lv->SetSize(1, 1, sz.x-2, sz.y-2); + wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL); + if (il != NULL) { + int w, h; + il->GetSize(0, w, h); + w += 4; + lv->SetColumnWidth(0, w); + } + else { + lv->SetColumnWidth(0, 0); + } + lv->SetColumnWidth(1, sz.x - lv->GetColumnWidth(0) - + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X)); + event.Skip(); } - wxListBox* GetLB() { return lb; } -#if wxUSE_POPUPWIN && wxSTC_USE_POPUP - virtual void DoSetSize(int x, int y, - int width, int height, - int sizeFlags = wxSIZE_AUTO) { - if (x != -1) - GetParent()->ClientToScreen(&x, NULL); - if (y != -1) - GetParent()->ClientToScreen(NULL, &y); - wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags); + void OnActivate(wxListEvent& event) { + doubleClickAction(doubleClickActionData); } -#endif + + void SetDoubleClickAction(CallBackAction action, void *data) { + doubleClickAction = action; + doubleClickActionData = data; + } + + wxListView* GetLB() { return lv; } private: - wxSTCListBox* lb; DECLARE_EVENT_TABLE() }; -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase) - EVT_SIZE(wxSTCListBoxWin::OnSize) -END_EVENT_TABLE() -#endif -inline wxListBox* GETLB(WindowID win) { +BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow) + EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus) + EVT_SIZE ( wxSTCListBoxWin::OnSize) + EVT_LIST_ITEM_ACTIVATED(-1, wxSTCListBoxWin::OnActivate) +END_EVENT_TABLE() + + + + +inline wxListView* GETLB(WindowID win) { return (((wxSTCListBoxWin*)win)->GetLB()); } //---------------------------------------------------------------------- +class ListBoxImpl : public ListBox { +private: + int lineHeight; + bool unicodeMode; + int desiredVisibleRows; + int aveCharWidth; + int maxStrWidth; + wxImageList* imgList; + wxArrayInt* imgTypeMap; + +public: + ListBoxImpl(); + ~ListBoxImpl(); + + virtual void SetFont(Font &font); + virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_); + virtual void SetAverageCharWidth(int width); + virtual void SetVisibleRows(int rows); + virtual PRectangle GetDesiredRect(); + virtual int CaretFromEdge(); + virtual void Clear(); + virtual void Append(char *s, int type = -1); + virtual int Length(); + virtual void Select(int n); + virtual int GetSelection(); + virtual int Find(const char *prefix); + virtual void GetValue(int n, char *value, int len); + virtual void Sort(); + virtual void RegisterImage(int type, const char *xpm_data); + virtual void ClearRegisteredImages(); + virtual void SetDoubleClickAction(CallBackAction, void *); + +}; + + +ListBoxImpl::ListBoxImpl() + : lineHeight(10), unicodeMode(false), + desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0), + imgList(NULL), imgTypeMap(NULL) +{ +} + +ListBoxImpl::~ListBoxImpl() { + if (imgList) { + delete imgList; + imgList = NULL; + } + if (imgTypeMap) { + delete imgTypeMap; + imgTypeMap = NULL; + } +} + + +void ListBoxImpl::SetFont(Font &font) { + GETLB(id)->SetFont(*((wxFont*)font.GetID())); +} + + +void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) { + lineHeight = lineHeight_; + unicodeMode = unicodeMode_; + maxStrWidth = 0; + id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID); + if (imgList != NULL) + GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL); +} + + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + + +void ListBoxImpl::SetVisibleRows(int rows) { + desiredVisibleRows = rows; +} + + +PRectangle ListBoxImpl::GetDesiredRect() { + // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of + // the max size in Append and calculate it here... + int maxw = maxStrWidth; + int maxh = 0; + + // give it a default if there are no lines, and/or add a bit more + if (maxw == 0) maxw = 100; + maxw += aveCharWidth * 3 + IconWidth + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); + if (maxw > 350) + maxw = 350; + + // estimate a desired height + int count = GETLB(id)->GetItemCount(); + if (count) { + wxRect rect; + GETLB(id)->GetItemRect(0, rect); + maxh = count * rect.GetHeight(); + if (maxh > 140) // TODO: Use desiredVisibleRows?? + maxh = 140; + } + else + maxh = 100; + + PRectangle rc; + rc.top = 0; + rc.left = 0; + rc.right = maxw; + rc.bottom = maxh; + return rc; +} + + +int ListBoxImpl::CaretFromEdge() { + return 0; // 4 + IconWidth(); TODO +} + + +void ListBoxImpl::Clear() { + GETLB(id)->DeleteAllItems(); +} + + +void ListBoxImpl::Append(char *s, int type) { + wxString text = stc2wx(s); + long count = GETLB(id)->GetItemCount(); + long itemID = GETLB(id)->InsertItem(count, wxEmptyString); + GETLB(id)->SetItem(itemID, 1, text); + int itemWidth = 0; + GETLB(id)->GetTextExtent(text, &itemWidth, NULL); + maxStrWidth = wxMax(maxStrWidth, itemWidth); + if (type != -1) { + wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap")); + long idx = imgTypeMap->Item(type); + GETLB(id)->SetItemImage(itemID, idx, idx); + } +} + + +int ListBoxImpl::Length() { + return GETLB(id)->GetItemCount(); +} + + +void ListBoxImpl::Select(int n) { + bool select = TRUE; + if (n == -1) { + n = 0; + select = FALSE; + } + GETLB(id)->Focus(n); + GETLB(id)->Select(n, select); +} + + +int ListBoxImpl::GetSelection() { + return GETLB(id)->GetFirstSelected(); +} + + +int ListBoxImpl::Find(const char *prefix) { + // No longer used + return -1; +} + + +void ListBoxImpl::GetValue(int n, char *value, int len) { + wxListItem item; + item.SetId(n); + item.SetColumn(1); + item.SetMask(wxLIST_MASK_TEXT); + GETLB(id)->GetItem(item); + strncpy(value, wx2stc(item.GetText()), len); + value[len-1] = '\0'; +} + +void ListBoxImpl::Sort() { +} + + +void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { + wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1); + wxBitmap bmp(wxImage(stream, wxBITMAP_TYPE_XPM)); + + if (! imgList) { + // assumes all images are the same size + imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), TRUE); + imgTypeMap = new wxArrayInt; + } + + int idx = imgList->Add(bmp); + + // do we need to extend the mapping array? + wxArrayInt& itm = *imgTypeMap; + if ( itm.GetCount() < type+1) + itm.Add(-1, type - itm.GetCount() + 1); + + // Add an item that maps type to the image index + itm[type] = idx; +} + +void ListBoxImpl::ClearRegisteredImages() { + printf("LB:ClearRegisteredImages\n"); + if (imgList) { + delete imgList; + imgList = NULL; + } + if (imgTypeMap) { + delete imgTypeMap; + imgTypeMap = NULL; + } + if (id) + GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL); +} + + +void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) { + ((wxSTCListBoxWin*)id)->SetDoubleClickAction(action, data); +} + + + ListBox::ListBox() { } ListBox::~ListBox() { } -void ListBox::Create(Window &parent, int ctrlID) { - id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID); -} - -void ListBox::SetVisibleRows(int rows) { - desiredVisibleRows = rows; -} - -PRectangle ListBox::GetDesiredRect() { - wxSize sz = GETLB(id)->GetBestSize(); - PRectangle rc; - rc.top = 0; - rc.left = 0; - if (sz.x > 400) - sz.x = 400; - if (sz.y > 140) // TODO: Use desiredVisibleRows?? - sz.y = 140; - rc.right = sz.x; - rc.bottom = sz.y; - return rc; -} - -void ListBox::SetAverageCharWidth(int width) { - aveCharWidth = width; -} - -void ListBox::SetFont(Font &font) { - GETLB(id)->SetFont(*((wxFont*)font.GetID())); -} - -void ListBox::Clear() { - GETLB(id)->Clear(); -} - -void ListBox::Append(char *s) { - GETLB(id)->Append(stc2wx(s)); -} - -int ListBox::Length() { - return GETLB(id)->GetCount(); -} - -void ListBox::Select(int n) { - bool select = TRUE; - if (n == -1) { - n = 0; - select = FALSE; - } - GETLB(id)->SetSelection(n, select); -#ifdef __WXGTK__ - if (n > 4) - n = n - 4; - else - n = 0; - GETLB(id)->SetFirstItem(n); -#endif -} - -int ListBox::GetSelection() { - return GETLB(id)->GetSelection(); -} - -int ListBox::Find(const char *prefix) { - // No longer used - return -1; -} - -void ListBox::GetValue(int n, char *value, int len) { - wxString text = GETLB(id)->GetString(n); - strncpy(value, wx2stc(text), len); - value[len-1] = '\0'; -} - -void ListBox::Sort() { +ListBox *ListBox::Allocate() { + return new ListBoxImpl(); } //---------------------------------------------------------------------- @@ -906,7 +1073,7 @@ const char *Platform::DefaultFont() { } int Platform::DefaultFontSize() { - return 8; + return wxNORMAL_FONT->GetPointSize(); } unsigned int Platform::DoubleClickTime() { @@ -1014,6 +1181,13 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) { return false; } +int Platform::DBCSCharLength(int codePage, const char *s) { + return 0; +} + +int Platform::DBCSCharMaxLength() { + return 0; +} //---------------------------------------------------------------------- diff --git a/contrib/src/stc/ScintillaWX.cpp b/contrib/src/stc/ScintillaWX.cpp index 78a4da2099..9c37278177 100644 --- a/contrib/src/stc/ScintillaWX.cpp +++ b/contrib/src/stc/ScintillaWX.cpp @@ -67,7 +67,7 @@ void wxSTCDropTarget::OnLeave() { #define param2 wxBORDER_NONE // popup's 2nd param is flags #else #define wxSTCCallTipBase wxWindow -#define param2 -1 // wxWindows 2nd param is ID +#define param2 -1 // wxWindow's 2nd param is ID #endif class wxSTCCallTip : public wxSTCCallTipBase { @@ -438,9 +438,9 @@ long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lPar switch (iMessage) { case SCI_CALLTIPSHOW: { // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx - // because of the little tweak that needs done below. When updating - // new versions double check that this is still needed, and that any - // new code there is copied here too. + // because of the little tweak that needs done below for wxGTK. + // When updating new versions double check that this is still + // needed, and that any new code there is copied here too. AutoCompleteCancel(); if (!ct.wCallTip.Created()) { Point pt = LocationFromPosition(wParam); @@ -470,20 +470,6 @@ long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lPar break; } - case SCI_SETCARETWIDTH: - // NOTE: Allows a caet width of zero. This one has been added to - // Scintilla CVS so it can be removed from here when we update to - // version 1.50. - if (wParam <= 0) - vs.caretWidth = 0; - else if (wParam >= 3) - vs.caretWidth = 3; - else - vs.caretWidth = wParam; - InvalidateStyleRedraw(); - break; - - default: return ScintillaBase::WndProc(iMessage, wParam, lParam); } @@ -500,21 +486,21 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) { paintState = painting; Surface* surfaceWindow = Surface::Allocate(); surfaceWindow->Init(dc); - PRectangle rcPaint = PRectangleFromwxRect(rect); + rcPaint = PRectangleFromwxRect(rect); + PRectangle rcClient = GetClientRectangle(); + paintingAllText = rcPaint.Contains(rcClient); + dc->BeginDrawing(); + ClipChildren(*dc, rcPaint); Paint(surfaceWindow, rcPaint); dc->EndDrawing(); + delete surfaceWindow; if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; -#ifdef __WXGTK__ - // On wxGTK the editor window paints can overwrite the listbox... - if (ac.Active()) - ((wxWindow*)ac.lb.GetID())->Refresh(TRUE); -#endif } @@ -791,16 +777,18 @@ void ScintillaWX::DoDragLeave() { // Redraw all of text area. This paint will not be abandoned. void ScintillaWX::FullPaint() { paintState = painting; - rcPaint = GetTextRectangle(); + rcPaint = GetClientRectangle(); paintingAllText = true; wxClientDC dc(stc); Surface* surfaceWindow = Surface::Allocate(); surfaceWindow->Init(&dc); + + dc.BeginDrawing(); + ClipChildren(dc, rcPaint); Paint(surfaceWindow, rcPaint); + dc.EndDrawing(); + delete surfaceWindow; - -// stc->Refresh(FALSE); - paintState = notPainting; } @@ -814,6 +802,21 @@ void ScintillaWX::DoScrollToColumn(int column) { HorizontalScrollTo(column * vs.spaceWidth); } +void ScintillaWX::ClipChildren(wxDC& dc, PRectangle rect) { +#ifdef __WXGTK__ + wxRegion rgn(wxRectFromPRectangle(rect)); + if (ac.Active()) { + wxRect childRect = ((wxWindow*)ac.lb->GetID())->GetRect(); + rgn.Subtract(childRect); + } + if (ct.inCallTipMode) { + wxRect childRect = ((wxWindow*)ct.wCallTip.GetID())->GetRect(); + rgn.Subtract(childRect); + } + + dc.SetClippingRegion(rgn); +#endif +} //---------------------------------------------------------------------- diff --git a/contrib/src/stc/ScintillaWX.h b/contrib/src/stc/ScintillaWX.h index d904fc3c18..28e96719e8 100644 --- a/contrib/src/stc/ScintillaWX.h +++ b/contrib/src/stc/ScintillaWX.h @@ -27,6 +27,7 @@ #include "Platform.h" #include "Scintilla.h" +#include "XPM.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "PropSet.h" @@ -149,6 +150,7 @@ public: bool GetHideSelection() { return hideSelection; } void DoScrollToLine(int line); void DoScrollToColumn(int column); + void ClipChildren(wxDC& dc, PRectangle rect); private: bool capturedMouse; diff --git a/contrib/src/stc/StcVC.dsp b/contrib/src/stc/StcVC.dsp index a6c2c4ce95..77d23fed0e 100644 --- a/contrib/src/stc/StcVC.dsp +++ b/contrib/src/stc/StcVC.dsp @@ -282,6 +282,10 @@ SOURCE=.\scintilla\src\LexAda.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexAsm.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexAVE.cxx # End Source File # Begin Source File @@ -306,10 +310,18 @@ SOURCE=.\scintilla\src\LexCrontab.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexCSS.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexEiffel.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexFortran.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexHTML.cxx # End Source File # Begin Source File @@ -446,6 +458,10 @@ SOURCE=.\scintilla\src\WindowAccessor.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\XPM.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\include\WindowAccessor.h # End Source File # End Group diff --git a/contrib/src/stc/gen_iface.py b/contrib/src/stc/gen_iface.py index 6689380466..e22ad2346e 100644 --- a/contrib/src/stc/gen_iface.py +++ b/contrib/src/stc/gen_iface.py @@ -42,6 +42,7 @@ cmdValues = [ (2300, 2349), (2176, 2180), (2390, 2393), (2395, 2396), + 2404, ] @@ -88,90 +89,113 @@ methodOverrideMap = { 'GetViewWS' : ( 'GetViewWhiteSpace', 0, 0, 0), 'SetViewWS' : ( 'SetViewWhiteSpace', 0, 0, 0), - 'GetCharAt' : ( 0, 0, - '''int %s(int pos) { - return (unsigned char)SendMsg(%s, pos, 0);''', - 0), + 'GetCharAt' : + ( 0, 0, + '''int %s(int pos) { + return (unsigned char)SendMsg(%s, pos, 0);''', + 0), - 'GetStyleAt' : ( 0, 0, - '''int %s(int pos) { - return (unsigned char)SendMsg(%s, pos, 0);''', - 0), + 'GetStyleAt' : + ( 0, 0, + '''int %s(int pos) { + return (unsigned char)SendMsg(%s, pos, 0);''', + 0), - 'GetStyledText' : (0, - 'wxMemoryBuffer %s(int startPos, int endPos);', + 'GetStyledText' : + (0, + 'wxMemoryBuffer %s(int startPos, int endPos);', - '''wxMemoryBuffer %s(int startPos, int endPos) { - wxMemoryBuffer buf; - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - int len = endPos - startPos; - if (!len) return buf; - TextRange tr; - tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1); - tr.chrg.cpMin = startPos; - tr.chrg.cpMax = endPos; - len = SendMsg(%s, 0, (long)&tr); - buf.UngetWriteBuf(len); - return buf;''', + '''wxMemoryBuffer %s(int startPos, int endPos) { + wxMemoryBuffer buf; + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + int len = endPos - startPos; + if (!len) return buf; + TextRange tr; + tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1); + tr.chrg.cpMin = startPos; + tr.chrg.cpMax = endPos; + len = SendMsg(%s, 0, (long)&tr); + buf.UngetWriteBuf(len); + return buf;''', - ('Retrieve a buffer of cells.',)), + ('Retrieve a buffer of cells.',)), - 'PositionFromPoint' : (0, - 'int %s(wxPoint pt);', + 'PositionFromPoint' : + (0, + 'int %s(wxPoint pt);', - '''int %s(wxPoint pt) { - return SendMsg(%s, pt.x, pt.y);''', + '''int %s(wxPoint pt) { + return SendMsg(%s, pt.x, pt.y);''', + 0), - 0), + 'GetCurLine' : + (0, + '#ifdef SWIG\n wxString %s(int* OUTPUT);\n#else\n wxString GetCurLine(int* linePos=NULL);\n#endif', - 'GetCurLine' : (0, - '#ifdef SWIG\n wxString %s(int* OUTPUT);\n#else\n wxString GetCurLine(int* linePos=NULL);\n#endif', + '''wxString %s(int* linePos) { + int len = LineLength(GetCurrentLine()); + if (!len) { + if (linePos) *linePos = 0; + return wxEmptyString; + } - '''wxString %s(int* linePos) { - int len = LineLength(GetCurrentLine()); - if (!len) { - if (linePos) *linePos = 0; - return wxEmptyString; - } + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); + int pos = SendMsg(%s, len+1, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + if (linePos) *linePos = pos; + return stc2wx(buf);''', - int pos = SendMsg(%s, len+1, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - if (linePos) *linePos = pos; - return stc2wx(buf);''', - - 0), + 0), 'SetUsePalette' : (None, 0,0,0), 'MarkerSetFore' : ('MarkerSetForeground', 0, 0, 0), 'MarkerSetBack' : ('MarkerSetBackground', 0, 0, 0), - 'MarkerDefine' : (0, - '''void %s(int markerNumber, int markerSymbol, - const wxColour& foreground = wxNullColour, - const wxColour& background = wxNullColour);''', + 'MarkerDefine' : + (0, + '''void %s(int markerNumber, int markerSymbol, + const wxColour& foreground = wxNullColour, + const wxColour& background = wxNullColour);''', - '''void %s(int markerNumber, int markerSymbol, - const wxColour& foreground, - const wxColour& background) { + '''void %s(int markerNumber, int markerSymbol, + const wxColour& foreground, + const wxColour& background) { - SendMsg(%s, markerNumber, markerSymbol); - if (foreground.Ok()) - MarkerSetForeground(markerNumber, foreground); - if (background.Ok()) - MarkerSetBackground(markerNumber, background);''', + SendMsg(%s, markerNumber, markerSymbol); + if (foreground.Ok()) + MarkerSetForeground(markerNumber, foreground); + if (background.Ok()) + MarkerSetBackground(markerNumber, background);''', + + ('Set the symbol used for a particular marker number,', + 'and optionally the fore and background colours.')), + + + 'MarkerDefinePixmap' : + ('MarkerDefineBitmap', + '''void %s(int markerNumber, const wxBitmap& bmp);''', + '''void %s(int markerNumber, const wxBitmap& bmp) { + // convert bmp to a xpm in a string + wxMemoryOutputStream strm; + wxImage(bmp).SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len+1] = 0; + SendMsg(%s, markerNumber, (long)buff); + delete [] buff; + ''', + ('Define a marker from a bitmap',)), - ('Set the symbol used for a particular marker number,', - 'and optionally the fore and background colours.')), 'SetMarginTypeN' : ('SetMarginType', 0, 0, 0), 'GetMarginTypeN' : ('GetMarginType', 0, 0, 0), @@ -189,32 +213,33 @@ methodOverrideMap = { 'SetCaretFore' : ('SetCaretForeground', 0, 0, 0), 'StyleSetFont' : ('StyleSetFaceName', 0, 0, 0), - 'AssignCmdKey' : ('CmdKeyAssign', - 'void %s(int key, int modifiers, int cmd);', + 'AssignCmdKey' : + ('CmdKeyAssign', + 'void %s(int key, int modifiers, int cmd);', - '''void %s(int key, int modifiers, int cmd) { - SendMsg(%s, MAKELONG(key, modifiers), cmd);''', + '''void %s(int key, int modifiers, int cmd) { + SendMsg(%s, MAKELONG(key, modifiers), cmd);''', + 0), - 0), - 'ClearCmdKey' : ('CmdKeyClear', - 'void %s(int key, int modifiers);', + 'ClearCmdKey' : + ('CmdKeyClear', + 'void %s(int key, int modifiers);', - '''void %s(int key, int modifiers) { - SendMsg(%s, MAKELONG(key, modifiers));''', - - 0), + '''void %s(int key, int modifiers) { + SendMsg(%s, MAKELONG(key, modifiers));''', + 0), 'ClearAllCmdKeys' : ('CmdKeyClearAll', 0, 0, 0), - 'SetStylingEx' : ('SetStyleBytes', - 'void %s(int length, char* styleBytes);', + 'SetStylingEx' : + ('SetStyleBytes', + 'void %s(int length, char* styleBytes);', - '''void %s(int length, char* styleBytes) { - SendMsg(%s, length, (long)styleBytes);''', - - 0), + '''void %s(int length, char* styleBytes) { + SendMsg(%s, length, (long)styleBytes);''', + 0), 'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0), @@ -245,129 +270,161 @@ methodOverrideMap = { 'AutoCGetAutoHide' : ('AutoCompGetAutoHide', 0, 0, 0), 'AutoCSetDropRestOfWord' : ('AutoCompSetDropRestOfWord', 0,0,0), 'AutoCGetDropRestOfWord' : ('AutoCompGetDropRestOfWord', 0,0,0), + 'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0), + 'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0), + + 'RegisterImage' : + (0, + '''void %s(int type, const wxBitmap& bmp);''', + '''void %s(int type, const wxBitmap& bmp) { + // convert bmp to a xpm in a string + wxMemoryOutputStream strm; + wxImage(bmp).SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len+1] = 0; + SendMsg(%s, type, (long)buff); + delete [] buff; + ''', + ('Register an image for use in autocompletion lists.',)), + + + 'ClearRegisteredImages' : (0, 0, 0, + ('Clear all the registered images.',)), 'SetHScrollBar' : ('SetUseHorizontalScrollBar', 0, 0, 0), 'GetHScrollBar' : ('GetUseHorizontalScrollBar', 0, 0, 0), + 'SetVScrollBar' : ('SetUseVerticalScrollBar', 0, 0, 0), + 'GetVScrollBar' : ('GetUseVerticalScrollBar', 0, 0, 0), + 'GetCaretFore' : ('GetCaretForeground', 0, 0, 0), 'GetUsePalette' : (None, 0, 0, 0), - 'FindText' : (0, - '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''', + 'FindText' : + (0, + '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''', - '''int %s(int minPos, int maxPos, - const wxString& text, - int flags) { - TextToFind ft; - ft.chrg.cpMin = minPos; - ft.chrg.cpMax = maxPos; - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - ft.lpstrText = (char*)(const char*)buf; + '''int %s(int minPos, int maxPos, + const wxString& text, + int flags) { + TextToFind ft; + ft.chrg.cpMin = minPos; + ft.chrg.cpMax = maxPos; + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + ft.lpstrText = (char*)(const char*)buf; - return SendMsg(%s, flags, (long)&ft);''', - 0), + return SendMsg(%s, flags, (long)&ft);''', + 0), - 'FormatRange' : (0, - '''int %s(bool doDraw, - int startPos, - int endPos, - wxDC* draw, - wxDC* target, // Why does it use two? Can they be the same? - wxRect renderRect, - wxRect pageRect);''', - ''' int %s(bool doDraw, - int startPos, - int endPos, - wxDC* draw, - wxDC* target, // Why does it use two? Can they be the same? - wxRect renderRect, - wxRect pageRect) { - RangeToFormat fr; + 'FormatRange' : + (0, + '''int %s(bool doDraw, + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect);''', + ''' int %s(bool doDraw, + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect) { + RangeToFormat fr; - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - fr.hdc = draw; - fr.hdcTarget = target; - fr.rc.top = renderRect.GetTop(); - fr.rc.left = renderRect.GetLeft(); - fr.rc.right = renderRect.GetRight(); - fr.rc.bottom = renderRect.GetBottom(); - fr.rcPage.top = pageRect.GetTop(); - fr.rcPage.left = pageRect.GetLeft(); - fr.rcPage.right = pageRect.GetRight(); - fr.rcPage.bottom = pageRect.GetBottom(); - fr.chrg.cpMin = startPos; - fr.chrg.cpMax = endPos; + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + fr.hdc = draw; + fr.hdcTarget = target; + fr.rc.top = renderRect.GetTop(); + fr.rc.left = renderRect.GetLeft(); + fr.rc.right = renderRect.GetRight(); + fr.rc.bottom = renderRect.GetBottom(); + fr.rcPage.top = pageRect.GetTop(); + fr.rcPage.left = pageRect.GetLeft(); + fr.rcPage.right = pageRect.GetRight(); + fr.rcPage.bottom = pageRect.GetBottom(); + fr.chrg.cpMin = startPos; + fr.chrg.cpMax = endPos; - return SendMsg(%s, doDraw, (long)&fr);''', - 0), + return SendMsg(%s, doDraw, (long)&fr);''', + 0), - 'GetLine' : (0, - 'wxString %s(int line);', + 'GetLine' : + (0, + 'wxString %s(int line);', - '''wxString %s(int line) { - int len = LineLength(line); - if (!len) return wxEmptyString; + '''wxString %s(int line) { + int len = LineLength(line); + if (!len) return wxEmptyString; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(%s, line, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf);''', + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(%s, line, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf);''', - ('Retrieve the contents of a line.',)), + ('Retrieve the contents of a line.',)), 'SetSel' : ('SetSelection', 0, 0, 0), - 'GetSelText' : ('GetSelectedText', - 'wxString %s();', - '''wxString %s() { - int start; - int end; + 'GetSelText' : + ('GetSelectedText', + 'wxString %s();', - GetSelection(&start, &end); - int len = end - start; - if (!len) return wxEmptyString; + '''wxString %s() { + int start; + int end; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(%s, 0, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf);''', + GetSelection(&start, &end); + int len = end - start; + if (!len) return wxEmptyString; - ('Retrieve the selected text.',)), + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(%s, 0, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf);''', - 'GetTextRange' : (0, - 'wxString %s(int startPos, int endPos);', + ('Retrieve the selected text.',)), - '''wxString %s(int startPos, int endPos) { - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - int len = endPos - startPos; - if (!len) return wxEmptyString; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len); - TextRange tr; - tr.lpstrText = buf; - tr.chrg.cpMin = startPos; - tr.chrg.cpMax = endPos; - SendMsg(%s, 0, (long)&tr); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf);''', - ('Retrieve a range of text.',)), + 'GetTextRange' : + (0, + 'wxString %s(int startPos, int endPos);', + + '''wxString %s(int startPos, int endPos) { + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + int len = endPos - startPos; + if (!len) return wxEmptyString; + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len); + TextRange tr; + tr.lpstrText = buf; + tr.chrg.cpMin = startPos; + tr.chrg.cpMax = endPos; + SendMsg(%s, 0, (long)&tr); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf);''', + + ('Retrieve a range of text.',)), 'PointXFromPosition' : (None, 0, 0, 0), 'PointYFromPosition' : (None, 0, 0, 0), @@ -376,19 +433,20 @@ methodOverrideMap = { 'ReplaceSel' : ('ReplaceSelection', 0, 0, 0), 'Null' : (None, 0, 0, 0), - 'GetText' : (0, - 'wxString %s();', + 'GetText' : + (0, + 'wxString %s();', - '''wxString %s() { - int len = GetTextLength(); - wxMemoryBuffer mbuf(len+1); // leave room for the null... - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(%s, len+1, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf);''', + '''wxString %s() { + int len = GetTextLength(); + wxMemoryBuffer mbuf(len+1); // leave room for the null... + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(%s, len+1, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf);''', - ('Retrieve all the text in the document.', )), + ('Retrieve all the text in the document.', )), 'GetDirectFunction' : (None, 0, 0, 0), 'GetDirectPointer' : (None, 0, 0, 0), @@ -398,66 +456,76 @@ methodOverrideMap = { 'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0), - 'ReplaceTarget' : (0, - 'int %s(const wxString& text);', + 'ReplaceTarget' : + (0, + 'int %s(const wxString& text);', - ''' - int %s(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', - 0), + ''' + int %s(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', + 0), - 'ReplaceTargetRE' : (0, - 'int %s(const wxString& text);', + 'ReplaceTargetRE' : + (0, + 'int %s(const wxString& text);', - ''' - int %s(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', - 0), + ''' + int %s(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', + 0), - 'SearchInTarget' : (0, - 'int %s(const wxString& text);', + 'SearchInTarget' : + (0, + 'int %s(const wxString& text);', - ''' - int %s(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', - 0), + ''' + int %s(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(%s, strlen(buf), (long)(const char*)buf);''', + 0), - 'GetDocPointer' : (0, - 'void* %s();', - '''void* %s() { - return (void*)SendMsg(%s);''', - 0), + 'GetDocPointer' : + (0, + 'void* %s();', + '''void* %s() { + return (void*)SendMsg(%s);''', + 0), - 'SetDocPointer' : (0, - 'void %s(void* docPointer);', - '''void %s(void* docPointer) { - SendMsg(%s, 0, (long)docPointer);''', - 0), + 'SetDocPointer' : + (0, + 'void %s(void* docPointer);', + '''void %s(void* docPointer) { + SendMsg(%s, 0, (long)docPointer);''', + 0), - 'CreateDocument' : (0, - 'void* %s();', - '''void* %s() { - return (void*)SendMsg(%s);''', - 0), + 'CreateDocument' : + (0, + 'void* %s();', + '''void* %s() { + return (void*)SendMsg(%s);''', + 0), - 'AddRefDocument' : (0, - 'void %s(void* docPointer);', - '''void %s(void* docPointer) { - SendMsg(%s, 0, (long)docPointer);''', - 0), + 'AddRefDocument' : + (0, + 'void %s(void* docPointer);', + '''void %s(void* docPointer) { + SendMsg(%s, 0, (long)docPointer);''', + 0), - 'ReleaseDocument' : (0, - 'void %s(void* docPointer);', - '''void %s(void* docPointer) { - SendMsg(%s, 0, (long)docPointer);''', - 0), - 'SetCodePage' : (0, - 0, - '''void %s(int codePage) { + 'ReleaseDocument' : + (0, + 'void %s(void* docPointer);', + '''void %s(void* docPointer) { + SendMsg(%s, 0, (long)docPointer);''', + 0), + + 'SetCodePage' : + (0, + 0, + '''void %s(int codePage) { #if wxUSE_UNICODE wxASSERT_MSG(codePage == wxSTC_CP_UTF8, wxT("Only wxSTC_CP_UTF8 may be used when wxUSE_UNICODE is on.")); @@ -465,8 +533,8 @@ methodOverrideMap = { wxASSERT_MSG(codePage != wxSTC_CP_UTF8, wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off.")); #endif - SendMsg(%s, codePage);''', - ("Set the code page used to interpret the bytes of the document as characters.",) ), + SendMsg(%s, codePage);''', + ("Set the code page used to interpret the bytes of the document as characters.",) ), 'GrabFocus' : (None, 0, 0, 0), diff --git a/contrib/src/stc/makefile.b32 b/contrib/src/stc/makefile.b32 index 5a9843f863..8e9dfdccff 100644 --- a/contrib/src/stc/makefile.b32 +++ b/contrib/src/stc/makefile.b32 @@ -34,13 +34,16 @@ OBJECTS = \ KeyWords.obj \ LexAVE.obj \ LexAda.obj \ + LexAsm.obj \ LexBaan.obj \ LexBullant.obj \ LexMatlab.obj \ LexCPP.obj \ LexConf.obj \ LexCrontab.obj \ + LexCSS.obj \ LexEiffel.obj \ + LexFortran.obj \ LexHTML.obj \ LexLisp.obj \ LexLua.obj \ @@ -60,17 +63,19 @@ OBJECTS = \ UniConversion.obj \ ViewStyle.obj \ WindowAccessor.obj \ + XPM.cxx \ \ PlatWX.obj \ ScintillaWX.obj \ stc.obj \ + STCCFG = stc.cfg STCCPPFLAGS=$(DLL_FLAGS) $(EXTRACPPFLAGS) @$(STCCFG) default: $(STCCFG) $(LIBTARGET) -cleancfg: +cleancfg: del $(STCCFG) {$(S)}.cxx.obj: diff --git a/contrib/src/stc/makefile.g95 b/contrib/src/stc/makefile.g95 index 4ae99521f5..2d8581973c 100644 --- a/contrib/src/stc/makefile.g95 +++ b/contrib/src/stc/makefile.g95 @@ -22,13 +22,16 @@ OBJECTS = \ $(S)/KeyWords.$(OBJSUFF) \ $(S)/LexAVE.$(OBJSUFF) \ $(S)/LexAda.$(OBJSUFF) \ + $(S)/LexAsm.$(OBJSUFF) \ $(S)/LexBaan.$(OBJSUFF) \ $(S)/LexBullant.$(OBJSUFF) \ $(S)/LexMatlab.$(OBJSUFF) \ $(S)/LexCPP.$(OBJSUFF) \ $(S)/LexConf.$(OBJSUFF) \ $(S)/LexCrontab.$(OBJSUFF) \ + $(S)/LexCSS.$(OBJSUFF) \ $(S)/LexEiffel.$(OBJSUFF) \ + $(S)/LexFortran.$(OBJSUFF) \ $(S)/LexHTML.$(OBJSUFF) \ $(S)/LexLisp.$(OBJSUFF) \ $(S)/LexLua.$(OBJSUFF) \ @@ -48,11 +51,13 @@ OBJECTS = \ $(S)/UniConversion.$(OBJSUFF) \ $(S)/ViewStyle.$(OBJSUFF) \ $(S)/WindowAccessor.$(OBJSUFF) \ + $(S)/XPM.$(OBJSUFF) \ \ PlatWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \ stc.$(OBJSUFF) + LIBTARGET = $(WXDIR)/lib/libstc.a include $(WXDIR)/src/makelib.g95 \ No newline at end of file diff --git a/contrib/src/stc/makefile.vc b/contrib/src/stc/makefile.vc index 9a3fdc08e7..caad6ade36 100644 --- a/contrib/src/stc/makefile.vc +++ b/contrib/src/stc/makefile.vc @@ -27,13 +27,16 @@ OBJECTS = \ $(D)\KeyWords.obj \ $(D)\LexAVE.obj \ $(D)\LexAda.obj \ + $(D)\LexAsm.obj \ $(D)\LexBaan.obj \ $(D)\LexBullant.obj \ $(D)\LexMatlab.obj \ $(D)\LexCPP.obj \ $(D)\LexConf.obj \ $(D)\LexCrontab.obj \ + $(D)\LexCSS.obj \ $(D)\LexEiffel.obj \ + $(D)\LexFortran.obj \ $(D)\LexHTML.obj \ $(D)\LexLisp.obj \ $(D)\LexLua.obj \ @@ -53,6 +56,7 @@ OBJECTS = \ $(D)\UniConversion.obj \ $(D)\ViewStyle.obj \ $(D)\WindowAccessor.obj \ + $(D)\XPM.obj \ \ $(D)\PlatWX.obj \ $(D)\ScintillaWX.obj \ diff --git a/contrib/src/stc/makefile.wat b/contrib/src/stc/makefile.wat index 3a42017756..ac516a0f86 100644 --- a/contrib/src/stc/makefile.wat +++ b/contrib/src/stc/makefile.wat @@ -31,13 +31,16 @@ OBJECTS = & KeyWords.obj & LexAVE.obj & LexAda.obj & + LexAsm.obj & LexBaan.obj & LexBullant.obj & LexMatlab.obj & LexCPP.obj & LexConf.obj & LexCrontab.obj & + LexCSS.obj & LexEiffel.obj & + LexFortran.obj & LexHTML.obj & LexLisp.obj & LexLua.obj & @@ -57,9 +60,10 @@ OBJECTS = & UniConversion.obj & ViewStyle.obj & WindowAccessor.obj & + XPM.obj & PlatWX.obj & ScintillaWX.obj & - stc.obj + stc.obj all: $(STCLIB) .SYMBOLIC @@ -67,17 +71,17 @@ $(STCLIB): $(OBJECTS) *wlib /b /c /n /P=256 $(STCLIB) $(OBJECTS) clean: .SYMBOLIC - -erase *.obj - -erase *.bak - -erase *.err - -erase *.pch - -erase $(STCLIB) + -erase *.obj + -erase *.bak + -erase *.err + -erase *.pch + -erase $(STCLIB) -erase *.lbc .EXTENSIONS: .cxx .cxx: $(S) .cxx.obj: - $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS) + $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS) diff --git a/contrib/src/stc/scintilla/README.txt b/contrib/src/stc/scintilla/README.txt index 8538707cde..1933d10a97 100644 --- a/contrib/src/stc/scintilla/README.txt +++ b/contrib/src/stc/scintilla/README.txt @@ -3,5 +3,4 @@ scintilla/include directories from the Scintilla/SCiTE source distribution. All other code needed to implement Scintilla on top of wxWindows is located in the directory above this one. -The current version of the Scintilla code is 1.48 - +The current version of the Scintilla code is 1.51 diff --git a/contrib/src/stc/scintilla/include/Accessor.h b/contrib/src/stc/scintilla/include/Accessor.h index 0b2c4baee2..3f59c07939 100644 --- a/contrib/src/stc/scintilla/include/Accessor.h +++ b/contrib/src/stc/scintilla/include/Accessor.h @@ -25,7 +25,7 @@ protected: char buf[bufferSize+1]; int startPos; int endPos; - int codePage; + int codePage; virtual bool InternalIsLeadByte(char ch)=0; virtual void Fill(int position)=0; @@ -44,7 +44,7 @@ public: if (position < startPos || position >= endPos) { Fill(position); if (position < startPos || position >= endPos) { - // Position is outside range of document + // Position is outside range of document return chDefault; } } diff --git a/contrib/src/stc/scintilla/include/KeyWords.h b/contrib/src/stc/scintilla/include/KeyWords.h index df4e870c58..c51c88ef59 100644 --- a/contrib/src/stc/scintilla/include/KeyWords.h +++ b/contrib/src/stc/scintilla/include/KeyWords.h @@ -7,7 +7,7 @@ typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler); - + /** * A LexerModule is responsible for lexing and folding a particular language. * The class maintains a list of LexerModules which can be searched to find a @@ -26,7 +26,7 @@ protected: public: const char *languageName; - LexerModule(int language_, LexerFunction fnLexer_, + LexerModule(int language_, LexerFunction fnLexer_, const char *languageName_=0, LexerFunction fnFolder_=0, const char * const wordListDescriptions_[] = NULL); int GetLanguage() const { return language; } diff --git a/contrib/src/stc/scintilla/include/Platform.h b/contrib/src/stc/scintilla/include/Platform.h index 1a8dfaa96e..2ef2d5bb69 100644 --- a/contrib/src/stc/scintilla/include/Platform.h +++ b/contrib/src/stc/scintilla/include/Platform.h @@ -3,7 +3,7 @@ ** Interface to platform facilities. Also includes some basic utilities. ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef PLATFORM_H @@ -136,7 +136,7 @@ public: } ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { - co = red | (green << 8) | (blue << 16); + Set(red, green, blue); } bool operator==(const ColourDesired &other) const { @@ -147,6 +147,31 @@ public: co = lcol; } + void Set(unsigned int red, unsigned int green, unsigned int blue) { + co = red | (green << 8) | (blue << 16); + } + + static inline unsigned int ValueOfHex(const char ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else + return 0; + } + + void Set(const char *val) { + if (*val == '#') { + val++; + } + unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); + unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); + unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); + Set(r, g, b); + } + long AsLong() const { return co; } @@ -196,6 +221,9 @@ struct ColourPair { desired = desired_; allocated.Set(desired.AsLong()); } + void Copy() { + allocated.Set(desired.AsLong()); + } }; class Window; // Forward declaration for Palette @@ -292,6 +320,7 @@ public: virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0; virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; virtual int WidthText(Font &font_, const char *s, int len)=0; virtual int WidthChar(Font &font_, char ch)=0; @@ -307,6 +336,7 @@ public: virtual void FlushCachedState()=0; virtual void SetUnicodeMode(bool unicodeMode_)=0; + virtual void SetDBCSMode(int codePage)=0; }; /** @@ -329,8 +359,8 @@ public: id = id_; return *this; } - WindowID GetID() { return id; } - bool Created() { return id != 0; } + WindowID GetID() const { return id; } + bool Created() const { return id != 0; } void Destroy(); bool HasFocus(); PRectangle GetPosition(); @@ -353,38 +383,28 @@ private: */ class ListBox : public Window { -private: -#if PLAT_GTK - WindowID list; - WindowID scroller; - int current; -#endif - int desiredVisibleRows; - unsigned int maxItemCharacters; - unsigned int aveCharWidth; -public: - CallBackAction doubleClickAction; - void *doubleClickActionData; public: ListBox(); virtual ~ListBox(); - void Create(Window &parent, int ctrlID); - virtual void SetFont(Font &font); - void SetAverageCharWidth(int width); - void SetVisibleRows(int rows); - PRectangle GetDesiredRect(); - void Clear(); - void Append(char *s); - int Length(); - void Select(int n); - int GetSelection(); - int Find(const char *prefix); - void GetValue(int n, char *value, int len); - void Sort(); - void SetDoubleClickAction(CallBackAction action, void *data) { - doubleClickAction = action; - doubleClickActionData = data; - } + static ListBox *Allocate(); + + virtual void SetFont(Font &font)=0; + virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_)=0; + virtual void SetAverageCharWidth(int width)=0; + virtual void SetVisibleRows(int rows)=0; + virtual PRectangle GetDesiredRect()=0; + virtual int CaretFromEdge()=0; + virtual void Clear()=0; + virtual void Append(char *s, int type = -1)=0; + virtual int Length()=0; + virtual void Select(int n)=0; + virtual int GetSelection()=0; + virtual int Find(const char *prefix)=0; + virtual void GetValue(int n, char *value, int len)=0; + virtual void Sort()=0; + virtual void RegisterImage(int type, const char *xpm_data)=0; + virtual void ClearRegisteredImages()=0; + virtual void SetDoubleClickAction(CallBackAction, void *)=0; }; /** @@ -433,6 +453,8 @@ public: static long SendScintillaPointer( WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); static bool IsDBCSLeadByte(int codePage, char ch); + static int DBCSCharLength(int codePage, const char *s); + static int DBCSCharMaxLength(); // These are utility functions not really tied to a platform static int Minimum(int a, int b); diff --git a/contrib/src/stc/scintilla/include/PropSet.h b/contrib/src/stc/scintilla/include/PropSet.h index 59588c62ed..3f1b64f77f 100644 --- a/contrib/src/stc/scintilla/include/PropSet.h +++ b/contrib/src/stc/scintilla/include/PropSet.h @@ -60,7 +60,7 @@ public: bool onlyLineEnds; ///< Delimited by any white space or only line ends bool sorted; int starts[256]; - WordList(bool onlyLineEnds_ = false) : + WordList(bool onlyLineEnds_ = false) : words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {} ~WordList() { Clear(); } operator bool() { return len ? true : false; } @@ -70,9 +70,9 @@ public: char *Allocate(int size); void SetFromAllocated(); bool InList(const char *s); - const char *GetNearestWord(const char *wordStart, int searchLen = -1, + const char *GetNearestWord(const char *wordStart, int searchLen = -1, bool ignoreCase = false, SString wordCharacters=""); - char *GetNearestWords(const char *wordStart, int searchLen=-1, + char *GetNearestWords(const char *wordStart, int searchLen=-1, bool ignoreCase=false, char otherSeparator='\0'); }; diff --git a/contrib/src/stc/scintilla/include/SString.h b/contrib/src/stc/scintilla/include/SString.h index 3c7ccc33a5..01602df781 100644 --- a/contrib/src/stc/scintilla/include/SString.h +++ b/contrib/src/stc/scintilla/include/SString.h @@ -238,7 +238,7 @@ public: return append(sOther, static_cast(measure_length)); } SString &operator+=(const SString &sOther) { - return append(sOther.s, sOther.sSize); + return append(sOther.s, sOther.sLen); } SString &operator+=(char ch) { return append(&ch, 1); @@ -369,11 +369,7 @@ public: */ inline char *StringDup( const char *s, ///< The string to duplicate - /* gcc 2.96 doesn't seem to like this syntax: gives - 'non-local function uses anonymous type' - SString::lenpos_t len=SString::measure_length) ///< The length of memory to allocate. Optional. - */ - SString::lenpos_t len=0xffffffffU) ///< The length of memory to allocate. Optional. + SString::lenpos_t len=SString::measure_length) ///< The length of memory to allocate. Optional. { return SString::StringAllocate(s, len); } diff --git a/contrib/src/stc/scintilla/include/SciLexer.h b/contrib/src/stc/scintilla/include/SciLexer.h index a6066cd585..80b3ef22bf 100644 --- a/contrib/src/stc/scintilla/include/SciLexer.h +++ b/contrib/src/stc/scintilla/include/SciLexer.h @@ -48,6 +48,11 @@ #define SCLEX_BAAN 31 #define SCLEX_MATLAB 32 #define SCLEX_SCRIPTOL 33 +#define SCLEX_ASM 34 +#define SCLEX_CPPNOCASE 35 +#define SCLEX_FORTRAN 36 +#define SCLEX_F77 37 +#define SCLEX_CSS 38 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -273,6 +278,7 @@ #define SCE_ERR_DIFF_ADDITION 11 #define SCE_ERR_DIFF_DELETION 12 #define SCE_ERR_DIFF_MESSAGE 13 +#define SCE_ERR_PHP 14 #define SCE_BAT_DEFAULT 0 #define SCE_BAT_COMMENT 1 #define SCE_BAT_WORD 2 @@ -309,22 +315,29 @@ #define SCE_AVE_COMMENT 1 #define SCE_AVE_NUMBER 2 #define SCE_AVE_WORD 3 -#define SCE_AVE_KEYWORD 4 -#define SCE_AVE_STATEMENT 5 #define SCE_AVE_STRING 6 #define SCE_AVE_ENUM 7 #define SCE_AVE_STRINGEOL 8 #define SCE_AVE_IDENTIFIER 9 #define SCE_AVE_OPERATOR 10 +#define SCE_AVE_WORD1 11 +#define SCE_AVE_WORD2 12 +#define SCE_AVE_WORD3 13 +#define SCE_AVE_WORD4 14 +#define SCE_AVE_WORD5 15 +#define SCE_AVE_WORD6 16 #define SCE_ADA_DEFAULT 0 -#define SCE_ADA_COMMENT 1 -#define SCE_ADA_NUMBER 2 -#define SCE_ADA_WORD 3 -#define SCE_ADA_STRING 4 +#define SCE_ADA_WORD 1 +#define SCE_ADA_IDENTIFIER 2 +#define SCE_ADA_NUMBER 3 +#define SCE_ADA_DELIMITER 4 #define SCE_ADA_CHARACTER 5 -#define SCE_ADA_OPERATOR 6 -#define SCE_ADA_IDENTIFIER 7 +#define SCE_ADA_CHARACTEREOL 6 +#define SCE_ADA_STRING 7 #define SCE_ADA_STRINGEOL 8 +#define SCE_ADA_LABEL 9 +#define SCE_ADA_COMMENTLINE 10 +#define SCE_ADA_ILLEGAL 11 #define SCE_BAAN_DEFAULT 0 #define SCE_BAAN_COMMENT 1 #define SCE_BAAN_COMMENTDOC 2 @@ -392,6 +405,45 @@ #define SCE_SCRIPTOL_COMMENTDOCKEYWORD 17 #define SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR 18 #define SCE_SCRIPTOL_COMMENTBASIC 19 +#define SCE_ASM_DEFAULT 0 +#define SCE_ASM_COMMENT 1 +#define SCE_ASM_NUMBER 2 +#define SCE_ASM_STRING 3 +#define SCE_ASM_OPERATOR 4 +#define SCE_ASM_IDENTIFIER 5 +#define SCE_ASM_CPUINSTRUCTION 6 +#define SCE_ASM_MATHINSTRUCTION 7 +#define SCE_ASM_REGISTER 8 +#define SCE_ASM_DIRECTIVE 9 +#define SCE_ASM_DIRECTIVEOPERAND 10 +#define SCE_F_DEFAULT 0 +#define SCE_F_COMMENT 1 +#define SCE_F_NUMBER 2 +#define SCE_F_STRING1 3 +#define SCE_F_STRING2 4 +#define SCE_F_STRINGEOL 5 +#define SCE_F_OPERATOR 6 +#define SCE_F_IDENTIFIER 7 +#define SCE_F_WORD 8 +#define SCE_F_WORD2 9 +#define SCE_F_WORD3 10 +#define SCE_F_PREPROCESSOR 11 +#define SCE_F_OPERATOR2 12 +#define SCE_F_LABEL 13 +#define SCE_F_CONTINUATION 14 +#define SCE_CSS_DEFAULT 0 +#define SCE_CSS_TAG 1 +#define SCE_CSS_CLASS 2 +#define SCE_CSS_PSEUDOCLASS 3 +#define SCE_CSS_UNKNOWN_PSEUDOCLASS 4 +#define SCE_CSS_OPERATOR 5 +#define SCE_CSS_IDENTIFIER 6 +#define SCE_CSS_UNKNOWN_IDENTIFIER 7 +#define SCE_CSS_VALUE 8 +#define SCE_CSS_COMMENT 9 +#define SCE_CSS_ID 10 +#define SCE_CSS_IMPORTANT 11 +#define SCE_CSS_DIRECTIVE 12 //--Autogenerated -- end of section automatically generated from Scintilla.iface #endif diff --git a/contrib/src/stc/scintilla/include/Scintilla.h b/contrib/src/stc/scintilla/include/Scintilla.h index 30fcf50fc4..9f3b9ea348 100644 --- a/contrib/src/stc/scintilla/include/Scintilla.h +++ b/contrib/src/stc/scintilla/include/Scintilla.h @@ -2,7 +2,7 @@ /** @file Scintilla.h ** Interface to the edit control. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. // Most of this file is automatically generated from the Scintilla.iface interface definition @@ -83,6 +83,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETTABWIDTH 2036 #define SCI_GETTABWIDTH 2121 #define SC_CP_UTF8 65001 +#define SC_CP_DBCS 1 #define SCI_SETCODEPAGE 2037 #define SCI_SETUSEPALETTE 2039 #define MARKER_MAX 31 @@ -111,6 +112,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MARK_BACKGROUND 22 #define SC_MARK_DOTDOTDOT 23 #define SC_MARK_ARROWS 24 +#define SC_MARK_PIXMAP 25 #define SC_MARK_CHARACTER 10000 #define SC_MARKNUM_FOLDEREND 25 #define SC_MARKNUM_FOLDEROPENMID 26 @@ -129,6 +131,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_MARKERGET 2046 #define SCI_MARKERNEXT 2047 #define SCI_MARKERPREVIOUS 2048 +#define SCI_MARKERDEFINEPIXMAP 2049 #define SC_MARGIN_SYMBOL 0 #define SC_MARGIN_NUMBER 1 #define SCI_SETMARGINTYPEN 2240 @@ -241,6 +244,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_AUTOCGETAUTOHIDE 2119 #define SCI_AUTOCSETDROPRESTOFWORD 2270 #define SCI_AUTOCGETDROPRESTOFWORD 2271 +#define SCI_REGISTERIMAGE 2405 +#define SCI_CLEARREGISTEREDIMAGES 2408 +#define SCI_AUTOCGETTYPESEPARATOR 2285 +#define SCI_AUTOCSETTYPESEPARATOR 2286 #define SCI_SETINDENT 2122 #define SCI_GETINDENT 2123 #define SCI_SETUSETABS 2124 @@ -338,6 +345,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_FOLDLEVELBASE 0x400 #define SC_FOLDLEVELWHITEFLAG 0x1000 #define SC_FOLDLEVELHEADERFLAG 0x2000 +#define SC_FOLDLEVELBOXHEADERFLAG 0x4000 +#define SC_FOLDLEVELBOXFOOTERFLAG 0x8000 +#define SC_FOLDLEVELCONTRACTED 0x10000 +#define SC_FOLDLEVELUNINDENT 0x20000 #define SC_FOLDLEVELNUMBERMASK 0x0FFF #define SCI_SETFOLDLEVEL 2222 #define SCI_GETFOLDLEVEL 2223 @@ -350,6 +361,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETFOLDEXPANDED 2230 #define SCI_TOGGLEFOLD 2231 #define SCI_ENSUREVISIBLE 2232 +#define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 +#define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 +#define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 +#define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010 +#define SC_FOLDFLAG_LEVELNUMBERS 0x0040 +#define SC_FOLDFLAG_BOX 0x0001 #define SCI_SETFOLDFLAGS 2233 #define SCI_ENSUREVISIBLEENFORCEPOLICY 2234 #define SCI_SETTABINDENTS 2260 @@ -377,6 +394,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETENDATLASTLINE 2277 #define SCI_GETENDATLASTLINE 2278 #define SCI_TEXTHEIGHT 2279 +#define SCI_SETVSCROLLBAR 2280 +#define SCI_GETVSCROLLBAR 2281 +#define SCI_APPENDTEXT 2282 +#define SCI_GETTWOPHASEDRAW 2283 +#define SCI_SETTWOPHASEDRAW 2284 +#define SCI_TARGETFROMSELECTION 2287 +#define SCI_LINESJOIN 2288 +#define SCI_LINESSPLIT 2289 +#define SCI_SETFOLDMARGINCOLOUR 2290 +#define SCI_SETFOLDMARGINHICOLOUR 2291 #define SCI_LINEDOWN 2300 #define SCI_LINEDOWNEXTEND 2301 #define SCI_LINEUP 2302 @@ -417,6 +444,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_LINECUT 2337 #define SCI_LINEDELETE 2338 #define SCI_LINETRANSPOSE 2339 +#define SCI_LINEDUPLICATE 2404 #define SCI_LOWERCASE 2340 #define SCI_UPPERCASE 2341 #define SCI_LINESCROLLDOWN 2342 @@ -464,7 +492,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETMOUSEDOWNCAPTURES 2384 #define SCI_GETMOUSEDOWNCAPTURES 2385 #define SC_CURSORNORMAL -1 -#define SC_CURSORWAIT 3 +#define SC_CURSORWAIT 4 #define SCI_SETCURSOR 2386 #define SCI_GETCURSOR 2387 #define SCI_SETCONTROLCHARSYMBOL 2388 @@ -480,6 +508,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_DELLINERIGHT 2396 #define SCI_SETXOFFSET 2397 #define SCI_GETXOFFSET 2398 +#define SCI_CHOOSECARETX 2399 #define SCI_GRABFOCUS 2400 #define CARET_SLOP 0x01 #define CARET_STRICT 0x04 @@ -487,6 +516,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define CARET_EVEN 0x08 #define SCI_SETXCARETPOLICY 2402 #define SCI_SETYCARETPOLICY 2403 +#define SCI_SETPRINTWRAPMODE 2406 +#define SCI_GETPRINTWRAPMODE 2407 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 diff --git a/contrib/src/stc/scintilla/include/Scintilla.iface b/contrib/src/stc/scintilla/include/Scintilla.iface index d6383b103b..e7c3a851ae 100644 --- a/contrib/src/stc/scintilla/include/Scintilla.iface +++ b/contrib/src/stc/scintilla/include/Scintilla.iface @@ -221,6 +221,9 @@ get int GetTabWidth=2121(,) # This is the same value as CP_UTF8 in Windows val SC_CP_UTF8=65001 +# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+. +val SC_CP_DBCS=1 + # Set the code page used to interpret the bytes of the document as characters. # The SC_CP_UTF8 value can be used to enter Unicode mode. set void SetCodePage=2037(int codePage,) @@ -260,6 +263,7 @@ val SC_MARK_CIRCLEMINUSCONNECTED=21 val SC_MARK_BACKGROUND=22 val SC_MARK_DOTDOTDOT=23 val SC_MARK_ARROWS=24 +val SC_MARK_PIXMAP=25 val SC_MARK_CHARACTER=10000 @@ -302,6 +306,9 @@ fun int MarkerNext=2047(int lineStart, int markerMask) # Find the previous line before lineStart that includes a marker in mask. fun int MarkerPrevious=2048(int lineStart, int markerMask) +# Define a marker from a pixmap. +fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap) + enu MarginType=SC_MARGIN_ val SC_MARGIN_SYMBOL=0 val SC_MARGIN_NUMBER=1 @@ -578,6 +585,19 @@ set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,) # after the inserted text upon completion. get bool AutoCGetDropRestOfWord=2271(,) +# Register an XPM image for use in autocompletion lists. +fun void RegisterImage=2405(int type, string xpmData) + +# Clear all the registered XPM images. +fun void ClearRegisteredImages=2408(,) + +# Retrieve the auto-completion list type-separator character. +get int AutoCGetTypeSeparator=2285(,) + +# Change the type-separator character in the string setting up an auto-completion list. +# Default is '?' but can be changed if items contain '?'. +set void AutoCSetTypeSeparator=2286(int separatorCharacter,) + # Set the number of spaces used for one level of indentation. set void SetIndent=2122(int indentSize,) @@ -688,7 +708,7 @@ fun position FindText=2150(int flags, findtext ft) # On Windows, will draw the document into a display context such as a printer. fun void FormatRange=2151(bool draw, formatrange fr) -# Retrieve the line at the top of the display. +# Retrieve the display line at the top of the display. get int GetFirstVisibleLine=2152(,) # Retrieve the contents of a line. @@ -873,6 +893,10 @@ enu FoldLevel=SC_FOLDLEVEL val SC_FOLDLEVELBASE=0x400 val SC_FOLDLEVELWHITEFLAG=0x1000 val SC_FOLDLEVELHEADERFLAG=0x2000 +val SC_FOLDLEVELBOXHEADERFLAG=0x4000 +val SC_FOLDLEVELBOXFOOTERFLAG=0x8000 +val SC_FOLDLEVELCONTRACTED=0x10000 +val SC_FOLDLEVELUNINDENT=0x20000 val SC_FOLDLEVELNUMBERMASK=0x0FFF # Set the fold level of a line. @@ -910,7 +934,15 @@ fun void ToggleFold=2231(int line,) # Ensure a particular line is visible by expanding any header line hiding it. fun void EnsureVisible=2232(int line,) -# Set some debugging options for folding. +enu FoldFlag=SC_FOLDFLAG_ +val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002 +val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004 +val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008 +val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010 +val SC_FOLDFLAG_LEVELNUMBERS=0x0040 +val SC_FOLDFLAG_BOX=0x0001 + +# Set some style options for folding. fun void SetFoldFlags=2233(int flags,) # Ensure a particular line is visible by expanding any header line hiding it. @@ -988,6 +1020,39 @@ get int GetEndAtLastLine=2278(,) # Retrieve the height of a particular line of text in pixels. fun int TextHeight=2279(int line,) +# Show or hide the vertical scroll bar. +set void SetVScrollBar=2280(bool show,) + +# Is the vertical scroll bar visible? +get bool GetVScrollBar=2281(,) + +# Append a string to the end of the document without changing the selection. +fun void AppendText=2282(int length, string text) + +# Is drawing done in two phases with backgrounds drawn before foregrounds? +get bool GetTwoPhaseDraw=2283(,) + +# In twoPhaseDraw mode, drawing is performed in two phases, first the background +# and then the foreground. This avoids chopping off characters that overlap the next run. +set void SetTwoPhaseDraw=2284(bool twoPhase,) + +# Make the target range start and end be the same as the selection range start and end. +fun void TargetFromSelection=2287(,) + +# Join the lines in the target. +# This is an experimental feature and may be changed or removed. +fun void LinesJoin=2288(,) + +# Split the lines in the target into lines that are less wide than pixelWidth +# where possible. +fun void LinesSplit=2289(int pixelWidth,) + +# Set the colours used as a chequerboard pattern in the fold margin +fun void SetFoldMarginColour=2290(bool useSetting, colour back) +fun void SetFoldMarginHiColour=2291(bool useSetting, colour fore) + +## New messages go here + ## Start of key messages # Move caret down one line. fun void LineDown=2300(,) @@ -1111,6 +1176,9 @@ fun void LineDelete=2338(,) # Switch the current line with the previous. fun void LineTranspose=2339(,) +# Duplicate the current line. +fun void LineDuplicate=2404(,) + # Transform the selection to lower case. fun void LowerCase=2340(,) @@ -1251,7 +1319,7 @@ get bool GetMouseDownCaptures=2385(,) enu CursorShape=SC_CURSOR val SC_CURSORNORMAL=-1 -val SC_CURSORWAIT=3 +val SC_CURSORWAIT=4 # Sets the cursor to one of the SC_CURSOR* values. set void SetCursor=2386(int cursorType,) # Get cursor type. @@ -1291,6 +1359,9 @@ fun void DelLineRight=2396(,) set void SetXOffset=2397(int newOffset,) get int GetXOffset=2398(,) +# Set the last x chosen value to be the caret x position +fun void ChooseCaretX=2399(,) + # Set the focus to this Scintilla widget. # GTK+ Specific. fun void GrabFocus=2400(,) @@ -1327,6 +1398,12 @@ fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop) # The exclusion zone is given in lines. fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop) +# Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE). +set void SetPrintWrapMode=2406(int mode,) + +# Is printing line wrapped. +get int GetPrintWrapMode=2407(,) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) @@ -1442,6 +1519,11 @@ val SCLEX_PHP=30 val SCLEX_BAAN=31 val SCLEX_MATLAB=32 val SCLEX_SCRIPTOL=33 +val SCLEX_ASM=34 +val SCLEX_CPPNOCASE=35 +val SCLEX_FORTRAN=36 +val SCLEX_F77=37 +val SCLEX_CSS=38 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -1708,6 +1790,7 @@ val SCE_ERR_DIFF_CHANGED=10 val SCE_ERR_DIFF_ADDITION=11 val SCE_ERR_DIFF_DELETION=12 val SCE_ERR_DIFF_MESSAGE=13 +val SCE_ERR_PHP=14 # Lexical states for SCLEX_BATCH lex Batch=SCLEX_BATCH SCE_BAT_ val SCE_BAT_DEFAULT=0 @@ -1754,24 +1837,31 @@ val SCE_AVE_DEFAULT=0 val SCE_AVE_COMMENT=1 val SCE_AVE_NUMBER=2 val SCE_AVE_WORD=3 -val SCE_AVE_KEYWORD=4 -val SCE_AVE_STATEMENT=5 val SCE_AVE_STRING=6 val SCE_AVE_ENUM=7 val SCE_AVE_STRINGEOL=8 val SCE_AVE_IDENTIFIER=9 val SCE_AVE_OPERATOR=10 +val SCE_AVE_WORD1=11 +val SCE_AVE_WORD2=12 +val SCE_AVE_WORD3=13 +val SCE_AVE_WORD4=14 +val SCE_AVE_WORD5=15 +val SCE_AVE_WORD6=16 # Lexical states for SCLEX_ADA lex Ada=SCLEX_ADA SCE_ADA_ val SCE_ADA_DEFAULT=0 -val SCE_ADA_COMMENT=1 -val SCE_ADA_NUMBER=2 -val SCE_ADA_WORD=3 -val SCE_ADA_STRING=4 +val SCE_ADA_WORD=1 +val SCE_ADA_IDENTIFIER=2 +val SCE_ADA_NUMBER=3 +val SCE_ADA_DELIMITER=4 val SCE_ADA_CHARACTER=5 -val SCE_ADA_OPERATOR=6 -val SCE_ADA_IDENTIFIER=7 +val SCE_ADA_CHARACTEREOL=6 +val SCE_ADA_STRING=7 val SCE_ADA_STRINGEOL=8 +val SCE_ADA_LABEL=9 +val SCE_ADA_COMMENTLINE=10 +val SCE_ADA_ILLEGAL=11 # Lexical states for SCLEX_BAAN lex Baan=SCLEX_BAAN SCE_BAAN_ val SCE_BAAN_DEFAULT=0 @@ -1852,6 +1942,52 @@ val SCE_SCRIPTOL_WORD2=16 val SCE_SCRIPTOL_COMMENTDOCKEYWORD=17 val SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR=18 val SCE_SCRIPTOL_COMMENTBASIC=19 +# Lexical states for SCLEX_ASM +lex Asm=SCLEX_ASM SCE_ASM_ +val SCE_ASM_DEFAULT=0 +val SCE_ASM_COMMENT=1 +val SCE_ASM_NUMBER=2 +val SCE_ASM_STRING=3 +val SCE_ASM_OPERATOR=4 +val SCE_ASM_IDENTIFIER=5 +val SCE_ASM_CPUINSTRUCTION=6 +val SCE_ASM_MATHINSTRUCTION=7 +val SCE_ASM_REGISTER=8 +val SCE_ASM_DIRECTIVE=9 +val SCE_ASM_DIRECTIVEOPERAND=10 +# Lexical states for SCLEX_FORTRAN +lex Fortran=SCLEX_FORTRAN SCE_F_ +lex F77=SCLEX_F77 SCE_F_ +val SCE_F_DEFAULT=0 +val SCE_F_COMMENT=1 +val SCE_F_NUMBER=2 +val SCE_F_STRING1=3 +val SCE_F_STRING2=4 +val SCE_F_STRINGEOL=5 +val SCE_F_OPERATOR=6 +val SCE_F_IDENTIFIER=7 +val SCE_F_WORD=8 +val SCE_F_WORD2=9 +val SCE_F_WORD3=10 +val SCE_F_PREPROCESSOR=11 +val SCE_F_OPERATOR2=12 +val SCE_F_LABEL=13 +val SCE_F_CONTINUATION=14 +# Lexical states for SCLEX_CSS +lex CSS=SCLEX_CSS SCE_CSS_ +val SCE_CSS_DEFAULT=0 +val SCE_CSS_TAG=1 +val SCE_CSS_CLASS=2 +val SCE_CSS_PSEUDOCLASS=3 +val SCE_CSS_UNKNOWN_PSEUDOCLASS=4 +val SCE_CSS_OPERATOR=5 +val SCE_CSS_IDENTIFIER=6 +val SCE_CSS_UNKNOWN_IDENTIFIER=7 +val SCE_CSS_VALUE=8 +val SCE_CSS_COMMENT=9 +val SCE_CSS_ID=10 +val SCE_CSS_IMPORTANT=11 +val SCE_CSS_DIRECTIVE=12 # Events diff --git a/contrib/src/stc/scintilla/include/ScintillaWidget.h b/contrib/src/stc/scintilla/include/ScintillaWidget.h index 203f357339..765fd8594d 100644 --- a/contrib/src/stc/scintilla/include/ScintillaWidget.h +++ b/contrib/src/stc/scintilla/include/ScintillaWidget.h @@ -37,7 +37,8 @@ struct _ScintillaClass { guint scintilla_get_type (void); GtkWidget* scintilla_new (void); void scintilla_set_id (ScintillaObject *sci,int id); -sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); +sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); +void scintilla_release_resources(void); #if GTK_MAJOR_VERSION < 2 #define SCINTILLA_NOTIFY "notify" diff --git a/contrib/src/stc/scintilla/include/WindowAccessor.h b/contrib/src/stc/scintilla/include/WindowAccessor.h index 6c16b150f2..4324605017 100644 --- a/contrib/src/stc/scintilla/include/WindowAccessor.h +++ b/contrib/src/stc/scintilla/include/WindowAccessor.h @@ -26,8 +26,8 @@ protected: bool InternalIsLeadByte(char ch); void Fill(int position); public: - WindowAccessor(WindowID id_, PropSet &props_) : - Accessor(), id(id_), props(props_), + WindowAccessor(WindowID id_, PropSet &props_) : + Accessor(), id(id_), props(props_), lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { } ~WindowAccessor(); @@ -40,8 +40,8 @@ public: void Flush(); int GetLineState(int line); int SetLineState(int line, int state); - int GetPropertyInt(const char *key, int defaultValue=0) { - return props.GetInt(key, defaultValue); + int GetPropertyInt(const char *key, int defaultValue=0) { + return props.GetInt(key, defaultValue); } char *GetProperties() { return props.ToString(); diff --git a/contrib/src/stc/scintilla/src/AutoComplete.cxx b/contrib/src/stc/scintilla/src/AutoComplete.cxx index d971fa12a0..adbd24d038 100644 --- a/contrib/src/stc/scintilla/src/AutoComplete.cxx +++ b/contrib/src/stc/scintilla/src/AutoComplete.cxx @@ -2,7 +2,7 @@ /** @file AutoComplete.cxx ** Defines the auto completion list box. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -14,33 +14,42 @@ #include "PropSet.h" #include "AutoComplete.h" -AutoComplete::AutoComplete() : +AutoComplete::AutoComplete() : active(false), separator(' '), + typesep('?'), ignoreCase(false), chooseSingle(false), + lb(0), posStart(0), startLen(0), cancelAtStartPos(true), autoHide(true), dropRestOfWord(false) { + lb = ListBox::Allocate(); stopChars[0] = '\0'; fillUpChars[0] = '\0'; } AutoComplete::~AutoComplete() { - lb.Destroy(); + if (lb) { + lb->Destroy(); + delete lb; + lb = 0; + } } bool AutoComplete::Active() { return active; } -void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) { - if (!lb.Created()) { - lb.Create(parent, ctrlID); +void AutoComplete::Start(Window &parent, int ctrlID, int position, + int startLen_, int lineHeight, bool unicodeMode) { + if (active) { + Cancel(); } - lb.Clear(); + lb->Create(parent, ctrlID, lineHeight, unicodeMode); + lb->Clear(); active = true; startLen = startLen_; posStart = position; @@ -63,7 +72,7 @@ void AutoComplete::SetFillUpChars(const char *fillUpChars_) { bool AutoComplete::IsFillUpChar(char ch) { return ch && strchr(fillUpChars, ch); } - + void AutoComplete::SetSeparator(char separator_) { separator = separator_; } @@ -72,49 +81,65 @@ char AutoComplete::GetSeparator() { return separator; } +void AutoComplete::SetTypesep(char separator_) { + typesep = separator_; +} + +char AutoComplete::GetTypesep() { + return typesep; +} + void AutoComplete::SetList(const char *list) { - lb.Clear(); + lb->Clear(); char *words = new char[strlen(list) + 1]; if (words) { strcpy(words, list); char *startword = words; + char *numword = NULL; int i = 0; for (; words && words[i]; i++) { if (words[i] == separator) { words[i] = '\0'; - lb.Append(startword); + if (numword) + *numword = '\0'; + lb->Append(startword, numword?atoi(numword + 1):-1); startword = words + i + 1; + numword = NULL; + } else if (words[i] == typesep) { + numword = words + i; } } if (startword) { - lb.Append(startword); + if (numword) + *numword = '\0'; + lb->Append(startword, numword?atoi(numword + 1):-1); } delete []words; } } void AutoComplete::Show() { - lb.Show(); - lb.Select(0); + lb->Show(); + lb->Select(0); } void AutoComplete::Cancel() { - if (lb.Created()) { - lb.Destroy(); + if (lb->Created()) { + lb->Destroy(); active = false; } } void AutoComplete::Move(int delta) { - int count = lb.Length(); - int current = lb.GetSelection(); + int count = lb->Length(); + int current = lb->GetSelection(); current += delta; if (current >= count) current = count - 1; if (current < 0) current = 0; - lb.Select(current); + lb->Select(current); } void AutoComplete::Select(const char *word) { @@ -123,10 +148,10 @@ void AutoComplete::Select(const char *word) { const int maxItemLen=1000; char item[maxItemLen]; int start = 0; // lower bound of the api array block to search - int end = lb.Length() - 1; // upper bound of the api array block to search + int end = lb->Length() - 1; // upper bound of the api array block to search while ((start <= end) && (location == -1)) { // Binary searching loop int pivot = (start + end) / 2; - lb.GetValue(pivot, item, maxItemLen); + lb->GetValue(pivot, item, maxItemLen); int cond; if (ignoreCase) cond = CompareNCaseInsensitive(word, item, lenWord); @@ -135,7 +160,7 @@ void AutoComplete::Select(const char *word) { if (!cond) { // Find first match while (pivot > start) { - lb.GetValue(pivot-1, item, maxItemLen); + lb->GetValue(pivot-1, item, maxItemLen); if (ignoreCase) cond = CompareNCaseInsensitive(word, item, lenWord); else @@ -154,6 +179,6 @@ void AutoComplete::Select(const char *word) { if (location == -1 && autoHide) Cancel(); else - lb.Select(location); + lb->Select(location); } diff --git a/contrib/src/stc/scintilla/src/AutoComplete.h b/contrib/src/stc/scintilla/src/AutoComplete.h index 622a5666ec..981fb44c06 100644 --- a/contrib/src/stc/scintilla/src/AutoComplete.h +++ b/contrib/src/stc/scintilla/src/AutoComplete.h @@ -2,7 +2,7 @@ /** @file AutoComplete.h ** Defines the auto completion list box. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef AUTOCOMPLETE_H @@ -15,11 +15,12 @@ class AutoComplete { char stopChars[256]; char fillUpChars[256]; char separator; + char typesep; // Type seperator public: bool ignoreCase; bool chooseSingle; - ListBox lb; + ListBox *lb; int posStart; int startLen; /// Should autocompletion be canceled if editor's currentPos <= startPos? @@ -34,7 +35,8 @@ public: bool Active(); /// Display the auto completion list positioned to be near a character position - void Start(Window &parent, int ctrlID, int position, int startLen_); + void Start(Window &parent, int ctrlID, int position, + int startLen_, int lineHeight, bool unicodeMode); /// The stop chars are characters which, when typed, cause the auto completion list to disappear void SetStopChars(const char *stopChars_); @@ -48,6 +50,10 @@ public: void SetSeparator(char separator_); char GetSeparator(); + /// The typesep character is used for seperating the word from the type + void SetTypesep(char separator_); + char GetTypesep(); + /// The list string contains a sequence of words separated by the separator character void SetList(const char *list); diff --git a/contrib/src/stc/scintilla/src/CallTip.cxx b/contrib/src/stc/scintilla/src/CallTip.cxx index d67173b084..f95a1db148 100644 --- a/contrib/src/stc/scintilla/src/CallTip.cxx +++ b/contrib/src/stc/scintilla/src/CallTip.cxx @@ -117,19 +117,21 @@ void CallTip::PaintCT(Surface *surfaceWindow) { } PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, - const char *faceName, int size, bool unicodeMode_) { + const char *faceName, int size, + int codePage_) { if (val) delete []val; val = new char[strlen(defn) + 1]; if (!val) return PRectangle(); strcpy(val, defn); - unicodeMode = unicodeMode_; + codePage = codePage_; Surface *surfaceMeasure = Surface::Allocate(); if (!surfaceMeasure) return PRectangle(); surfaceMeasure->Init(); - surfaceMeasure->SetUnicodeMode(unicodeMode); + surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); + surfaceMeasure->SetDBCSMode(codePage); startHighlight = 0; endHighlight = 0; inCallTipMode = true; diff --git a/contrib/src/stc/scintilla/src/CallTip.h b/contrib/src/stc/scintilla/src/CallTip.h index 9f5025f63b..877d9f34e5 100644 --- a/contrib/src/stc/scintilla/src/CallTip.h +++ b/contrib/src/stc/scintilla/src/CallTip.h @@ -29,22 +29,22 @@ public: ColourPair colourSel; ColourPair colourShade; ColourPair colourLight; - bool unicodeMode; - + int codePage; + CallTip(); ~CallTip(); - + /// Claim or accept palette entries for the colours required to paint a calltip. void RefreshColourPalette(Palette &pal, bool want); - + void PaintCT(Surface *surfaceWindow); - + /// Setup the calltip and return a rectangle of the area required. - PRectangle CallTipStart(int pos, Point pt, const char *defn, - const char *faceName, int size, bool unicodeMode_); - + PRectangle CallTipStart(int pos, Point pt, const char *defn, + const char *faceName, int size, int codePage_); + void CallTipCancel(); - + /// Set a range of characters to be displayed in a highlight style. /// Commonly used to highlight the current parameter. void SetHighlight(int start, int end); diff --git a/contrib/src/stc/scintilla/src/CellBuffer.cxx b/contrib/src/stc/scintilla/src/CellBuffer.cxx index 420dee6ff7..8f292869d7 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.cxx +++ b/contrib/src/stc/scintilla/src/CellBuffer.cxx @@ -739,6 +739,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) { } bool CellBuffer::SetStyleAt(int position, char style, char mask) { + style &= mask; char curVal = ByteAt(position * 2 + 1); if ((curVal & mask) != style) { SetByteAt(position*2 + 1, static_cast((curVal & ~mask) | style)); diff --git a/contrib/src/stc/scintilla/src/CellBuffer.h b/contrib/src/stc/scintilla/src/CellBuffer.h index 5cfcbfe1f0..2866d548cb 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.h +++ b/contrib/src/stc/scintilla/src/CellBuffer.h @@ -212,7 +212,7 @@ public: int GetMark(int line); void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle); - + /// Actions without undo void BasicInsertString(int position, char *s, int insertLength); void BasicDeleteChars(int position, int deleteLength); diff --git a/contrib/src/stc/scintilla/src/Document.cxx b/contrib/src/stc/scintilla/src/Document.cxx index 7458120442..20a53b1321 100644 --- a/contrib/src/stc/scintilla/src/Document.cxx +++ b/contrib/src/stc/scintilla/src/Document.cxx @@ -2,7 +2,7 @@ /** @file Document.cxx ** Text document that handles notifications, DBCS, styling, words and end of line. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -23,6 +23,22 @@ static inline bool isspacechar(unsigned char ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } +static inline bool IsPunctuation(char ch) { + return isascii(ch) && ispunct(ch); +} + +static inline bool IsADigit(char ch) { + return isascii(ch) && isdigit(ch); +} + +static inline bool IsLowerCase(char ch) { + return isascii(ch) && islower(ch); +} + +static inline bool IsUpperCase(char ch) { + return isascii(ch) && isupper(ch); +} + Document::Document() { refCount = 0; #ifdef unix @@ -218,32 +234,12 @@ bool Document::IsCrLf(int pos) { return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } -bool Document::IsDBCS(int pos) { - if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { - unsigned char ch = static_cast(cb.CharAt(pos)); - return ch >= 0x80; - } else { - // Anchor DBCS calculations at start of line because start of line can - // not be a DBCS trail byte. - int startLine = pos; - while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n') - startLine--; - while (startLine <= pos) { - if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) { - startLine++; - if (startLine >= pos) - return true; - } - startLine++; - } - } - } - return false; -} +static const int maxBytesInDBCSCharacter=5; int Document::LenChar(int pos) { - if (IsCrLf(pos)) { + if (pos < 0) { + return 1; + } else if (IsCrLf(pos)) { return 2; } else if (SC_CP_UTF8 == dbcsCodePage) { unsigned char ch = static_cast(cb.CharAt(pos)); @@ -257,8 +253,14 @@ int Document::LenChar(int pos) { return lengthDoc -pos; else return len; - } else if (IsDBCS(pos)) { - return 2; + } else if (dbcsCodePage) { + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for (i=0; i 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n') startLine--; - bool atLeadByte = false; while (startLine < pos) { - if (atLeadByte) - atLeadByte = false; - else if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) - atLeadByte = true; - else - atLeadByte = false; - startLine++; - } + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for(i=0;i 0) - return pos + 1; - else - return pos - 1; + int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr); + if (startLine + mbsize == pos) { + return pos; + } else if (startLine + mbsize > pos) { + if (moveDir > 0) { + return startLine + mbsize; + } else { + return startLine; + } + } + startLine += mbsize; } } } @@ -524,7 +528,7 @@ bool Document::InsertString(int position, const char *s, size_t insertLength) { sWithStyle[i*2] = s[i]; sWithStyle[i*2 + 1] = 0; } - changed = InsertStyledString(position*2, sWithStyle, + changed = InsertStyledString(position*2, sWithStyle, static_cast(insertLength*2)); delete []sWithStyle; } @@ -545,11 +549,9 @@ void Document::DelCharBack(int pos) { return; } else if (IsCrLf(pos - 2)) { DeleteChars(pos - 2, 2); - } else if (SC_CP_UTF8 == dbcsCodePage) { + } else if (dbcsCodePage) { int startChar = MovePositionOutsideChar(pos - 1, -1, false); DeleteChars(startChar, pos - startChar); - } else if (IsDBCS(pos - 1)) { - DeleteChars(pos - 2, 2); } else { DeleteChars(pos - 1, 1); } @@ -745,7 +747,7 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) { } /** - * Find the start of the next word in either a forward (delta >= 0) or backwards direction + * Find the start of the next word in either a forward (delta >= 0) or backwards direction * (delta < 0). * This is looking for a transition between character classes although there is also some * additional movement to transit white space. @@ -798,7 +800,7 @@ bool Document::IsWordEndAt(int pos) { } /** - * Check that the given range is has transitions between character classes at both + * Check that the given range is has transitions between character classes at both * ends and where the characters on the inside are word or punctuation characters. */ bool Document::IsWordAt(int start, int end) { @@ -853,16 +855,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, if (!pre) return -1; - int startPos; - int endPos; + int increment = (minPos <= maxPos) ? 1 : -1; - if (minPos <= maxPos) { - startPos = minPos; - endPos = maxPos; - } else { - startPos = maxPos; - endPos = minPos; - } + int startPos = minPos; + int endPos = maxPos; // Range endpoints should not be inside DBCS characters, but just in case, move them. startPos = MovePositionOutsideChar(startPos, 1, false); @@ -878,7 +874,9 @@ long Document::FindText(int minPos, int maxPos, const char *s, // Replace: $(\1-\2) int lineRangeStart = LineFromPosition(startPos); int lineRangeEnd = LineFromPosition(endPos); - if ((startPos >= LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) { + if ((increment == 1) && + (startPos >= LineEnd(lineRangeStart)) && + (lineRangeStart < lineRangeEnd)) { // the start position is at end of line or between line end characters. lineRangeStart++; startPos = LineStart(lineRangeStart); @@ -886,27 +884,16 @@ long Document::FindText(int minPos, int maxPos, const char *s, int pos = -1; int lenRet = 0; char searchEnd = s[*length - 1]; - if (*length == 1) { - // These produce empty selections so nudge them on if needed - if (s[0] == '^') { - if (startPos == LineStart(lineRangeStart)) - startPos++; - } else if (s[0] == '$') { - if ((startPos == LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) - startPos = LineStart(lineRangeStart + 1); - } - lineRangeStart = LineFromPosition(startPos); - lineRangeEnd = LineFromPosition(endPos); - } - for (int line = lineRangeStart; line <= lineRangeEnd; line++) { + int lineRangeBreak = lineRangeEnd + increment; + for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { int startOfLine = LineStart(line); int endOfLine = LineEnd(line); - if (line == lineRangeStart) { + if ((increment == 1) && (line == lineRangeStart)) { if ((startPos != startOfLine) && (s[0] == '^')) continue; // Can't match start of line if start position after start of line startOfLine = startPos; } - if (line == lineRangeEnd) { + if ((increment == 1) && (line == lineRangeEnd)) { if ((endPos != endOfLine) && (searchEnd == '$')) continue; // Can't match end of line if end position before end of line endOfLine = endPos; @@ -916,6 +903,20 @@ long Document::FindText(int minPos, int maxPos, const char *s, if (success) { pos = pre->bopat[0]; lenRet = pre->eopat[0] - pre->bopat[0]; + if (increment == -1) { + // Check for the last match on this line. + while (success && (pre->eopat[0] < endOfLine)) { + success = pre->Execute(di, pre->eopat[0], endOfLine); + if (success) { + if (pre->eopat[0] <= minPos) { + pos = pre->bopat[0]; + lenRet = pre->eopat[0] - pre->bopat[0]; + } else { + success = 0; + } + } + } + } break; } } @@ -1033,16 +1034,17 @@ int Document::LinesTotal() { void Document::ChangeCase(Range r, bool makeUpperCase) { for (int pos = r.start; pos < r.end; pos++) { - char ch = CharAt(pos); - if (dbcsCodePage && IsDBCS(pos)) { - pos += LenChar(pos); + int len = LenChar(pos); + if (dbcsCodePage && (len > 1)) { + pos += len; } else { + char ch = CharAt(pos); if (makeUpperCase) { - if (islower(ch)) { + if (IsLowerCase(ch)) { ChangeChar(pos, static_cast(MakeUpperCase(ch))); } } else { - if (isupper(ch)) { + if (IsUpperCase(ch)) { ChangeChar(pos, static_cast(MakeLowerCase(ch))); } } @@ -1067,7 +1069,7 @@ void Document::SetWordChars(unsigned char *chars) { } } else { for (ch = 0; ch < 256; ch++) { - if (ch >= 0x80 || isalnum(ch) || ch == '_') + if (ch >= 0x80 || isalnum(ch) || ch == '_') charClass[ch] = ccWord; } } @@ -1092,6 +1094,7 @@ bool Document::SetStyleFor(int length, char style) { return false; } else { enteredCount++; + style &= stylingMask; int prevEndStyled = endStyled; if (cb.SetStyleFor(endStyled, length, style, stylingMask)) { DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, @@ -1206,7 +1209,7 @@ void Document::NotifyModified(DocModification mh) { } bool Document::IsWordPartSeparator(char ch) { - return ispunct(ch) && (WordCharClass(ch) == ccWord); + return (WordCharClass(ch) == ccWord) && IsPunctuation(ch); } int Document::WordPartLeft(int pos) { @@ -1221,31 +1224,38 @@ int Document::WordPartLeft(int pos) { if (pos > 0) { startChar = cb.CharAt(pos); --pos; - if (islower(startChar)) { - while (pos > 0 && islower(cb.CharAt(pos))) + if (IsLowerCase(startChar)) { + while (pos > 0 && IsLowerCase(cb.CharAt(pos))) --pos; - if (!isupper(cb.CharAt(pos)) && !islower(cb.CharAt(pos))) + if (!IsUpperCase(cb.CharAt(pos)) && !IsLowerCase(cb.CharAt(pos))) ++pos; - } else if (isupper(startChar)) { - while (pos > 0 && isupper(cb.CharAt(pos))) + } else if (IsUpperCase(startChar)) { + while (pos > 0 && IsUpperCase(cb.CharAt(pos))) --pos; - if (!isupper(cb.CharAt(pos))) + if (!IsUpperCase(cb.CharAt(pos))) ++pos; - } else if (isdigit(startChar)) { - while (pos > 0 && isdigit(cb.CharAt(pos))) + } else if (IsADigit(startChar)) { + while (pos > 0 && IsADigit(cb.CharAt(pos))) --pos; - if (!isdigit(cb.CharAt(pos))) + if (!IsADigit(cb.CharAt(pos))) ++pos; - } else if (ispunct(startChar)) { - while (pos > 0 && ispunct(cb.CharAt(pos))) + } else if (IsPunctuation(startChar)) { + while (pos > 0 && IsPunctuation(cb.CharAt(pos))) --pos; - if (!ispunct(cb.CharAt(pos))) + if (!IsPunctuation(cb.CharAt(pos))) ++pos; } else if (isspacechar(startChar)) { while (pos > 0 && isspacechar(cb.CharAt(pos))) --pos; if (!isspacechar(cb.CharAt(pos))) ++pos; + } else if (!isascii(startChar)) { + while (pos > 0 && !isascii(cb.CharAt(pos))) + --pos; + if (isascii(cb.CharAt(pos))) + ++pos; + } else { + ++pos; } } } @@ -1260,29 +1270,34 @@ int Document::WordPartRight(int pos) { ++pos; startChar = cb.CharAt(pos); } - if (islower(startChar)) { - while (pos < length && islower(cb.CharAt(pos))) + if (!isascii(startChar)) { + while (pos < length && !isascii(cb.CharAt(pos))) ++pos; - } else if (isupper(startChar)) { - if (islower(cb.CharAt(pos + 1))) { + } else if (IsLowerCase(startChar)) { + while (pos < length && IsLowerCase(cb.CharAt(pos))) ++pos; - while (pos < length && islower(cb.CharAt(pos))) + } else if (IsUpperCase(startChar)) { + if (IsLowerCase(cb.CharAt(pos + 1))) { + ++pos; + while (pos < length && IsLowerCase(cb.CharAt(pos))) ++pos; } else { - while (pos < length && isupper(cb.CharAt(pos))) + while (pos < length && IsUpperCase(cb.CharAt(pos))) ++pos; } - if (islower(cb.CharAt(pos)) && isupper(cb.CharAt(pos - 1))) + if (IsLowerCase(cb.CharAt(pos)) && IsUpperCase(cb.CharAt(pos - 1))) --pos; - } else if (isdigit(startChar)) { - while (pos < length && isdigit(cb.CharAt(pos))) + } else if (IsADigit(startChar)) { + while (pos < length && IsADigit(cb.CharAt(pos))) ++pos; - } else if (ispunct(startChar)) { - while (pos < length && ispunct(cb.CharAt(pos))) + } else if (IsPunctuation(startChar)) { + while (pos < length && IsPunctuation(cb.CharAt(pos))) ++pos; } else if (isspacechar(startChar)) { while (pos < length && isspacechar(cb.CharAt(pos))) ++pos; + } else { + ++pos; } return pos; } diff --git a/contrib/src/stc/scintilla/src/Document.h b/contrib/src/stc/scintilla/src/Document.h index 82931207cf..30fdc625ed 100644 --- a/contrib/src/stc/scintilla/src/Document.h +++ b/contrib/src/stc/scintilla/src/Document.h @@ -2,7 +2,7 @@ /** @file Document.h ** Text document that handles notifications, DBCS, styling, words and end of line. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef DOCUMENT_H @@ -26,10 +26,10 @@ public: Position start; Position end; - Range(Position pos=0) : + Range(Position pos=0) : start(pos), end(pos) { }; - Range(Position start_, Position end_) : + Range(Position start_, Position end_) : start(start_), end(end_) { }; @@ -60,7 +60,7 @@ public: } bool Overlaps(Range other) const { - return + return Contains(other.start) || Contains(other.end) || other.Contains(start) || @@ -88,7 +88,7 @@ public: } }; -private: +private: int refCount; CellBuffer cb; enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation }; @@ -191,7 +191,7 @@ public: int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); int NextWordStart(int pos, int delta); int Length() { return cb.Length(); } - long FindText(int minPos, int maxPos, const char *s, + long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, bool regExp, int *length); long FindText(int iMessage, unsigned long wParam, long lParam); const char *SubstituteByPosition(const char *text, int *length); @@ -222,7 +222,6 @@ public: int WordPartRight(int pos); private: - bool IsDBCS(int pos); charClassification WordCharClass(unsigned char ch); bool IsWordStartAt(int pos); bool IsWordEndAt(int pos); @@ -252,7 +251,7 @@ public: int foldLevelNow; int foldLevelPrev; - DocModification(int modificationType_, int position_=0, int length_=0, + DocModification(int modificationType_, int position_=0, int length_=0, int linesAdded_=0, const char *text_=0) : modificationType(modificationType_), position(position_), diff --git a/contrib/src/stc/scintilla/src/DocumentAccessor.cxx b/contrib/src/stc/scintilla/src/DocumentAccessor.cxx index 595edf8ba2..b7902df35a 100644 --- a/contrib/src/stc/scintilla/src/DocumentAccessor.cxx +++ b/contrib/src/stc/scintilla/src/DocumentAccessor.cxx @@ -174,7 +174,7 @@ int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnI *flags = spaceFlags; indent += SC_FOLDLEVELBASE; // if completely empty line or the start of a comment... - if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || + if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) ) return indent | SC_FOLDLEVELWHITEFLAG; else diff --git a/contrib/src/stc/scintilla/src/DocumentAccessor.h b/contrib/src/stc/scintilla/src/DocumentAccessor.h index dc591d13ec..f6523c94f9 100644 --- a/contrib/src/stc/scintilla/src/DocumentAccessor.h +++ b/contrib/src/stc/scintilla/src/DocumentAccessor.h @@ -32,9 +32,9 @@ protected: void Fill(int position); public: - DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : + DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : Accessor(), pdoc(pdoc_), props(props_), id(id_), - lenDoc(-1), validLen(0), chFlags(0), chWhile(0), + lenDoc(-1), validLen(0), chFlags(0), chWhile(0), startSeg(0), startPosStyling(0) { } ~DocumentAccessor(); @@ -47,8 +47,8 @@ public: void Flush(); int GetLineState(int line); int SetLineState(int line, int state); - int GetPropertyInt(const char *key, int defaultValue=0) { - return props.GetInt(key, defaultValue); + int GetPropertyInt(const char *key, int defaultValue=0) { + return props.GetInt(key, defaultValue); } char *GetProperties() { return props.ToString(); diff --git a/contrib/src/stc/scintilla/src/Editor.cxx b/contrib/src/stc/scintilla/src/Editor.cxx index f2ba9f088b..9e5e76ea0c 100644 --- a/contrib/src/stc/scintilla/src/Editor.cxx +++ b/contrib/src/stc/scintilla/src/Editor.cxx @@ -2,7 +2,7 @@ /** @file Editor.cxx ** Main code for the edit control. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -12,7 +12,9 @@ #include "Platform.h" +#ifndef PLAT_QT #define INCLUDE_DEPRECATED_FEATURES +#endif #include "Scintilla.h" #include "ContractionState.h" @@ -20,6 +22,7 @@ #include "CellBuffer.h" #include "KeyMap.h" #include "Indicator.h" +#include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" @@ -52,7 +55,7 @@ LineLayout::LineLayout(int maxLineLength_) : positions(0), widthLine(wrapWidthInfinite), lines(1) { - Resize(maxLineLength_); + Resize(maxLineLength_); } LineLayout::~LineLayout() { @@ -96,7 +99,7 @@ void LineLayout::SetLineStart(int line, int start) { int *newLineStarts = new int[newMaxLines]; if (!newLineStarts) return; - for (int i=0; i= rangeLine.start && braces[1] <= rangeLine.end) || - (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) { + (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) { xHighlightGuide = xHighlight; } } @@ -165,9 +168,9 @@ void LineLayoutCache::Allocate(int length_) { size = (size / 16 + 1) * 16; } if (size > 0) { - cache = new LineLayout *[size]; + cache = new LineLayout * [size]; } - for (int i=0; i size) { Deallocate(); } else if (lengthForLevel < length) { - for (int i=lengthForLevel; iInvalidate(validity_); } @@ -223,7 +226,7 @@ void LineLayoutCache::SetLevel(int level_) { } LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc) { + int linesOnScreen, int linesInDoc) { AllocateForLevel(linesOnScreen, linesInDoc); if (styleClock != styleClock_) { Invalidate(LineLayout::llCheckTextAndStyle); @@ -243,7 +246,7 @@ LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChar if (cache && (pos < length)) { if (cache[pos]) { if ((cache[pos]->lineNumber != lineNumber) || - (cache[pos]->maxLineLength < maxChars)) { + (cache[pos]->maxLineLength < maxChars)) { delete cache[pos]; cache[pos] = 0; } @@ -283,6 +286,7 @@ Editor::Editor() { printMagnification = 0; printColourMode = SC_PRINT_NORMAL; + printWrapState = eWrapWord; cursorMode = SC_CURSORNORMAL; controlCharSymbol = 0; /* Draw the control characters */ @@ -293,6 +297,7 @@ Editor::Editor() { mouseDownCaptures = true; bufferedDraw = true; + twoPhaseDraw = true; lastClickTime = 0; dwellDelay = SC_TIME_FOREVER; @@ -327,6 +332,7 @@ Editor::Editor() { xCaretMargin = 50; horizontalScrollBarVisible = true; scrollWidth = 2000; + verticalScrollBarVisible = true; endAtLastLine = true; pixmapLine = Surface::Allocate(); @@ -368,7 +374,7 @@ Editor::Editor() { wrapWidth = LineLayout::wrapWidthInfinite; docLineLastWrapped = -1; - llc.SetLevel(LineLayoutCache::llcDocument); + llc.SetLevel(LineLayoutCache::llcCaret); } Editor::~Editor() { @@ -414,7 +420,7 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) { void Editor::RefreshStyleData() { if (!stylesValid) { stylesValid = true; - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(CodePage()); if (surface) { vs.Refresh(*surface); RefreshColourPalette(palette, true); @@ -474,10 +480,10 @@ static inline bool IsControlCharacter(char ch) { const char *ControlCharacterString(unsigned char ch) { const char *reps[] = { - "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" + "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", + "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", + "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", + "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; if (ch < (sizeof(reps) / sizeof(reps[0]))) { return reps[ch]; @@ -486,6 +492,29 @@ const char *ControlCharacterString(unsigned char ch) { } } +// Convenience class to ensure LineLayout objects are always disposed. +class AutoLineLayout { + LineLayoutCache &llc; + LineLayout *ll; + AutoLineLayout &operator=(const AutoLineLayout &) { return *this; } +public: + AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {} + ~AutoLineLayout() { + llc.Dispose(ll); + ll = 0; + } + LineLayout *operator->() const { + return ll; + } + operator LineLayout *() const { + return ll; + } + void Set(LineLayout *ll_) { + llc.Dispose(ll); + ll = ll_; + } +}; + Point Editor::LocationFromPosition(int pos) { Point pt; RefreshStyleData(); @@ -494,8 +523,8 @@ Point Editor::LocationFromPosition(int pos) { int line = pdoc->LineFromPosition(pos); int lineVisible = cs.DisplayFromDoc(line); //Platform::DebugPrintf("line=%d\n", line); - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(line); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { // -1 because of adding in for visible lines in following loop. pt.y = (lineVisible - topLine - 1) * vs.lineHeight; @@ -507,8 +536,8 @@ Point Editor::LocationFromPosition(int pos) { if (posInLine > ll->maxLineLength) { pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)]; } - for (int subLine=0; subLinelines; subLine++) { - if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) { + for (int subLine = 0; subLine < ll->lines; subLine++) { + if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) { pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)]; } if (posInLine >= ll->LineStart(subLine)) { @@ -517,7 +546,6 @@ Point Editor::LocationFromPosition(int pos) { } pt.x += vs.fixedColumnWidth - xOffset; } - llc.Dispose(ll); return pt; } @@ -535,6 +563,10 @@ void Editor::SetTopLine(int topLineNew) { posTopLine = pdoc->LineStart(topLine); } +static inline bool IsEOLChar(char ch) { + return (ch == '\r') || (ch == '\n'); +} + int Editor::PositionFromLocation(Point pt) { RefreshStyleData(); pt.x = pt.x - vs.fixedColumnWidth + xOffset; @@ -547,31 +579,28 @@ int Editor::PositionFromLocation(Point pt) { int lineDoc = cs.DocFromDisplay(visibleLine); if (lineDoc >= pdoc->LinesTotal()) return pdoc->Length(); - AutoSurface surface(IsUnicodeMode()); - int retVal = 0; - LineLayout *ll = RetrieveLineLayout(lineDoc); + unsigned int posLineStart = pdoc->LineStart(lineDoc); + int retVal = posLineStart; + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); - unsigned int posLineStart = pdoc->LineStart(lineDoc); int lineStartSet = cs.DisplayFromDoc(lineDoc); int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine+1); + int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; for (int i = lineStart; i < lineEnd; i++) { if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - ll->chars[i] == '\r' || ll->chars[i] == '\n') { - llc.Dispose(ll); + IsEOLChar(ll->chars[i])) { return pdoc->MovePositionOutsideChar(i + posLineStart, 1); } } - llc.Dispose(ll); return lineEnd + posLineStart; } retVal = ll->numCharsInLine + posLineStart; } - llc.Dispose(ll); return retVal; } @@ -595,8 +624,8 @@ int Editor::PositionFromLocationClose(Point pt) { return INVALID_POSITION; if (lineDoc >= pdoc->LinesTotal()) return INVALID_POSITION; - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(lineDoc); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -604,18 +633,16 @@ int Editor::PositionFromLocationClose(Point pt) { int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine+1); + int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; for (int i = lineStart; i < lineEnd; i++) { if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - ll->chars[i] == '\r' || ll->chars[i] == '\n') { - llc.Dispose(ll); + IsEOLChar(ll->chars[i])) { return pdoc->MovePositionOutsideChar(i + posLineStart, 1); } } } } - llc.Dispose(ll); return INVALID_POSITION; } @@ -629,8 +656,8 @@ int Editor::PositionFromLineX(int lineDoc, int x) { if (lineDoc >= pdoc->LinesTotal()) return pdoc->Length(); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(lineDoc); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); int retVal = 0; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -638,17 +665,16 @@ int Editor::PositionFromLineX(int lineDoc, int x) { retVal = ll->numCharsInLine + posLineStart; int subLine = 0; int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine+1); + int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; for (int i = lineStart; i < lineEnd; i++) { if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - ll->chars[i] == '\r' || ll->chars[i] == '\n') { + IsEOLChar(ll->chars[i])) { retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1); break; } } } - llc.Dispose(ll); return retVal; } @@ -820,18 +846,45 @@ void Editor::SetEmptySelection(int currentPos_) { SetSelection(currentPos_, currentPos_); } +bool Editor::RangeContainsProtected(int start, int end) const { + if (vs.ProtectionActive()) { + if (start > end) { + int t = start; + start = end; + end = t; + } + int mask = pdoc->stylingBitsMask; + for (int pos = start; pos < end; pos++) { + if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) + return true; + } + } + return false; +} + +bool Editor::SelectionContainsProtected() const { + // TODO: make support rectangular selection + return RangeContainsProtected(anchor, currentPos); +} + int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { // Asks document to find a good position and then moves out of any invisible positions pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd); - int mask = pdoc->stylingBitsMask; - if (moveDir > 0) { - while ((pos < pdoc->Length()) && - (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected())) - pos++; - } else { - while ((pos > 0) && - (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected())) - pos--; + if (vs.ProtectionActive()) { + int mask = pdoc->stylingBitsMask; + if (moveDir > 0) { + if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) { + while ((pos < pdoc->Length()) && + (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected())) + pos++; + } + } else if (moveDir < 0) { + if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) { + while ((pos > 0) && + (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected())) + pos--; + } + } } return pos; } @@ -877,7 +930,7 @@ void Editor::SetLastXChosen() { lastXChosen = pt.x; } -void Editor::ScrollTo(int line) { +void Editor::ScrollTo(int line, bool moveThumb) { int topLineNew = Platform::Clamp(line, 0, MaxScrollPos()); if (topLineNew != topLine) { // Try to optimise small scrolls @@ -890,7 +943,9 @@ void Editor::ScrollTo(int line) { } else { Redraw(); } - SetVerticalScrollPos(); + if (moveThumb) { + SetVerticalScrollPos(); + } } } @@ -916,32 +971,31 @@ void Editor::MoveCaretInsideView(bool ensureVisible) { if (pt.y < rcClient.top) { MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top)), - false, ensureVisible); + false, ensureVisible); } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight; MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)), - false, ensureVisible); + false, ensureVisible); } } int Editor::DisplayFromPosition(int pos) { int lineDoc = pdoc->LineFromPosition(pos); int lineDisplay = cs.DisplayFromDoc(lineDoc); - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(lineDoc); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); unsigned int posLineStart = pdoc->LineStart(lineDoc); int posInLine = pos - posLineStart; lineDisplay--; // To make up for first increment ahead. - for (int subLine=0; subLinelines; subLine++) { - if (posInLine >= ll->LineStart(subLine)) { + for (int subLine = 0; subLine < ll->lines; subLine++) { + if (posInLine >= ll->LineStart(subLine)) { lineDisplay++; } } } - llc.Dispose(ll); return lineDisplay; } @@ -1166,7 +1220,7 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { } } else { // No slop if (bStrict || - (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) { + (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) { // Strict or going out of display if (bEven) { // Center caret @@ -1201,6 +1255,14 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { } if (xOffset != xOffsetNew) { xOffset = xOffsetNew; + if (xOffsetNew > 0) { + PRectangle rcText = GetTextRectangle(); + if (horizontalScrollBarVisible == true && + rcText.Width() + xOffset > scrollWidth) { + scrollWidth = xOffset + rcText.Width(); + SetScrollBars(); + } + } SetHorizontalScrollPos(); Redraw(); } @@ -1249,7 +1311,7 @@ bool Editor::WrapLines() { if (wrapState == eWrapNone) { if (wrapWidth != LineLayout::wrapWidthInfinite) { wrapWidth = LineLayout::wrapWidthInfinite; - for (int lineDoc=0; lineDocLinesTotal(); lineDoc++) { + for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) { cs.SetHeight(lineDoc, 1); } wrapOccurred = true; @@ -1265,18 +1327,17 @@ bool Editor::WrapLines() { wrapWidth = rcTextArea.Width(); // Ensure all of the document is styled. pdoc->EnsureStyledTo(pdoc->Length()); - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(CodePage()); if (surface) { int lastLineToWrap = pdoc->LinesTotal(); while (docLineLastWrapped <= lastLineToWrap) { docLineLastWrapped++; - LineLayout *ll = RetrieveLineLayout(docLineLastWrapped); + AutoLineLayout ll(llc, RetrieveLineLayout(docLineLastWrapped)); int linesWrapped = 1; if (ll) { LayoutLine(docLineLastWrapped, surface, vs, ll, wrapWidth); linesWrapped = ll->lines; } - llc.Dispose(ll); if (cs.SetHeight(docLineLastWrapped, linesWrapped)) { wrapOccurred = true; } @@ -1299,6 +1360,55 @@ bool Editor::WrapLines() { return wrapOccurred; } +void Editor::LinesJoin() { + if (!RangeContainsProtected(targetStart, targetEnd)) { + pdoc->BeginUndoAction(); + for (int pos = targetStart; pos < targetEnd; pos++) { + if (IsEOLChar(pdoc->CharAt(pos))) { + targetEnd -= pdoc->LenChar(pos); + pdoc->DelChar(pos); + } + } + pdoc->EndUndoAction(); + } +} + +const char *StringFromEOLMode(int eolMode) { + if (eolMode == SC_EOL_CRLF) { + return "\r\n"; + } else if (eolMode == SC_EOL_CR) { + return "\r"; + } else { + return "\n"; + } +} + +void Editor::LinesSplit(int pixelWidth) { + if (!RangeContainsProtected(targetStart, targetEnd)) { + if (pixelWidth == 0) { + PRectangle rcText = GetTextRectangle(); + pixelWidth = rcText.Width(); + } + int lineStart = pdoc->LineFromPosition(targetStart); + int lineEnd = pdoc->LineFromPosition(targetEnd); + const char *eol = StringFromEOLMode(pdoc->eolMode); + pdoc->BeginUndoAction(); + for (int line = lineStart; line <= lineEnd; line++) { + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(line)); + if (surface && ll) { + unsigned int posLineStart = pdoc->LineStart(line); + LayoutLine(line, surface, vs, ll, pixelWidth); + for (int subLine = 1; subLine < ll->lines; subLine++) { + pdoc->InsertString(posLineStart + subLine - 1 + ll->LineStart(subLine), eol); + targetEnd += strlen(eol); + } + } + } + pdoc->EndUndoAction(); + } +} + int Editor::SubstituteMarkerIfEmpty(int markerCheck, int markerDefault) { if (vs.markers[markerCheck].markType == SC_MARK_EMPTY) return markerDefault; @@ -1371,9 +1481,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { // Old code does not know about new markers needed to distinguish all cases int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, - SC_MARKNUM_FOLDEROPEN); + SC_MARKNUM_FOLDEROPEN); int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, - SC_MARKNUM_FOLDER); + SC_MARKNUM_FOLDER); while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) { @@ -1385,7 +1495,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { // Decide which fold indicator should be displayed level = pdoc->GetLevel(lineDoc); - int levelNext = pdoc->GetLevel(lineDoc+1); + int levelNext = pdoc->GetLevel(lineDoc + 1); int marks = pdoc->GetMark(lineDoc); if (!firstSubLine) marks = 0; @@ -1455,7 +1565,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { number[0] = '\0'; if (firstSubLine) sprintf(number, "%d", lineDoc + 1); - if (foldFlags & 64) + if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) sprintf(number, "%X", pdoc->GetLevel(lineDoc)); PRectangle rcNumber = rcMarker; // Right justify @@ -1463,9 +1573,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { int xpos = rcNumber.right - width - 3; rcNumber.left = xpos; surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font, - rcNumber.top + vs.maxAscent, number, strlen(number), - vs.styles[STYLE_LINENUMBER].fore.allocated, - vs.styles[STYLE_LINENUMBER].back.allocated); + rcNumber.top + vs.maxAscent, number, strlen(number), + vs.styles[STYLE_LINENUMBER].fore.allocated, + vs.styles[STYLE_LINENUMBER].back.allocated); } if (marks) { @@ -1518,8 +1628,8 @@ LineLayout *Editor::RetrieveLineLayout(int lineNumber) { int posLineEnd = pdoc->LineStart(lineNumber + 1); int lineCaret = pdoc->LineFromPosition(currentPos); return llc.Retrieve(lineNumber, lineCaret, - posLineEnd - posLineStart, pdoc->GetStyleClock(), - LinesOnScreen() + 1, pdoc->LinesTotal()); + posLineEnd - posLineStart, pdoc->GetStyleClock(), + LinesOnScreen() + 1, pdoc->LinesTotal()); } /** @@ -1540,7 +1650,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou int lineLength = 0; for (int cid = posLineStart; cid < posLineEnd; cid++) { char chDoc = pdoc->CharAt(cid); - if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { + if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { lineLength++; } } @@ -1554,20 +1664,20 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) { char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); - if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { - allSame = allSame && - (ll->styles[numCharsInLine] == static_cast(styleByte & styleMask)); - allSame = allSame && - (ll->indicators[numCharsInLine] == static_cast(styleByte & ~styleMask)); + if (vstyle.viewEOL || (!IsEOLChar(chDoc != '\r'))) { + allSame = allSame && + (ll->styles[numCharsInLine] == static_cast(styleByte & styleMask)); + allSame = allSame && + (ll->indicators[numCharsInLine] == static_cast(styleByte & ~styleMask)); if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) - allSame = allSame && - (ll->chars[numCharsInLine] == static_cast(toupper(chDoc))); + allSame = allSame && + (ll->chars[numCharsInLine] == static_cast(toupper(chDoc))); else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) - allSame = allSame && - (ll->chars[numCharsInLine] == static_cast(tolower(chDoc))); + allSame = allSame && + (ll->chars[numCharsInLine] == static_cast(tolower(chDoc))); else allSame = allSame && - (ll->chars[numCharsInLine] == chDoc); + (ll->chars[numCharsInLine] == chDoc); numCharsInLine++; } } @@ -1599,7 +1709,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) { char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); - if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { + if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { ll->chars[numCharsInLine] = chDoc; ll->styles[numCharsInLine] = static_cast(styleByte & styleMask); ll->indicators[numCharsInLine] = static_cast(styleByte & ~styleMask); @@ -1630,13 +1740,13 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou bool isControl = isControlNext; isControlNext = IsControlCharacter(ll->chars[charInLine + 1]); if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) || - isControl || isControlNext) { + isControl || isControlNext) { ll->positions[startseg] = 0; if (vstyle.styles[ll->styles[charInLine]].visible) { if (isControl) { if (ll->chars[charInLine] == '\t') { ll->positions[charInLine + 1] = ((((startsegx + 2) / - tabWidth) + 1) * tabWidth) - startsegx; + tabWidth) + 1) * tabWidth) - startsegx; } else if (controlCharSymbol < 32) { const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); // +3 For a blank on front and rounded edge each side: @@ -1644,7 +1754,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } else { char cc[2] = { static_cast(controlCharSymbol), '\0' }; surface->MeasureWidths(ctrlCharsFont, cc, 1, - ll->positions + startseg + 1); + ll->positions + startseg + 1); } lastSegItalics = false; } else { // Regular character @@ -1656,7 +1766,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } else { lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic; surface->MeasureWidths(vstyle.styles[ll->styles[charInLine]].font, ll->chars + startseg, - lenSeg, ll->positions + startseg + 1); + lenSeg, ll->positions + startseg + 1); } } } else { // invisible @@ -1697,19 +1807,19 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou int lastGoodBreak = 0; int lastLineStart = 0; int startOffset = 0; - int p=0; + int p = 0; while (p < ll->numCharsInLine) { - if ((ll->positions[p+1] - startOffset) >= width) { + if ((ll->positions[p + 1] - startOffset) >= width) { if (lastGoodBreak == lastLineStart) { // Try moving to start of last character if (p > 0) { lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1) - - posLineStart; + - posLineStart; } if (lastGoodBreak == lastLineStart) { // Ensure at least one character on line. - lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart +1, 1) - - posLineStart; + lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) + - posLineStart; } } lastLineStart = lastGoodBreak; @@ -1720,9 +1830,9 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou continue; } if (p > 0) { - if (ll->styles[p] != ll->styles[p-1]) { + if (ll->styles[p] != ll->styles[p - 1]) { lastGoodBreak = p; - } else if (IsSpaceOrTab(ll->chars[p-1]) && !IsSpaceOrTab(ll->chars[p])) { + } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { lastGoodBreak = p; } } @@ -1734,6 +1844,69 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } } +ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground, + ColourAllocated background, bool inSelection, int styleMain, int i, LineLayout *ll) { + if (inSelection) { + if (vsDraw.selbackset) { + if (primarySelection) + return vsDraw.selbackground.allocated; + else + return vsDraw.selbackground2.allocated; + } + } else { + if ((vsDraw.edgeState == EDGE_BACKGROUND) && + (i >= ll->edgeColumn) && + !IsEOLChar(ll->chars[i])) + return vsDraw.edgecolour.allocated; + if (overrideBackground) + return background; + } + return vsDraw.styles[styleMain].back.allocated; +} + +void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) { + Point from(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0); + PRectangle rcCopyArea(start + 1, rcSegment.top, start + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, + highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); +} + +void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, + int line, int lineEnd, int xStart, int subLine, int subLineStart, + bool overrideBackground, ColourAllocated background) { + + int styleMask = pdoc->stylingBitsMask; + PRectangle rcSegment = rcLine; + + // Fill in a PRectangle representing the end of line characters + int xEol = ll->positions[lineEnd] - subLineStart; + rcSegment.left = xEol + xStart; + rcSegment.right = xEol + vsDraw.aveCharWidth + xStart; + int posLineEnd = pdoc->LineStart(line + 1); + bool eolInSelection = (subLine == (ll->lines - 1)) && + (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd); + if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { + if (primarySelection) + surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); + else + surface->FillRectangle(rcSegment, vsDraw.selbackground2.allocated); + } else if (overrideBackground) { + surface->FillRectangle(rcSegment, background); + } else { + surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated); + } + + rcSegment.left = xEol + vsDraw.aveCharWidth + xStart; + rcSegment.right = rcLine.right; + if (overrideBackground) { + surface->FillRectangle(rcSegment, background); + } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) { + surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated); + } else { + surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); + } +} + void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) { @@ -1780,29 +1953,92 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } } + bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) && + (!overrideBackground) && (vsDraw.whitespaceBackgroundSet); + bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. int indentWidth = pdoc->indentInChars * vsDraw.spaceWidth; if (indentWidth == 0) indentWidth = pdoc->tabInChars * vsDraw.spaceWidth; int posLineStart = pdoc->LineStart(line); - int posLineEnd = pdoc->LineStart(line + 1); - int styleMask = pdoc->stylingBitsMask; int startseg = ll->LineStart(subLine); int subLineStart = ll->positions[startseg]; int lineStart = 0; int lineEnd = 0; if (subLine < ll->lines) { lineStart = ll->LineStart(subLine); - lineEnd = ll->LineStart(subLine+1); + lineEnd = ll->LineStart(subLine + 1); } - for (int i = lineStart; i < lineEnd; i++) { + int i; + + // Background drawing loop + for (i = lineStart; twoPhaseDraw && (i < lineEnd); i++) { int iDoc = i + posLineStart; // If there is the end of a style run for any reason if ((ll->styles[i] != ll->styles[i + 1]) || - i == (lineEnd-1) || + i == (lineEnd - 1) || + IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) || + ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) || + (i == (ll->edgeColumn - 1))) { + rcSegment.left = ll->positions[startseg] + xStart - subLineStart; + rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; + // Only try to draw if really visible - enhances performance by not calling environment to + // draw strings that are completely past the right side of the window. + if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { + int styleMain = ll->styles[i]; + bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, styleMain, i, ll); + if (ll->chars[i] == '\t') { + // Tab display + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) + textBack = vsDraw.whitespaceBackground.allocated; + surface->FillRectangle(rcSegment, textBack); + } else if (IsControlCharacter(ll->chars[i])) { + // Control character display + inIndentation = false; + surface->FillRectangle(rcSegment, textBack); + } else { + // Normal text display + surface->FillRectangle(rcSegment, textBack); + if (vsDraw.viewWhitespace != wsInvisible || + (inIndentation && vsDraw.viewIndentationGuides)) { + for (int cpos = 0; cpos <= i - startseg; cpos++) { + if (ll->chars[cpos + startseg] == ' ') { + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { + PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, + ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); + surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated); + } + } else { + inIndentation = false; + } + } + } + } + } + startseg = i + 1; + } + } + + if (twoPhaseDraw) { + DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, + xStart, subLine, subLineStart, overrideBackground, background); + } + + inIndentation = subLine == 0; // Do not handle indentation except on first subline. + startseg = ll->LineStart(subLine); + // Foreground drawing loop + for (i = lineStart; i < lineEnd; i++) { + + int iDoc = i + posLineStart; + // If there is the end of a style run for any reason + if ((ll->styles[i] != ll->styles[i + 1]) || + i == (lineEnd - 1) || IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) || ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) || (i == (ll->edgeColumn - 1))) { @@ -1812,30 +2048,21 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis // draw strings that are completely past the right side of the window. if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { int styleMain = ll->styles[i]; - ColourAllocated textBack = vsDraw.styles[styleMain].back.allocated; ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated; Font &textFont = vsDraw.styles[styleMain].font; bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); - if (inSelection) { - if (vsDraw.selbackset) { - if (primarySelection) - textBack = vsDraw.selbackground.allocated; - else - textBack = vsDraw.selbackground2.allocated; - } - if (vsDraw.selforeset) - textFore = vsDraw.selforeground.allocated; - } else { - if (overrideBackground) - textBack = background; - if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll->edgeColumn) && (ll->chars[i] != '\n') && (ll->chars[i] != '\r')) - textBack = vsDraw.edgecolour.allocated; + if (inSelection && (vsDraw.selforeset)) { + textFore = vsDraw.selforeground.allocated; } + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, styleMain, i, ll); if (ll->chars[i] == '\t') { - // Manage tab display - if (!overrideBackground && vsDraw.whitespaceBackgroundSet && (vsDraw.viewWhitespace != wsInvisible) && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) - textBack = vsDraw.whitespaceBackground.allocated; - surface->FillRectangle(rcSegment, textBack); + // Tab display + if (!twoPhaseDraw) { + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) + textBack = vsDraw.whitespaceBackground.allocated; + surface->FillRectangle(rcSegment, textBack); + } if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) { if (vsDraw.whitespaceForegroundSet) textFore = vsDraw.whitespaceForeground.allocated; @@ -1844,29 +2071,29 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis if (inIndentation && vsDraw.viewIndentationGuides) { for (int xIG = ll->positions[i] / indentWidth * indentWidth; xIG < ll->positions[i + 1]; xIG += indentWidth) { if (xIG >= ll->positions[i] && xIG > 0) { - Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); - PRectangle rcCopyArea(xIG + xStart + 1, rcSegment.top, xIG + xStart + 2, rcSegment.bottom); - surface->Copy(rcCopyArea, from, (ll->xHighlightGuide == xIG) ? - *pixmapIndentGuideHighlight : *pixmapIndentGuide); + DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment, + (ll->xHighlightGuide == xIG)); } } } if (vsDraw.viewWhitespace != wsInvisible) { if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, - rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); + rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); } } } else if (IsControlCharacter(ll->chars[i])) { - // Manage control character display + // Control character display inIndentation = false; if (controlCharSymbol < 32) { // Draw the character const char *ctrlChar = ControlCharacterString(ll->chars[i]); - surface->FillRectangle(rcSegment, textBack); + if (!twoPhaseDraw) { + surface->FillRectangle(rcSegment, textBack); + } int normalCharHeight = surface->Ascent(ctrlCharsFont) - - surface->InternalLeading(ctrlCharsFont); + surface->InternalLeading(ctrlCharsFont); PRectangle rcCChar = rcSegment; rcCChar.left = rcCChar.left + 1; rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; @@ -1879,19 +2106,27 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis rcChar.left++; rcChar.right--; surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), - textBack, textFore); + rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), + textBack, textFore); } else { char cc[2] = { static_cast(controlCharSymbol), '\0' }; surface->DrawTextNoClip(rcSegment, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, - cc, 1, textBack, textFore); + rcSegment.top + vsDraw.maxAscent, + cc, 1, textBack, textFore); } } else { - // Manage normal display - surface->DrawTextNoClip(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, - i - startseg + 1, textFore, textBack); + // Normal text display + if (vsDraw.styles[styleMain].visible) { + if (twoPhaseDraw) { + surface->DrawTextTransparent(rcSegment, textFont, + rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, + i - startseg + 1, textFore); + } else { + surface->DrawTextNoClip(rcSegment, textFont, + rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, + i - startseg + 1, textFore, textBack); + } + } if (vsDraw.viewWhitespace != wsInvisible || (inIndentation && vsDraw.viewIndentationGuides)) { for (int cpos = 0; cpos <= i - startseg; cpos++) { @@ -1901,12 +2136,13 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis textFore = vsDraw.whitespaceForeground.allocated; if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2; - if (!overrideBackground && vsDraw.whitespaceBackgroundSet) { + if (!twoPhaseDraw && drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { textBack = vsDraw.whitespaceBackground.allocated; PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); surface->FillRectangle(rcSpace, textBack); } - PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); + PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); rcDot.right = rcDot.left + 1; rcDot.bottom = rcDot.top + 1; surface->FillRectangle(rcDot, textFore); @@ -1915,10 +2151,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis if (inIndentation && vsDraw.viewIndentationGuides) { int startSpace = ll->positions[cpos + startseg]; if (startSpace > 0 && (startSpace % indentWidth == 0)) { - Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); - PRectangle rcCopyArea(startSpace + xStart + 1, rcSegment.top, startSpace + xStart + 2, rcSegment.bottom); - surface->Copy(rcCopyArea, from, (ll->xHighlightGuide == ll->positions[cpos + startseg]) ? - *pixmapIndentGuideHighlight : *pixmapIndentGuide); + DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment, + (ll->xHighlightGuide == ll->positions[cpos + startseg])); } } } else { @@ -1964,31 +2198,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } // End of the drawing of the current line - // Fill in a PRectangle representing the end of line characters - int xEol = ll->positions[lineEnd] - subLineStart; - rcSegment.left = xEol + xStart; - rcSegment.right = xEol + vsDraw.aveCharWidth + xStart; - bool eolInSelection = (subLine == (ll->lines-1)) && - (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd); - if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { - if (primarySelection) - surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); - else - surface->FillRectangle(rcSegment, vsDraw.selbackground2.allocated); - } else if (overrideBackground) { - surface->FillRectangle(rcSegment, background); - } else { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated); - } - - rcSegment.left = xEol + vsDraw.aveCharWidth + xStart; - rcSegment.right = rcLine.right; - if (overrideBackground) { - surface->FillRectangle(rcSegment, background); - } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated); - } else { - surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); + if (!twoPhaseDraw) { + DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, + xStart, subLine, subLineStart, overrideBackground, background); } if (vsDraw.edgeState == EDGE_LINE) { @@ -1999,43 +2211,44 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } } -void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { - //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n", - // paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); - - RefreshStyleData(); - - PRectangle rcClient = GetClientRectangle(); - //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", - // rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); - - if (WrapLines()) { - // The wrapping process has changed the height of some lines so abandon this - // paint for a complete repaint. - if (AbandonPaint()) { - return; - } - } - +void Editor::RefreshPixMaps(Surface *surfaceWindow) { if (!pixmapSelPattern->Initialised()) { - pixmapSelPattern->InitPixMap(8, 8, surfaceWindow); - // This complex procedure is to reproduce the checker board dithered pattern used by windows + const int patternSize=8; + pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow); + // This complex procedure is to reproduce the checkerboard dithered pattern used by windows // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half // way between the chrome colour and the chrome highlight colour making a nice transition // between the window chrome and the content area. And it works in low colour depths. - PRectangle rcPattern(0, 0, 8, 8); - if (vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff)) { - pixmapSelPattern->FillRectangle(rcPattern, vs.selbar.allocated); - pixmapSelPattern->PenColour(vs.selbarlight.allocated); - for (int stripe = 0; stripe < 8; stripe++) { - pixmapSelPattern->MoveTo(0, stripe * 2); - pixmapSelPattern->LineTo(8, stripe * 2 - 8); - } - } else { + PRectangle rcPattern(0, 0, patternSize, patternSize); + + // Initialize default colours based on the chrome colour scheme. Typically the highlight is white. + ColourAllocated colourFMFill = vs.selbar.allocated; + ColourAllocated colourFMStripes = vs.selbarlight.allocated; + + if (!(vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff))) { // User has chosen an unusual chrome colour scheme so just use the highlight edge colour. - pixmapSelPattern->FillRectangle(rcPattern, vs.selbarlight.allocated); + // (Typically, the highlight colour is white.) + colourFMFill = vs.selbarlight.allocated; + } + + if (vs.foldmarginColourSet) { + // override default fold margin colour + colourFMFill = vs.foldmarginColour.allocated; + } + if (vs.foldmarginHighlightColourSet) { + // override default fold margin highlight colour + colourFMStripes = vs.foldmarginHighlightColour.allocated; + } + + pixmapSelPattern->FillRectangle(rcPattern, colourFMFill); + pixmapSelPattern->PenColour(colourFMStripes); + for (int stripe = 0; stripe < patternSize; stripe++) { + // Alternating 1 pixel stripes is same as checkerboard. + pixmapSelPattern->MoveTo(0, stripe * 2); + pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize); } } + if (!pixmapIndentGuide->Initialised()) { // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow); @@ -2055,12 +2268,26 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (bufferedDraw) { if (!pixmapLine->Initialised()) { + PRectangle rcClient = GetClientRectangle(); pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(), - surfaceWindow); + surfaceWindow); pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, - rcClient.Height(), surfaceWindow); + rcClient.Height(), surfaceWindow); } } +} + +void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { + //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n", + // paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); + + RefreshStyleData(); + + RefreshPixMaps(surfaceWindow); + + PRectangle rcClient = GetClientRectangle(); + //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", + // rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); surfaceWindow->SetPalette(&palette, true); pixmapLine->SetPalette(&palette, !hasFocus); @@ -2090,6 +2317,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { PaintSelMargin(surfaceWindow, rcArea); + if (WrapLines()) { + // The wrapping process has changed the height of some lines so abandon this + // paint for a complete repaint. + if (AbandonPaint()) { + return; + } + } + PRectangle rcRightMargin = rcClient; rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; if (rcArea.Intersects(rcRightMargin)) { @@ -2119,6 +2354,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface = pixmapLine; } surface->SetUnicodeMode(IsUnicodeMode()); + surface->SetDBCSMode(CodePage()); int visibleLine = topLine + screenLinePaintFirst; @@ -2140,7 +2376,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //double durCopy = 0.0; //ElapsedTime etWhole; int lineDocPrevious = -1; // Used to avoid laying out one document line multiple times - LineLayout *ll = 0; + AutoLineLayout ll(llc, 0); while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) { int lineDoc = cs.DocFromDisplay(visibleLine); @@ -2153,8 +2389,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // and determine the x position at which each character starts. //ElapsedTime et; if (lineDoc != lineDocPrevious) { - llc.Dispose(ll); - ll = RetrieveLineLayout(lineDoc); + ll.Set(RetrieveLineLayout(lineDoc)); LayoutLine(lineDoc, surface, vs, ll, wrapWidth); lineDocPrevious = lineDoc; } @@ -2177,7 +2412,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1)); // Highlight the current braces if any ll->SetBracesHighlight(rangeLine, braces, static_cast(bracesMatchStyle), - highlightGuideColumn * vs.spaceWidth); + highlightGuideColumn * vs.spaceWidth); // Draw the line DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine); @@ -2187,26 +2422,68 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { ll->RestoreBracesHighlight(rangeLine, braces); bool expanded = cs.GetExpanded(lineDoc); - if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) { - if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) { + if ((foldFlags & SC_FOLDFLAG_BOX) == 0) { + // Paint the line above the fold + if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED)) + || + (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) { + if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) { + PRectangle rcFoldLine = rcLine; + rcFoldLine.bottom = rcFoldLine.top + 1; + surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); + } + } + // Paint the line below the fold + if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED)) + || + (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) { + if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) { + PRectangle rcFoldLine = rcLine; + rcFoldLine.top = rcFoldLine.bottom - 1; + surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); + } + } + } else { + int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; + int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; + int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK); + int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + // Draw line above fold + if ((FoldLevelPrev < FoldLevelCurr) + || + (FoldLevelFlags & SC_FOLDLEVELBOXHEADERFLAG + && + (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELBOXFOOTERFLAG) == 0)) { PRectangle rcFoldLine = rcLine; rcFoldLine.bottom = rcFoldLine.top + 1; + rcFoldLine.left += xStart + FoldLevelCurr * vs.spaceWidth * indentationStep - 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } - } - if ( (expanded && (foldFlags & 8)) || (!expanded && (foldFlags & 16)) ) { - if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) { + + // Line below the fold (or below a contracted fold) + if (FoldLevelFlags & SC_FOLDLEVELBOXFOOTERFLAG + || + (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) { PRectangle rcFoldLine = rcLine; rcFoldLine.top = rcFoldLine.bottom - 1; + rcFoldLine.left += xStart + (FoldLevelCurr) * vs.spaceWidth * indentationStep - 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } + + PRectangle rcBoxLine = rcLine; + // Draw vertical line for every fold level + for (int i = 0; i <= FoldLevelCurr; i++) { + rcBoxLine.left = xStart + i * vs.spaceWidth * indentationStep - 1; + rcBoxLine.right = rcBoxLine.left + 1; + surface->FillRectangle(rcBoxLine, vs.styles[STYLE_DEFAULT].fore.allocated); + } } // Draw the Caret if (lineDoc == lineCaret) { int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength); if ((offset >= ll->LineStart(subLine)) && - ((offset < ll->LineStart(subLine+1)) || offset == ll->numCharsInLine)) { + ((offset < ll->LineStart(subLine + 1)) || offset == ll->numCharsInLine)) { int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart; int widthOverstrikeCaret; if (posCaret == pdoc->Length()) { // At end of document @@ -2244,7 +2521,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (bufferedDraw) { Point from(vs.fixedColumnWidth, 0); PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen, - rcClient.right, yposScreen + vs.lineHeight); + rcClient.right, yposScreen + vs.lineHeight); surfaceWindow->Copy(rcCopyArea, from, *pixmapLine); } //durCopy += et.Duration(true); @@ -2258,7 +2535,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { visibleLine++; //gdk_flush(); } - llc.Dispose(ll); //if (durPaint < 0.00000001) // durPaint = 0.00000001; @@ -2307,10 +2583,10 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; - AutoSurface surface(pfr->hdc, IsUnicodeMode()); + AutoSurface surface(pfr->hdc, CodePage()); if (!surface) return 0; - AutoSurface surfaceMeasure(pfr->hdcTarget, IsUnicodeMode()); + AutoSurface surfaceMeasure(pfr->hdcTarget, CodePage()); if (!surfaceMeasure) { return 0; } @@ -2364,8 +2640,8 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { // Determining width must hapen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { - lineNumberWidth = surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, - "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace)); + lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, + "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; } @@ -2373,12 +2649,12 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1; if (linePrintLast < linePrintStart) linePrintLast = linePrintStart; - int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax - 1); + int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax); if (linePrintLast > linePrintMax) linePrintLast = linePrintMax; //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n", - // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight, - // surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font)); + // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight, + // surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font)); int endPosPrint = pdoc->Length(); if (linePrintLast < pdoc->LinesTotal()) endPosPrint = pdoc->LineStart(linePrintLast + 1); @@ -2388,61 +2664,101 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth; int ypos = pfr->rc.top; - int line = linePrintStart; - if (draw) { // Otherwise just measuring + int lineDoc = linePrintStart; - while (line <= linePrintLast && ypos < pfr->rc.bottom) { + int nPrintPos = pfr->chrg.cpMin; + int visibleLine = 0; + int widthPrint = pfr->rc.Width() - lineNumberWidth; + if (printWrapState == eWrapNone) + widthPrint = LineLayout::wrapWidthInfinite; - // When printing, the hdc and hdcTarget may be the same, so - // changing the state of surfaceMeasure may change the underlying - // state of surface. Therefore, any cached state is discarded before - // using each surface. - surfaceMeasure->FlushCachedState(); + while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { - // Copy this line and its styles from the document into local arrays - // and determine the x position at which each character starts. - LineLayout ll(8000); - LayoutLine(line, surfaceMeasure, vsPrint, &ll); - ll.selStart = -1; - ll.selEnd = -1; - ll.containsCaret = false; + // When printing, the hdc and hdcTarget may be the same, so + // changing the state of surfaceMeasure may change the underlying + // state of surface. Therefore, any cached state is discarded before + // using each surface. + surfaceMeasure->FlushCachedState(); - PRectangle rcLine; - rcLine.left = pfr->rc.left + lineNumberWidth; - rcLine.top = ypos; - rcLine.right = pfr->rc.right; - rcLine.bottom = ypos + vsPrint.lineHeight; + // Copy this line and its styles from the document into local arrays + // and determine the x position at which each character starts. + LineLayout ll(8000); + LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint); - if (lineNumberWidth) { - char number[100]; - sprintf(number, "%d" lineNumberPrintSpace, line + 1); - PRectangle rcNumber = rcLine; - rcNumber.right = rcNumber.left + lineNumberWidth; - // Right justify - rcNumber.left -= - surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); - surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, - ypos + vsPrint.maxAscent, number, strlen(number), - vsPrint.styles[STYLE_LINENUMBER].fore.allocated, - vsPrint.styles[STYLE_LINENUMBER].back.allocated); + ll.selStart = -1; + ll.selEnd = -1; + ll.containsCaret = false; + + PRectangle rcLine; + rcLine.left = pfr->rc.left + lineNumberWidth; + rcLine.top = ypos; + rcLine.right = pfr->rc.right - 1; + rcLine.bottom = ypos + vsPrint.lineHeight; + + // When document line is wrapped over multiple display lines, find where + // to start printing from to ensure a particular position is on the first + // line of the page. + if (visibleLine == 0) { + int startWithinLine = nPrintPos - pdoc->LineStart(lineDoc); + for (int iwl = 0; iwl < ll.lines - 1; iwl++) { + if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) { + visibleLine = -iwl; + } } - // Draw the line - surface->FlushCachedState(); - DrawLine(surface, vsPrint, line, line, xStart, rcLine, &ll); - - ypos += vsPrint.lineHeight; - line++; + if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) { + visibleLine = -(ll.lines - 1); + } } + + if (draw && lineNumberWidth && + (ypos + vsPrint.lineHeight <= pfr->rc.bottom) && + (visibleLine >= 0)) { + char number[100]; + sprintf(number, "%d" lineNumberPrintSpace, lineDoc + 1); + PRectangle rcNumber = rcLine; + rcNumber.right = rcNumber.left + lineNumberWidth; + // Right justify + rcNumber.left -= surfaceMeasure->WidthText( + vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); + surface->FlushCachedState(); + surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, + ypos + vsPrint.maxAscent, number, strlen(number), + vsPrint.styles[STYLE_LINENUMBER].fore.allocated, + vsPrint.styles[STYLE_LINENUMBER].back.allocated); + } + + // Draw the line + surface->FlushCachedState(); + + for (int iwl = 0; iwl < ll.lines; iwl++) { + if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) { + if (visibleLine >= 0) { + if (draw) { + rcLine.top = ypos; + rcLine.bottom = ypos + vsPrint.lineHeight; + DrawLine(surface, vsPrint, lineDoc, visibleLine, xStart, rcLine, &ll, iwl); + } + ypos += vsPrint.lineHeight; + } + visibleLine++; + if (iwl == ll.lines - 1) + nPrintPos = pdoc->LineStart(lineDoc + 1); + else + nPrintPos += ll.LineStart(iwl + 1) - ll.LineStart(iwl); + } + } + + ++lineDoc; } - return endPosPrint; + return nPrintPos; } int Editor::TextWidth(int style, const char *text) { RefreshStyleData(); - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(CodePage()); if (surface) { return surface->WidthText(vs.styles[style].font, text, strlen(text)); } else { @@ -2451,8 +2767,7 @@ int Editor::TextWidth(int style, const char *text) { } // Empty method is overridden on GTK+ to show / hide scrollbars -void Editor::ReconfigureScrollBars() { -} +void Editor::ReconfigureScrollBars() {} void Editor::SetScrollBars() { RefreshStyleData(); @@ -2499,9 +2814,9 @@ void Editor::AddChar(char ch) { void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { bool wasSelection = currentPos != anchor; ClearSelection(); - if (inOverstrike && !wasSelection) { + if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) { if (currentPos < (pdoc->Length() - 1)) { - if ((pdoc->CharAt(currentPos) != '\r') && (pdoc->CharAt(currentPos) != '\n')) { + if (!IsEOLChar(pdoc->CharAt(currentPos))) { pdoc->DelChar(currentPos); } } @@ -2516,7 +2831,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { if (treatAsDBCS) { NotifyChar((static_cast(s[0]) << 8) | - static_cast(s[1])); + static_cast(s[1])); } else { int byte = static_cast(s[0]); if ((byte < 0xC0) || (1 == len)) { @@ -2542,7 +2857,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { if (((byte2 & 0xC0) == 0x80) && ((byte3 & 0xC0) == 0x80)) { // Three-byte-character lead byte followed by two trail bytes. byte = (((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | - (byte3 & 0x3F)); + (byte3 & 0x3F)); } // A three-byte-character lead-byte not followed by two trail-bytes // represents itself. @@ -2553,29 +2868,31 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { } void Editor::ClearSelection() { - if (selType == selRectangle) { - pdoc->BeginUndoAction(); - int lineStart = pdoc->LineFromPosition(SelectionStart()); - int lineEnd = pdoc->LineFromPosition(SelectionEnd()); - int startPos = SelectionStart(); - for (int line = lineEnd; line >= lineStart; line--) { - startPos = SelectionStart(line); - unsigned int chars = SelectionEnd(line) - startPos; - if (0 != chars) { - pdoc->DeleteChars(startPos, chars); - } - } - SetEmptySelection(startPos); - pdoc->EndUndoAction(); - selType = selStream; - } else { - int startPos = SelectionStart(); - unsigned int chars = SelectionEnd() - startPos; - SetEmptySelection(startPos); - if (0 != chars) { + if (!SelectionContainsProtected()) { + if (selType == selRectangle) { pdoc->BeginUndoAction(); - pdoc->DeleteChars(startPos, chars); + int lineStart = pdoc->LineFromPosition(SelectionStart()); + int lineEnd = pdoc->LineFromPosition(SelectionEnd()); + int startPos = SelectionStart(); + for (int line = lineEnd; line >= lineStart; line--) { + startPos = SelectionStart(line); + unsigned int chars = SelectionEnd(line) - startPos; + if (0 != chars) { + pdoc->DeleteChars(startPos, chars); + } + } + SetEmptySelection(startPos); pdoc->EndUndoAction(); + selType = selStream; + } else { + int startPos = SelectionStart(); + unsigned int chars = SelectionEnd() - startPos; + SetEmptySelection(startPos); + if (0 != chars) { + pdoc->BeginUndoAction(); + pdoc->DeleteChars(startPos, chars); + pdoc->EndUndoAction(); + } } } } @@ -2603,14 +2920,14 @@ void Editor::ClearDocumentStyle() { } void Editor::Cut() { - if (!pdoc->IsReadOnly()) { + if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) { Copy(); ClearSelection(); } } void Editor::PasteRectangular(int pos, const char *ptr, int len) { - if (pdoc->IsReadOnly()) { + if (pdoc->IsReadOnly() || SelectionContainsProtected()) { return; } currentPos = pos; @@ -2619,7 +2936,7 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { bool prevCr = false; pdoc->BeginUndoAction(); for (int i = 0; i < len; i++) { - if ((ptr[i] == '\r') || (ptr[i] == '\n')) { + if (IsEOLChar(ptr[i])) { if ((ptr[i] == '\r') || (!prevCr)) line++; if (line >= pdoc->LinesTotal()) { @@ -2648,12 +2965,14 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { } bool Editor::CanPaste() { - return !pdoc->IsReadOnly(); + return !pdoc->IsReadOnly() && !SelectionContainsProtected(); } void Editor::Clear() { if (currentPos == anchor) { - DelChar(); + if (!RangeContainsProtected(currentPos, currentPos + 1)) { + DelChar(); + } } else { ClearSelection(); } @@ -2683,29 +3002,33 @@ void Editor::Redo() { } void Editor::DelChar() { - pdoc->DelChar(currentPos); + if (!RangeContainsProtected(currentPos, currentPos + 1)) { + pdoc->DelChar(currentPos); + } // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); } void Editor::DelCharBack(bool allowLineStartDeletion) { if (currentPos == anchor) { - int lineCurrentPos = pdoc->LineFromPosition(currentPos); - if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) { - if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) && - pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) { - pdoc->BeginUndoAction(); - int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); - if (indentation % indentationStep == 0) { - pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); + if (!RangeContainsProtected(currentPos - 1, currentPos)) { + int lineCurrentPos = pdoc->LineFromPosition(currentPos); + if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) { + if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) && + pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) { + pdoc->BeginUndoAction(); + int indentation = pdoc->GetLineIndentation(lineCurrentPos); + int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + if (indentation % indentationStep == 0) { + pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); + } else { + pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep)); + } + SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); + pdoc->EndUndoAction(); } else { - pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep)); + pdoc->DelCharBack(currentPos); } - SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); - pdoc->EndUndoAction(); - } else { - pdoc->DelCharBack(currentPos); } } } else { @@ -2841,23 +3164,22 @@ void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) { void Editor::CheckModificationForWrap(DocModification mh) { if ((mh.modificationType & SC_MOD_INSERTTEXT) || - (mh.modificationType & SC_MOD_DELETETEXT)) { + (mh.modificationType & SC_MOD_DELETETEXT)) { llc.Invalidate(LineLayout::llCheckTextAndStyle); if (wrapState != eWrapNone) { int lineDoc = pdoc->LineFromPosition(mh.position); if (mh.linesAdded == 0) { - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(lineDoc); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); if (cs.GetHeight(lineDoc) != ll->lines) { - NeedWrapping(lineDoc-1); + NeedWrapping(lineDoc - 1); Redraw(); } } else { NeedWrapping(lineDoc); } - llc.Dispose(ll); } else { NeedWrapping(lineDoc); } @@ -3004,6 +3326,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_REPLACESEL: case SCI_ADDTEXT: case SCI_INSERTTEXT: + case SCI_APPENDTEXT: case SCI_CLEARALL: case SCI_SELECTALL: case SCI_GOTOLINE: @@ -3054,6 +3377,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_LINECUT: case SCI_LINEDELETE: case SCI_LINETRANSPOSE: + case SCI_LINEDUPLICATE: case SCI_LOWERCASE: case SCI_UPPERCASE: case SCI_LINESCROLLDOWN: @@ -3070,7 +3394,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_NEWLINE: default: // printf("Filtered out %ld of macro recording\n", iMessage); - return; + return ; } // Send notification @@ -3154,6 +3478,17 @@ void Editor::LineTranspose() { } } +void Editor::LineDuplicate() { + int line = pdoc->LineFromPosition(currentPos); + int start = pdoc->LineStart(line); + int end = pdoc->LineEnd(line); + char *thisLine = CopyRange(start, end); + const char *eol = StringFromEOLMode(pdoc->eolMode); + pdoc->InsertString(end, eol); + pdoc->InsertString(end + strlen(eol), thisLine, end - start); + delete []thisLine; +} + void Editor::CancelModes() {} void Editor::NewLine() { @@ -3178,7 +3513,7 @@ void Editor::NewLine() { void Editor::CursorUpOrDown(int direction, bool extend) { Point pt = LocationFromPosition(currentPos); int posNew = PositionFromLocation( - Point(lastXChosen, pt.y + direction * vs.lineHeight)); + Point(lastXChosen, pt.y + direction * vs.lineHeight)); if (direction < 0) { // Line wrapping may lead to a location on the same line, so // seek back if that is the case. @@ -3196,29 +3531,28 @@ void Editor::CursorUpOrDown(int direction, bool extend) { int Editor::StartEndDisplayLine(int pos, bool start) { RefreshStyleData(); int line = pdoc->LineFromPosition(pos); - AutoSurface surface(IsUnicodeMode()); - LineLayout *ll = RetrieveLineLayout(line); + AutoSurface surface(CodePage()); + AutoLineLayout ll(llc, RetrieveLineLayout(line)); int posRet = INVALID_POSITION; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, wrapWidth); int posInLine = pos - posLineStart; if (posInLine <= ll->maxLineLength) { - for (int subLine=0; subLinelines; subLine++) { - if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) { + for (int subLine = 0; subLine < ll->lines; subLine++) { + if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) { if (start) { posRet = ll->LineStart(subLine) + posLineStart; } else { if (subLine == ll->lines - 1) - posRet = ll->LineStart(subLine+1) + posLineStart; + posRet = ll->LineStart(subLine + 1) + posLineStart; else - posRet = ll->LineStart(subLine+1) + posLineStart - 1; + posRet = ll->LineStart(subLine + 1) + posLineStart - 1; } } } } } - llc.Dispose(ll); if (posRet == INVALID_POSITION) { return pos; } else { @@ -3321,10 +3655,10 @@ int Editor::KeyCommand(unsigned int iMessage) { SetLastXChosen(); break; case SCI_PAGEUP: - PageMove( -1); + PageMove(-1); break; case SCI_PAGEUPEXTEND: - PageMove( -1, true); + PageMove(-1, true); break; case SCI_PAGEDOWN: PageMove(1); @@ -3338,7 +3672,7 @@ int Editor::KeyCommand(unsigned int iMessage) { ShowCaretAtCurrentPosition(); NotifyUpdateUI(); break; - case SCI_CANCEL: // Cancel any modes - handled in subclass + case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text CancelModes(); break; @@ -3438,6 +3772,9 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_LINETRANSPOSE: LineTranspose(); break; + case SCI_LINEDUPLICATE: + LineDuplicate(); + break; case SCI_LOWERCASE: ChangeCaseOfSelection(false); break; @@ -3462,22 +3799,22 @@ int Editor::KeyCommand(unsigned int iMessage) { break; case SCI_HOMEDISPLAY: MovePositionTo(MovePositionSoVisible( - StartEndDisplayLine(currentPos, true), -1)); + StartEndDisplayLine(currentPos, true), -1)); SetLastXChosen(); break; case SCI_HOMEDISPLAYEXTEND: MovePositionTo(MovePositionSoVisible( - StartEndDisplayLine(currentPos, true), -1), true); + StartEndDisplayLine(currentPos, true), -1), true); SetLastXChosen(); break; case SCI_LINEENDDISPLAY: MovePositionTo(MovePositionSoVisible( - StartEndDisplayLine(currentPos, false), 1)); + StartEndDisplayLine(currentPos, false), 1)); SetLastXChosen(); break; case SCI_LINEENDDISPLAYEXTEND: MovePositionTo(MovePositionSoVisible( - StartEndDisplayLine(currentPos, false), 1), true); + StartEndDisplayLine(currentPos, false), 1), true); SetLastXChosen(); break; } @@ -3592,7 +3929,7 @@ void Editor::Indent(bool forwards) { * @return The position of the found text, -1 if not found. */ long Editor::FindText( - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range. @@ -3632,8 +3969,8 @@ void Editor::SearchAnchor() { * @return The position of the found text, -1 if not found. */ long Editor::SearchText( - unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. + uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. sptr_t lParam) { ///< The text to search for. @@ -3967,8 +4304,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b lineAnchor = LineFromLocation(pt); SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor)); //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos); - } - else { + } else { SetEmptySelection(currentPos); } //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos); @@ -4072,6 +4408,9 @@ void Editor::ButtonMove(Point pt) { PRectangle rcClient = GetClientRectangle(); if (pt.y > rcClient.bottom) { int lineMove = cs.DisplayFromDoc(LineFromLocation(pt)); + if (lineMove < 0) { + lineMove = cs.DisplayFromDoc(pdoc->LinesTotal()-1); + } ScrollTo(lineMove - LinesOnScreen() + 5); Redraw(); } else if (pt.y < rcClient.top) { @@ -4117,7 +4456,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { if (drag.len) { if (ctrl) { if (pdoc->InsertString(newPos, drag.s, drag.len)) { - SetSelection(newPos, newPos + drag.len); + SetSelection(newPos, newPos + drag.len); } } else if (newPos < selStart) { pdoc->DeleteChars(selStart, drag.len); @@ -4169,8 +4508,8 @@ void Editor::Tick() { } } if ((dwellDelay < SC_TIME_FOREVER) && - (ticksToDwell > 0) && - (!HaveMouseCapture())) { + (ticksToDwell > 0) && + (!HaveMouseCapture())) { ticksToDwell -= timer.tickSize; if (ticksToDwell <= 0) { dwelling = true; @@ -4407,7 +4746,7 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) { SetVerticalScrollPos(); Redraw(); } else if ((lineDisplay > topLine + LinesOnScreen() - 1) || - ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) { + ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) { SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); @@ -4444,6 +4783,13 @@ bool Editor::IsUnicodeMode() const { return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); } +int Editor::CodePage() const { + if (pdoc) + return pdoc->dbcsCodePage; + else + return 0; +} + static bool ValidMargin(unsigned long wParam) { return wParam < ViewStyle::margins; } @@ -4461,8 +4807,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { switch (iMessage) { - case SCI_GETTEXT: - { + case SCI_GETTEXT: { if (lParam == 0) return 0; if (wParam == 0) @@ -4475,8 +4820,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return iChar; } - case SCI_SETTEXT: - { + case SCI_SETTEXT: { if (lParam == 0) return 0; pdoc->DeleteChars(0, pdoc->Length()); @@ -4593,7 +4937,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { // return -1; return pdoc->LineStart(wParam); - // Replacement of the old Scintilla interpretation of EM_LINELENGTH + // Replacement of the old Scintilla interpretation of EM_LINELENGTH case SCI_LINELENGTH: if ((static_cast(wParam) < 0) || (static_cast(wParam) > pdoc->LineFromPosition(pdoc->Length()))) @@ -4627,6 +4971,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETTARGETEND: return targetEnd; + case SCI_TARGETFROMSELECTION: + if (currentPos < anchor) { + targetStart = currentPos; + targetEnd = anchor; + } else { + targetStart = anchor; + targetEnd = currentPos; + } + break; + case SCI_REPLACETARGET: PLATFORM_ASSERT(lParam); return ReplaceTarget(false, CharPtrFromSPtr(lParam), wParam); @@ -4653,12 +5007,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_SETXOFFSET: xOffset = wParam; + SetHorizontalScrollPos(); Redraw(); break; case SCI_GETXOFFSET: return xOffset; + case SCI_CHOOSECARETX: + SetLastXChosen(); + break; + case SCI_SCROLLCARET: EnsureCaretVisible(); break; @@ -4763,6 +5122,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return 0; } + case SCI_APPENDTEXT: + pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam); + return 0; + case SCI_CLEARALL: ClearAll(); return 0; @@ -4848,6 +5211,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETPRINTCOLOURMODE: return printColourMode; + case SCI_SETPRINTWRAPMODE: + printWrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone; + break; + + case SCI_GETPRINTWRAPMODE: + return printWrapState; + case SCI_GETSTYLEAT: if (static_cast(wParam) >= pdoc->Length()) return 0; @@ -4948,7 +5318,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->SetStyleFor(wParam, static_cast(lParam)); break; - case SCI_SETSTYLINGEX: // Specify a complete styling buffer + case SCI_SETSTYLINGEX: // Specify a complete styling buffer if (lParam == 0) return 0; pdoc->SetStyles(wParam, CharPtrFromSPtr(lParam)); @@ -4961,6 +5331,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETBUFFEREDDRAW: return bufferedDraw; + case SCI_GETTWOPHASEDRAW: + return twoPhaseDraw; + + case SCI_SETTWOPHASEDRAW: + twoPhaseDraw = wParam != 0; + InvalidateStyleRedraw(); + break; + case SCI_SETTABWIDTH: if (wParam > 0) pdoc->tabInChars = wParam; @@ -5052,6 +5430,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETSCROLLWIDTH: return scrollWidth; + case SCI_LINESJOIN: + LinesJoin(); + break; + + case SCI_LINESSPLIT: + LinesSplit(wParam); + break; + case SCI_TEXTWIDTH: PLATFORM_ASSERT((wParam >= 0) && (wParam <= STYLE_MAX)); PLATFORM_ASSERT(lParam); @@ -5061,7 +5447,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.lineHeight; case SCI_SETENDATLASTLINE: - PLATFORM_ASSERT((wParam == 0) || (wParam ==1)); + PLATFORM_ASSERT((wParam == 0) || (wParam == 1)); if (endAtLastLine != (wParam != 0)) { endAtLastLine = wParam != 0; SetScrollBars(); @@ -5085,6 +5471,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETHSCROLLBAR: return horizontalScrollBarVisible; + case SCI_SETVSCROLLBAR: + if (verticalScrollBarVisible != (wParam != 0)) { + verticalScrollBarVisible = wParam != 0; + SetScrollBars(); + ReconfigureScrollBars(); + } + break; + + case SCI_GETVSCROLLBAR: + return verticalScrollBarVisible; + case SCI_SETINDENTATIONGUIDES: vs.viewIndentationGuides = wParam != 0; Redraw(); @@ -5174,6 +5571,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } return -1; + case SCI_MARKERDEFINEPIXMAP: + if (wParam <= MARKER_MAX) { + vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); + }; + InvalidateStyleData(); + RedrawSelMargin(); + break; + case SCI_SETMARGINTYPEN: if (ValidMargin(wParam)) { vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL); @@ -5412,10 +5817,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_SEARCHPREV: return SearchText(iMessage, wParam, lParam); - case SCI_SETCARETPOLICY: // Deprecated +#ifdef INCLUDE_DEPRECATED_FEATURES + case SCI_SETCARETPOLICY: // Deprecated caretXPolicy = caretYPolicy = wParam; caretXSlop = caretYSlop = lParam; break; +#endif case SCI_SETXCARETPOLICY: caretXPolicy = wParam; @@ -5468,8 +5875,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.caretcolour.desired.AsLong(); case SCI_SETCARETWIDTH: - if (wParam <= 1) - vs.caretWidth = 1; + if (wParam <= 0) + vs.caretWidth = 0; else if (wParam >= 3) vs.caretWidth = 3; else @@ -5556,6 +5963,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_LINECUT: case SCI_LINEDELETE: case SCI_LINETRANSPOSE: + case SCI_LINEDUPLICATE: case SCI_LOWERCASE: case SCI_UPPERCASE: case SCI_LINESCROLLDOWN: @@ -5634,7 +6042,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_CREATEDOCUMENT: { Document *doc = new Document(); - doc->AddRef(); + if (doc) { + doc->AddRef(); + } return reinterpret_cast(doc); } @@ -5716,6 +6126,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { MoveCaretInsideView(); break; + case SCI_SETFOLDMARGINCOLOUR: + vs.foldmarginColourSet = wParam != 0; + vs.foldmarginColour.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + + case SCI_SETFOLDMARGINHICOLOUR: + vs.foldmarginHighlightColourSet = wParam != 0; + vs.foldmarginHighlightColour.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + default: return DefWndProc(iMessage, wParam, lParam); } diff --git a/contrib/src/stc/scintilla/src/Editor.h b/contrib/src/stc/scintilla/src/Editor.h index 800630bbb0..5db0e870d8 100644 --- a/contrib/src/stc/scintilla/src/Editor.h +++ b/contrib/src/stc/scintilla/src/Editor.h @@ -2,7 +2,7 @@ /** @file Editor.h ** Defines the main editor class. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef EDITOR_H @@ -138,18 +138,20 @@ class AutoSurface { private: Surface *surf; public: - AutoSurface(bool unicodeMode) { + AutoSurface(int codePage) { surf = Surface::Allocate(); if (surf) { surf->Init(); - surf->SetUnicodeMode(unicodeMode); + surf->SetUnicodeMode(SC_CP_UTF8 == codePage); + surf->SetDBCSMode(codePage); } } - AutoSurface(SurfaceID sid, bool unicodeMode) { + AutoSurface(SurfaceID sid, int codePage) { surf = Surface::Allocate(); if (surf) { surf->Init(sid); - surf->SetUnicodeMode(unicodeMode); + surf->SetUnicodeMode(SC_CP_UTF8 == codePage); + surf->SetDBCSMode(codePage); } } ~AutoSurface() { @@ -184,6 +186,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int printMagnification; int printColourMode; + int printWrapState; int cursorMode; int controlCharSymbol; @@ -196,11 +199,15 @@ protected: // ScintillaBase subclass needs access to much of Editor /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to * the screen. This avoids flashing but is about 30% slower. */ bool bufferedDraw; + /** In twoPhaseDraw mode, drawing is performed in two phases, first the background + * and then the foreground. This avoids chopping off characters that overlap the next run. */ + bool twoPhaseDraw; int xOffset; ///< Horizontal scrolled amount in pixels int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; int scrollWidth; + bool verticalScrollBarVisible; bool endAtLastLine; Surface *pixmapLine; @@ -321,12 +328,14 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetSelection(int currentPos_, int anchor_); void SetSelection(int currentPos_); void SetEmptySelection(int currentPos_); + bool RangeContainsProtected(int start, int end) const; + bool SelectionContainsProtected() const; int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionTo(int newPos, bool extend=false, bool ensureVisible=true); int MovePositionSoVisible(int pos, int moveDir); void SetLastXChosen(); - void ScrollTo(int line); + void ScrollTo(int line, bool moveThumb=true); virtual void ScrollText(int linesToMove); void HorizontalScrollTo(int xPos); void MoveCaretInsideView(bool ensureVisible=true); @@ -338,14 +347,22 @@ protected: // ScintillaBase subclass needs access to much of Editor void NeedWrapping(int docLineStartWrapping=0); bool WrapLines(); + void LinesJoin(); + void LinesSplit(int pixelWidth); int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault); void PaintSelMargin(Surface *surface, PRectangle &rc); LineLayout *RetrieveLineLayout(int lineNumber); void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, int width=LineLayout::wrapWidthInfinite); + ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, int styleMain, int i, LineLayout *ll); + void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); + void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, + int line, int lineEnd, int xStart, int subLine, int subLineStart, + bool overrideBackground, ColourAllocated background); void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine=0); + void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); long FormatRange(bool draw, RangeToFormat *pfr); int TextWidth(int style, const char *text); @@ -403,6 +420,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void PageMove(int direction, bool extend=false); void ChangeCaseOfSelection(bool makeUpperCase); void LineTranspose(); + void LineDuplicate(); virtual void CancelModes(); void NewLine(); void CursorUpOrDown(int direction, bool extend=false); @@ -456,6 +474,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void EnsureLineVisible(int lineDoc, bool enforcePolicy); int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); + int CodePage() const; + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; public: diff --git a/contrib/src/stc/scintilla/src/KeyMap.cxx b/contrib/src/stc/scintilla/src/KeyMap.cxx index c91e6c6ccc..c85a5d4f83 100644 --- a/contrib/src/stc/scintilla/src/KeyMap.cxx +++ b/contrib/src/stc/scintilla/src/KeyMap.cxx @@ -1,5 +1,5 @@ // Scintilla source code edit control -/** @file KeyMap.cxx +/** @file KeyMap.cxx ** Defines a mapping between keystrokes and commands. **/ // Copyright 1998-2001 by Neil Hodgson @@ -13,7 +13,7 @@ KeyMap::KeyMap() : kmap(0), len(0), alloc(0) { for (int i = 0; MapDefault[i].key; i++) { - AssignCmdKey(MapDefault[i].key, + AssignCmdKey(MapDefault[i].key, MapDefault[i].modifiers, MapDefault[i].msg); } @@ -109,7 +109,7 @@ const KeyToCommand KeyMap::MapDefault[] = { {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, {SCK_BACK, SCI_ALT, SCI_UNDO}, - {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, + {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, {'Z', SCI_CTRL, SCI_UNDO}, {'Y', SCI_CTRL, SCI_REDO}, {'X', SCI_CTRL, SCI_CUT}, @@ -127,6 +127,7 @@ const KeyToCommand KeyMap::MapDefault[] = { {'L', SCI_CTRL, SCI_LINECUT}, {'L', SCI_CSHIFT, SCI_LINEDELETE}, {'T', SCI_CTRL, SCI_LINETRANSPOSE}, + {'D', SCI_CTRL, SCI_LINEDUPLICATE}, {'U', SCI_CTRL, SCI_LOWERCASE}, {'U', SCI_CSHIFT, SCI_UPPERCASE}, {0,0,0}, diff --git a/contrib/src/stc/scintilla/src/KeyWords.cxx b/contrib/src/stc/scintilla/src/KeyWords.cxx index 8a03aa8ac4..a0cb3d9677 100644 --- a/contrib/src/stc/scintilla/src/KeyWords.cxx +++ b/contrib/src/stc/scintilla/src/KeyWords.cxx @@ -25,10 +25,10 @@ int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1; LexerModule::LexerModule(int language_, LexerFunction fnLexer_, const char *languageName_, LexerFunction fnFolder_, const char * const wordListDescriptions_[]) : - language(language_), - fnLexer(fnLexer_), - fnFolder(fnFolder_), - wordListDescriptions(wordListDescriptions_), + language(language_), + fnLexer(fnLexer_), + fnFolder(fnFolder_), + wordListDescriptions(wordListDescriptions_), languageName(languageName_) { next = base; base = this; @@ -62,7 +62,7 @@ const char * LexerModule::GetWordListDescription(int index) const { return wordListDescriptions[index]; } } - + const LexerModule *LexerModule::Find(int language) { const LexerModule *lm = base; while (lm) { @@ -142,15 +142,20 @@ int Scintilla_LinkLexers() { //++Autogenerated -- run src/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) LINK_LEXER(lmAda); + LINK_LEXER(lmAsm); LINK_LEXER(lmAVE); LINK_LEXER(lmBaan); LINK_LEXER(lmBullant); LINK_LEXER(lmConf); LINK_LEXER(lmCPP); + LINK_LEXER(lmCPPNoCase); LINK_LEXER(lmTCL); LINK_LEXER(lmNncrontab); + LINK_LEXER(lmCss); LINK_LEXER(lmEiffel); LINK_LEXER(lmEiffelkw); + LINK_LEXER(lmFortran); + LINK_LEXER(lmF77); LINK_LEXER(lmHTML); LINK_LEXER(lmXML); LINK_LEXER(lmASP); diff --git a/contrib/src/stc/scintilla/src/LexAVE.cxx b/contrib/src/stc/scintilla/src/LexAVE.cxx index dfd15f02f1..900aea317c 100644 --- a/contrib/src/stc/scintilla/src/LexAVE.cxx +++ b/contrib/src/stc/scintilla/src/LexAVE.cxx @@ -1,188 +1,224 @@ // SciTE - Scintilla based Text Editor /** @file LexAVE.cxx ** Lexer for Avenue. + ** + ** Written by Alexey Yutkin . **/ -// Copyright 1998-2001 by Neil Hodgson +// Copyright 1998-2002 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include #include #include -#include #include +#include +#include #include "Platform.h" #include "PropSet.h" #include "Accessor.h" +#include "StyleContext.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" -static void ColouriseAveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); +} +static inline bool IsEnumChar(const int ch) { + return (ch < 0x80) && (isalnum(ch)|| ch == '_'); +} +static inline bool IsANumberChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' ); +} + +inline bool IsAWordStart(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +inline bool isAveOperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || + ch == '(' || ch == ')' || ch == '=' || + ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || + ch == '.' ) + return true; + return false; +} + +static void ColouriseAveDoc( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + WordList &keywords6 = *keywordlists[5]; - styler.StartAt(startPos); + // Do not leak onto next line + if (initStyle == SCE_AVE_STRINGEOL) { + initStyle = SCE_AVE_DEFAULT; + } - bool fold = styler.GetPropertyInt("fold") != 0; + StyleContext sc(startPos, length, initStyle, styler); + + for (; sc.More(); sc.Forward()) { + if (sc.atLineEnd) { + // Update the line state, so it can be seen by next line + int currentLine = styler.GetLine(sc.currentPos); + styler.SetLineState(currentLine, 0); + } + if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) { + // Prevent SCE_AVE_STRINGEOL from leaking back to previous line + sc.SetState(SCE_AVE_STRING); + } + + + // Determine if the current state should terminate. + if (sc.state == SCE_AVE_OPERATOR) { + sc.SetState(SCE_AVE_DEFAULT); + } else if (sc.state == SCE_AVE_NUMBER) { + if (!IsANumberChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); + } + } else if (sc.state == SCE_AVE_ENUM) { + if (!IsEnumChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); + } + } else if (sc.state == SCE_AVE_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { + char s[100]; + //sc.GetCurrent(s, sizeof(s)); + sc.GetCurrentLowered(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_AVE_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_AVE_WORD2); + } else if (keywords3.InList(s)) { + sc.ChangeState(SCE_AVE_WORD3); + } else if (keywords4.InList(s)) { + sc.ChangeState(SCE_AVE_WORD4); + } else if (keywords5.InList(s)) { + sc.ChangeState(SCE_AVE_WORD5); + } else if (keywords6.InList(s)) { + sc.ChangeState(SCE_AVE_WORD6); + } + sc.SetState(SCE_AVE_DEFAULT); + } + } else if (sc.state == SCE_AVE_COMMENT) { + if (sc.atLineEnd) { + sc.SetState(SCE_AVE_DEFAULT); + } + } else if (sc.state == SCE_AVE_STRING) { + if (sc.ch == '\"') { + sc.ForwardSetState(SCE_AVE_DEFAULT); + } else if (sc.atLineEnd) { + sc.ChangeState(SCE_AVE_STRINGEOL); + sc.ForwardSetState(SCE_AVE_DEFAULT); + } + } + + // Determine if a new state should be entered. + if (sc.state == SCE_AVE_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_AVE_NUMBER); + } else if (IsAWordStart(sc.ch)) { + sc.SetState(SCE_AVE_IDENTIFIER); + } else if (sc.Match('\"')) { + sc.SetState(SCE_AVE_STRING); + } else if (sc.Match('\'')) { + sc.SetState(SCE_AVE_COMMENT); + sc.Forward(); + } else if (isAveOperator(static_cast(sc.ch))) { + sc.SetState(SCE_AVE_OPERATOR); + } else if (sc.Match('#')) { + sc.SetState(SCE_AVE_ENUM); + sc.Forward(); + } + } + } + sc.Complete(); +} + +static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], + Accessor &styler) { + unsigned int lengthDoc = startPos + length; + int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; - - int state = initStyle; - if (state == SCE_AVE_STRINGEOL) // Does not leak onto next line - state = SCE_AVE_DEFAULT; - char chNext = styler[startPos]; - unsigned int lengthDoc = startPos + length; - int visibleChars = 0; - styler.StartSegment(startPos); + char chNext = static_cast(tolower(styler[startPos])); + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + int styleNext = styler.StyleAt(startPos); + char s[10]; for (unsigned int i = startPos; i < lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) - // Avoid triggering two times on Dos/Win - // End of line - if (state == SCE_AVE_STRINGEOL) { - styler.ColourTo(i, state); - state = SCE_AVE_DEFAULT; + char ch = static_cast(tolower(chNext)); + chNext = static_cast(tolower(styler.SafeGetCharAt(i + 1))); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (style == SCE_AVE_WORD) { + if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') { + for (unsigned int j = 0; j < 6; j++) { + if (!iswordchar(styler[i + j])) { + break; + } + s[j] = static_cast(tolower(styler[i + j])); + s[j + 1] = '\0'; + } + + if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { + levelCurrent++; + } + if ((strcmp(s, "end") == 0)) { + levelCurrent--; + } } - if (fold) { - int lev = levelPrev; - if (visibleChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; + } else if (style == SCE_AVE_OPERATOR) { + if (ch == '{' || ch == '(') { + levelCurrent++; + } else if (ch == '}' || ch == ')') { + levelCurrent--; + } + } + + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) { + lev |= SC_FOLDLEVELWHITEFLAG; + } + if ((levelCurrent > levelPrev) && (visibleChars > 0)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); - lineCurrent++; - levelPrev = levelCurrent; } + lineCurrent++; + levelPrev = levelCurrent; visibleChars = 0; } - if (!isspace(ch)) + if (!isspacechar(ch)) { visibleChars++; - if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; } - - if (state == SCE_AVE_DEFAULT) { - if (iswordstart(ch) || (ch == '.') ) { - styler.ColourTo(i-1, state); - state = SCE_AVE_IDENTIFIER; - } else if (ch == '\'') { - styler.ColourTo(i-1, state); - state = SCE_AVE_COMMENT; - } else if (ch == '\"') { - styler.ColourTo(i-1, state); - state = SCE_AVE_STRING; - } else if (ch == '#') { - styler.ColourTo(i-1, state); - state = SCE_AVE_ENUM; - } else if (isoperator(ch) ) { - styler.ColourTo(i-1, state); - styler.ColourTo(i, SCE_AVE_OPERATOR); - } - } - else if (state == SCE_AVE_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; - } - } - else if (state == SCE_AVE_ENUM) { - if (isoperator(ch) || ch == ' ' || ch == '\'' || ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; - } - } - else if (state == SCE_AVE_STRING) { - if (ch == '\"') { - if (chNext == '\"') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } else - { - styler.ColourTo(i, state); - state = SCE_AVE_DEFAULT; - } - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_AVE_STRINGEOL); - state = SCE_AVE_STRINGEOL; - } - } - if ((state == SCE_AVE_IDENTIFIER)) { - if (!iswordchar(ch) || ch == '.' ) { - char s[100]; - unsigned int start = styler.GetStartSegment(); - unsigned int end = i - 1; - for (unsigned int ii = 0; ii < end - start + 1 && ii < 30; ii++) { - s[ii] = static_cast(tolower(styler[start + ii])); - s[ii + 1] = '\0'; - } - - char chAttr = SCE_AVE_IDENTIFIER; - - if (isdigit(s[0])) - chAttr = SCE_AVE_NUMBER; - else { - if ((strcmp(s, "for") == 0) || (strcmp(s, "if") == 0) || (strcmp(s, "while") == 0)) - { - levelCurrent +=1; - chAttr = SCE_AVE_STATEMENT; - } - - if (strcmp(s, "end") == 0) - { - levelCurrent -=1; - chAttr = SCE_AVE_STATEMENT; - } - - if ( (strcmp(s, "then") == 0) || (strcmp(s, "else") == 0) || (strcmp(s, "break") == 0) || - (strcmp(s, "each") == 0) || - (strcmp(s, "exit") == 0) || (strcmp(s, "continue") == 0) || (strcmp(s, "return") == 0) || - (strcmp(s, "by") == 0) || (strcmp(s, "in") == 0) || (strcmp(s, "elseif") == 0)) - { - chAttr = SCE_AVE_STATEMENT; - } - - if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0)) - { - chAttr = SCE_AVE_KEYWORD; - } - - if (keywords.InList(s)) - { - chAttr = SCE_AVE_WORD; - } - } - styler.ColourTo(end, chAttr); - state = SCE_AVE_DEFAULT; - - if (ch == '\'') { - state = SCE_AVE_COMMENT; - } else if (ch == '\"') { - state = SCE_AVE_STRING; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_AVE_OPERATOR); - } - } - } - } - styler.ColourTo(lengthDoc - 1, state); - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - styler.SetLevel(lineCurrent, levelPrev | flagsNext); - } + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave"); +LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc); + diff --git a/contrib/src/stc/scintilla/src/LexAda.cxx b/contrib/src/stc/scintilla/src/LexAda.cxx index 0d8fb9d5dd..30f0732c70 100644 --- a/contrib/src/stc/scintilla/src/LexAda.cxx +++ b/contrib/src/stc/scintilla/src/LexAda.cxx @@ -1,198 +1,515 @@ -// SciTE - Scintilla based Text Editor -// LexAda.cxx - lexer for Ada95 -// by Tahir Karaca +// Scintilla source code edit control +/** @file LexAda.cxx + ** Lexer for Ada 95 + **/ +// Copyright 2002 by Sergey Koshcheyev // The License.txt file describes the conditions under which this software may be distributed. -#include -#include -#include -#include -#include +#include +#include +#include +#include #include "Platform.h" -#include "PropSet.h" #include "Accessor.h" +#include "StyleContext.h" +#include "PropSet.h" #include "KeyWords.h" -#include "Scintilla.h" #include "SciLexer.h" +#include "SString.h" -inline void classifyWordAda(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { +/* + * Interface + */ - static const unsigned KEWORD_LEN_MAX = 30; +static void ColouriseDocument( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler); - char wordLower[KEWORD_LEN_MAX + 1]; - unsigned i; - for(i = 0; ( i < KEWORD_LEN_MAX ) && ( i < end - start + 1 ); i++) { - wordLower[i] = static_cast(tolower(styler[start + i])); - } - wordLower[i] = '\0'; - -// int levelChange = 0; - char chAttr = SCE_ADA_IDENTIFIER; - if (keywords.InList(wordLower)) { - chAttr = SCE_ADA_WORD; +LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada"); -// Folding doesn't work this way since the semantics of some keywords depends -// on the current context. -// E.g. - "cond1 and THEN cond2" <-> "if ... THEN ..." -// - "procedure X IS ... end X;" <-> "procedure X IS new Y;" -// if (strcmp(wordLower, "is") == 0 || strcmp(wordLower, "then") == 0) -// levelChange=1; -// else if (strcmp(wordLower, "end") == 0) -// levelChange=-1; - } - styler.ColourTo(end, chAttr); - -// return levelChange; +/* + * Implementation + */ + +// Functions that have apostropheStartsAttribute as a parameter set it according to whether +// an apostrophe encountered after processing the current token will start an attribute or +// a character literal. +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL); +static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); +static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute); +static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); + +static inline bool IsDelimiterCharacter(int ch); +static inline bool IsNumberStartCharacter(int ch); +static inline bool IsNumberCharacter(int ch); +static inline bool IsSeparatorOrDelimiterCharacter(int ch); +static bool IsValidIdentifier(const SString& identifier); +static bool IsValidNumber(const SString& number); +static inline bool IsWordStartCharacter(int ch); +static inline bool IsWordCharacter(int ch); + +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; + + sc.SetState(SCE_ADA_CHARACTER); + + // Skip the apostrophe and one more character (so that '' is shown as non-terminated and ''' + // is handled correctly) + sc.Forward(); + sc.Forward(); + + ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL); } +static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) { + while (!sc.atLineEnd && !sc.Match(chEnd)) { + sc.Forward(); + } -static inline bool isAdaOperator(char ch) { - - if (ch == '&' || ch == '\'' || ch == '(' || ch == ')' || - ch == '*' || ch == '+' || ch == ',' || ch == '-' || - ch == '.' || ch == '/' || ch == ':' || ch == ';' || - ch == '<' || ch == '=' || ch == '>') - return true; - return false; -} - - -inline void styleTokenBegin(char beginChar, unsigned int pos, int &state, - Accessor &styler) { - - if (isalpha(beginChar)) { - styler.ColourTo(pos-1, state); - state = SCE_ADA_IDENTIFIER; - } else if (isdigit(beginChar)) { - styler.ColourTo(pos-1, state); - state = SCE_ADA_NUMBER; - } else if (beginChar == '-' && styler.SafeGetCharAt(pos + 1) == '-') { - styler.ColourTo(pos-1, state); - state = SCE_ADA_COMMENT; - } else if (beginChar == '\"') { - styler.ColourTo(pos-1, state); - state = SCE_ADA_STRING; - } else if (beginChar == '\'' && styler.SafeGetCharAt(pos + 2) == '\'') { - styler.ColourTo(pos-1, state); - state = SCE_ADA_CHARACTER; - } else if (isAdaOperator(beginChar)) { - styler.ColourTo(pos-1, state); - styler.ColourTo(pos, SCE_ADA_OPERATOR); + if (!sc.atLineEnd) { + sc.ForwardSetState(SCE_ADA_DEFAULT); + } else { + sc.ChangeState(stateEOL); } } +static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { + // Apostrophe meaning is not changed, but the parameter is present for uniformity -static void ColouriseAdaDoc(unsigned int startPos, int length, int initStyle, - WordList *keywordlists[], Accessor &styler) { - + sc.SetState(SCE_ADA_COMMENTLINE); + + while (!sc.atLineEnd) { + sc.Forward(); + } +} + +static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = sc.Match (')'); + sc.SetState(SCE_ADA_DELIMITER); + sc.ForwardSetState(SCE_ADA_DEFAULT); +} + +static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = false; + + sc.SetState(SCE_ADA_LABEL); + + // Skip "<<" + sc.Forward(); + sc.Forward(); + + SString identifier; + + while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { + identifier += static_cast(tolower(sc.ch)); + sc.Forward(); + } + + // Skip ">>" + if (sc.Match('>', '>')) { + sc.Forward(); + sc.Forward(); + } else { + sc.ChangeState(SCE_ADA_ILLEGAL); + } + + // If the name is an invalid identifier or a keyword, then make it invalid label + if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) { + sc.ChangeState(SCE_ADA_ILLEGAL); + } + + sc.SetState(SCE_ADA_DEFAULT); + +} + +static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; + + SString number; + sc.SetState(SCE_ADA_NUMBER); + + // Get all characters up to a delimiter or a separator, including points, but excluding + // double points (ranges). + while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { + number += static_cast(sc.ch); + sc.Forward(); + } + + // Special case: exponent with sign + if ((sc.chPrev == 'e' || sc.chPrev == 'E') && + (sc.ch == '+' || sc.ch == '-')) { + number += static_cast(sc.ch); + sc.Forward (); + + while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { + number += static_cast(sc.ch); + sc.Forward(); + } + } + + if (!IsValidNumber(number)) { + sc.ChangeState(SCE_ADA_ILLEGAL); + } + + sc.SetState(SCE_ADA_DEFAULT); +} + +static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; + + sc.SetState(SCE_ADA_STRING); + sc.Forward(); + + ColouriseContext(sc, '"', SCE_ADA_STRINGEOL); +} + +static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { + // Apostrophe meaning is not changed, but the parameter is present for uniformity + sc.SetState(SCE_ADA_DEFAULT); + sc.ForwardSetState(SCE_ADA_DEFAULT); +} + +static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; + sc.SetState(SCE_ADA_IDENTIFIER); + + SString word; + + while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { + word += static_cast(tolower(sc.ch)); + sc.Forward(); + } + + if (!IsValidIdentifier(word)) { + sc.ChangeState(SCE_ADA_ILLEGAL); + + } else if (keywords.InList(word.c_str())) { + sc.ChangeState(SCE_ADA_WORD); + + if (word != "all") { + apostropheStartsAttribute = false; + } + } + + sc.SetState(SCE_ADA_DEFAULT); +} + +// +// ColouriseDocument +// + +static void ColouriseDocument( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler) { WordList &keywords = *keywordlists[0]; - - styler.StartAt(startPos); - -// bool fold = styler.GetPropertyInt("fold"); -// int lineCurrent = styler.GetLine(startPos); -// int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; -// int levelCurrent = levelPrev; - int state = initStyle; - if (state == SCE_ADA_STRINGEOL) // Does not leak onto next line - state = SCE_ADA_DEFAULT; - char chNext = styler[startPos]; - const unsigned int lengthDoc = startPos + length; - //int visibleChars = 0; - styler.StartSegment(startPos); - for (unsigned int i = startPos; i < lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); + StyleContext sc(startPos, length, initStyle, styler); - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) - // Avoid triggering two times on Dos/Win - if (state == SCE_ADA_STRINGEOL) { - styler.ColourTo(i, state); - state = SCE_ADA_DEFAULT; - } -// if (fold) { -// int lev = levelPrev; -// if (visibleChars == 0) -// lev |= SC_FOLDLEVELWHITEFLAG; -// if ((levelCurrent > levelPrev) && (visibleChars > 0)) -// lev |= SC_FOLDLEVELHEADERFLAG; -// styler.SetLevel(lineCurrent, lev); -// lineCurrent++; -// levelPrev = levelCurrent; -// } - //visibleChars = 0; - } - //if (!isspacechar(ch)) - // visibleChars++; + int lineCurrent = styler.GetLine(startPos); + bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; - if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; + while (sc.More()) { + if (sc.atLineEnd) { + // Go to the next line + sc.Forward(); + lineCurrent++; + + // Remember the line state for future incremental lexing + styler.SetLineState(lineCurrent, apostropheStartsAttribute); + + // Don't continue any styles on the next line + sc.SetState(SCE_ADA_DEFAULT); } - if (state == SCE_ADA_DEFAULT) { - styleTokenBegin(ch, i, state, styler); - } else if (state == SCE_ADA_IDENTIFIER) { - if (!iswordchar(ch)) { - classifyWordAda(styler.GetStartSegment(), - i - 1, - keywords, - styler); - state = SCE_ADA_DEFAULT; - styleTokenBegin(ch, i, state, styler); - } - } else if (state == SCE_ADA_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_ADA_DEFAULT; - } - } else if (state == SCE_ADA_STRING) { - if (ch == '"' ) { - if( chNext == '"' ) { - i++; - chNext = styler.SafeGetCharAt(i + 1); - } else { - styler.ColourTo(i, state); - state = SCE_ADA_DEFAULT; - } - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_ADA_STRINGEOL); - state = SCE_ADA_STRINGEOL; - } - } else if (state == SCE_ADA_CHARACTER) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, SCE_ADA_STRINGEOL); - state = SCE_ADA_STRINGEOL; - } else if (ch == '\'' && styler.SafeGetCharAt(i - 2) == '\'') { - styler.ColourTo(i, state); - state = SCE_ADA_DEFAULT; - } - } else if (state == SCE_ADA_NUMBER) { - if ( !( isdigit(ch) || ch == '.' || ch == '_' || ch == '#' - || ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D' - || ch == 'E' || ch == 'F' - || ch == 'a' || ch == 'b' || ch == 'c' || ch == 'd' - || ch == 'e' || ch == 'f' ) ) { - styler.ColourTo(i-1, SCE_ADA_NUMBER); - state = SCE_ADA_DEFAULT; - styleTokenBegin(ch, i, state, styler); - } - } + // Comments + if (sc.Match('-', '-')) { + ColouriseComment(sc, apostropheStartsAttribute); + // Strings + } else if (sc.Match('"')) { + ColouriseString(sc, apostropheStartsAttribute); + + // Characters + } else if (sc.Match('\'') && !apostropheStartsAttribute) { + ColouriseCharacter(sc, apostropheStartsAttribute); + + // Labels + } else if (sc.Match('<', '<')) { + ColouriseLabel(sc, keywords, apostropheStartsAttribute); + + // Whitespace + } else if (isspace(sc.ch)) { + ColouriseWhiteSpace(sc, apostropheStartsAttribute); + + // Delimiters + } else if (IsDelimiterCharacter(sc.ch)) { + ColouriseDelimiter(sc, apostropheStartsAttribute); + + // Numbers + } else if (isdigit(sc.ch) || sc.ch == '#') { + ColouriseNumber(sc, apostropheStartsAttribute); + + // Keywords or identifiers + } else { + ColouriseWord(sc, keywords, apostropheStartsAttribute); + } } - styler.ColourTo(lengthDoc - 1, state); -// // Fill in the real level of the next line, keeping the current flags as they will be filled in later -// if (fold) { -// int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; -// styler.SetLevel(lineCurrent, levelPrev | flagsNext); -// } + sc.Complete(); } -LexerModule lmAda(SCLEX_ADA, ColouriseAdaDoc, "ada"); +static inline bool IsDelimiterCharacter(int ch) { + switch (ch) { + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ':': + case ';': + case '<': + case '=': + case '>': + case '|': + return true; + default: + return false; + } +} + +static inline bool IsNumberCharacter(int ch) { + return IsNumberStartCharacter(ch) || + ch == '_' || + ch == '.' || + ch == '#' || + (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F'); +} + +static inline bool IsNumberStartCharacter(int ch) { + return isdigit(ch) != 0; +} + +static inline bool IsSeparatorOrDelimiterCharacter(int ch) { + return isspace(ch) || IsDelimiterCharacter(ch); +} + +static bool IsValidIdentifier(const SString& identifier) { + // First character can't be '_', so initialize the flag to true + bool lastWasUnderscore = true; + + int length = identifier.length(); + + // Zero-length identifiers are not valid (these can occur inside labels) + if (length == 0) { + return false; + } + + // Check for valid character at the start + if (!IsWordStartCharacter(identifier[0])) { + return false; + } + + // Check for only valid characters and no double underscores + for (int i = 0; i < length; i++) { + if (!IsWordCharacter(identifier[i]) || + (identifier[i] == '_' && lastWasUnderscore)) { + return false; + } + lastWasUnderscore = identifier[i] == '_'; + } + + // Check for underscore at the end + if (lastWasUnderscore == true) { + return false; + } + + // All checks passed + return true; +} + +static bool IsValidNumber(const SString& number) { + int hashPos = number.search("#"); + bool seenDot = false; + + int i = 0; + int length = number.length(); + + if (length == 0) + return false; // Just in case + + // Decimal number + if (hashPos == -1) { + bool canBeSpecial = false; + + for (; i < length; i++) { + if (number[i] == '_') { + if (!canBeSpecial) { + return false; + } + canBeSpecial = false; + } else if (number[i] == '.') { + if (!canBeSpecial || seenDot) { + return false; + } + canBeSpecial = false; + seenDot = true; + } else if (isdigit(number[i])) { + canBeSpecial = true; + } else { + break; + } + } + + if (!canBeSpecial) + return false; + } else { + // Based number + bool canBeSpecial = false; + int base = 0; + + // Parse base + for (; i < length; i++) { + int ch = number[i]; + if (ch == '_') { + if (!canBeSpecial) + return false; + canBeSpecial = false; + } else if (isdigit (ch)) { + base = base * 10 + (ch - '0'); + if (base > 16) + return false; + canBeSpecial = true; + } else if (ch == '#' && canBeSpecial) { + break; + } else { + return false; + } + } + + if (base < 2) + return false; + if (i == length) + return false; + + i++; // Skip over '#' + + // Parse number + canBeSpecial = false; + + for (; i < length; i++) { + int ch = tolower(number[i]); + + if (ch == '_') { + if (!canBeSpecial) { + return false; + } + canBeSpecial = false; + + } else if (ch == '.') { + if (!canBeSpecial || seenDot) { + return false; + } + canBeSpecial = false; + seenDot = true; + + } else if (isdigit (ch)) { + if (ch - '0' >= base) { + return false; + } + canBeSpecial = true; + + } else if (ch >= 'a' && ch <= 'f') { + if (ch - 'a' + 10 >= base) { + return false; + } + canBeSpecial = true; + + } else if (ch == '#' && canBeSpecial) { + break; + + } else { + return false; + } + } + + if (i == length) { + return false; + } + + i++; + } + + // Exponent (optional) + if (i < length) { + if (number[i] != 'e' && number[i] != 'E') + return false; + + i++; // Move past 'E' + + if (i == length) { + return false; + } + + if (number[i] == '+') + i++; + else if (number[i] == '-') { + if (seenDot) { + i++; + } else { + return false; // Integer literals should not have negative exponents + } + } + + if (i == length) { + return false; + } + + bool canBeSpecial = false; + + for (; i < length; i++) { + if (number[i] == '_') { + if (!canBeSpecial) { + return false; + } + canBeSpecial = false; + } else if (isdigit(number[i])) { + canBeSpecial = true; + } else { + return false; + } + } + + if (!canBeSpecial) + return false; + } + + // if i == length, number was parsed successfully. + return i == length; +} + +static inline bool IsWordCharacter(int ch) { + return IsWordStartCharacter(ch) || isdigit(ch); +} + +static inline bool IsWordStartCharacter(int ch) { + return isalpha(ch) || ch == '_'; +} diff --git a/contrib/src/stc/scintilla/src/LexAsm.cxx b/contrib/src/stc/scintilla/src/LexAsm.cxx new file mode 100644 index 0000000000..0fc6f27ad2 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexAsm.cxx @@ -0,0 +1,133 @@ +// Scintilla source code edit control +/** @file LexAsm.cxx + ** Lexer for Assembler, just for the Masm Syntax + ** Written by The Black Horus + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + + + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\'); +} + +static inline bool IsAWordStart(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); +} + +inline bool isAsmOperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || + ch == '(' || ch == ')' || ch == '=' || + ch == '[' || ch == ']' || ch == '<' || + ch == '>' || ch == ',' || + ch == '.' || ch == '%' || ch == ':') + return true; + return false; +} + +static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &cpuInstruction = *keywordlists[0]; + WordList &mathInstruction = *keywordlists[1]; + WordList ®isters = *keywordlists[2]; + WordList &directive = *keywordlists[3]; + WordList &directiveOperand = *keywordlists[4]; + + StyleContext sc(startPos, length, initStyle, styler); + + for (; sc.More(); sc.Forward()) + { + // Handle line continuation generically. + if (sc.ch == '\\') { + if (sc.Match("\\\n")) { + sc.Forward(); + continue; + } + if (sc.Match("\\\r\n")) { + sc.Forward(); + sc.Forward(); + continue; + } + } + + // Determine if the current state should terminate. + if (sc.state == SCE_ASM_OPERATOR) { + sc.SetState(SCE_ASM_DEFAULT); + }else if (sc.state == SCE_ASM_NUMBER) { + if (!IsAWordChar(sc.ch)) { + sc.SetState(SCE_ASM_DEFAULT); + } + } else if (sc.state == SCE_ASM_IDENTIFIER) { + if (!IsAWordChar(sc.ch) ) { + char s[100]; + sc.GetCurrentLowered(s, sizeof(s)); + + if (cpuInstruction.InList(s)) { + sc.ChangeState(SCE_ASM_CPUINSTRUCTION); + } else if (mathInstruction.InList(s)) { + sc.ChangeState(SCE_ASM_MATHINSTRUCTION); + } else if (registers.InList(s)) { + sc.ChangeState(SCE_ASM_REGISTER); + } else if (directive.InList(s)) { + sc.ChangeState(SCE_ASM_DIRECTIVE); + } else if (directiveOperand.InList(s)) { + sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND); + } + sc.SetState(SCE_ASM_DEFAULT); + } + } + else if (sc.state == SCE_ASM_COMMENT ) { + if (sc.atLineEnd) { + sc.SetState(SCE_ASM_DEFAULT); + } + } else if (sc.state == SCE_ASM_STRING) { + if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_ASM_DEFAULT); + } else if (sc.atLineEnd) { + sc.ForwardSetState(SCE_ASM_DEFAULT); + } + } + + // Determine if a new state should be entered. + else if (sc.state == SCE_ASM_DEFAULT) { + if (sc.ch == ';'){ + sc.SetState(SCE_ASM_COMMENT); + } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) { + sc.SetState(SCE_ASM_NUMBER); + } else if (IsAWordStart(sc.ch)) { + sc.SetState(SCE_ASM_IDENTIFIER); + } else if (sc.Match('\"')) { + sc.SetState(SCE_ASM_STRING); + } + } + + } + sc.Complete(); +} + +LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm"); + diff --git a/contrib/src/stc/scintilla/src/LexCPP.cxx b/contrib/src/stc/scintilla/src/LexCPP.cxx index 39f458da73..661b968cd7 100644 --- a/contrib/src/stc/scintilla/src/LexCPP.cxx +++ b/contrib/src/stc/scintilla/src/LexCPP.cxx @@ -20,6 +20,9 @@ #include "Scintilla.h" #include "SciLexer.h" +#define KEYWORD_BOXHEADER 1 +#define KEYWORD_FOLDCONTRACTED 2 + static bool IsOKBeforeRE(const int ch) { return (ch == '(') || (ch == '=') || (ch == ','); } @@ -34,17 +37,17 @@ static inline bool IsAWordStart(const int ch) { static inline bool IsADoxygenChar(const int ch) { return (islower(ch) || ch == '$' || ch == '@' || - ch == '\\' || ch == '&' || ch == '<' || - ch == '>' || ch == '#' || ch == '{' || - ch == '}' || ch == '[' || ch == ']'); + ch == '\\' || ch == '&' || ch == '<' || + ch == '>' || ch == '#' || ch == '{' || + ch == '}' || ch == '[' || ch == ']'); } static inline bool IsStateComment(const int state) { return ((state == SCE_C_COMMENT) || - (state == SCE_C_COMMENTLINE) || - (state == SCE_C_COMMENTDOC) || - (state == SCE_C_COMMENTDOCKEYWORD) || - (state == SCE_C_COMMENTDOCKEYWORDERROR)); + (state == SCE_C_COMMENTLINE) || + (state == SCE_C_COMMENTDOC) || + (state == SCE_C_COMMENTDOCKEYWORD) || + (state == SCE_C_COMMENTDOCKEYWORDERROR)); } static inline bool IsStateString(const int state) { @@ -52,7 +55,7 @@ static inline bool IsStateString(const int state) { } static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], - Accessor &styler) { + Accessor &styler, bool caseSensitive) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; @@ -71,7 +74,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { - + if (sc.atLineStart && (sc.state == SCE_C_STRING)) { // Prevent SCE_C_STRINGEOL from leaking back to previous line sc.SetState(SCE_C_STRING); @@ -98,7 +101,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (sc.state == SCE_C_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; - sc.GetCurrent(s, sizeof(s)); + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } if (keywords.InList(s)) { lastWordWasUUID = strcmp(s, "uuid") == 0; sc.ChangeState(SCE_C_WORD); @@ -141,8 +148,12 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo sc.ForwardSetState(SCE_C_DEFAULT); } else if (!IsADoxygenChar(sc.ch)) { char s[100]; - sc.GetCurrent(s, sizeof(s)); - if (!isspace(sc.ch) || !keywords3.InList(s+1)) { + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } + if (!isspace(sc.ch) || !keywords3.InList(s + 1)) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); } sc.SetState(SCE_C_COMMENTDOC); @@ -237,7 +248,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo // Skip whitespace between # and preprocessor word do { sc.Forward(); - } while ((sc.ch == ' ') && (sc.ch == '\t') && sc.More()); + } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT); } @@ -245,9 +256,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo sc.SetState(SCE_C_OPERATOR); } } - + if (sc.atLineEnd) { - // Reset states to begining of colourise so no surprises + // Reset states to begining of colourise so no surprises // if different sets of lines lexed. chPrevNonWhite = ' '; visibleChars = 0; @@ -262,13 +273,234 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } static bool IsStreamCommentStyle(int style) { - return style == SCE_C_COMMENT || - style == SCE_C_COMMENTDOC || - style == SCE_C_COMMENTDOCKEYWORD || - style == SCE_C_COMMENTDOCKEYWORDERROR; + return style == SCE_C_COMMENT || + style == SCE_C_COMMENTDOC || + style == SCE_C_COMMENTDOCKEYWORD || + style == SCE_C_COMMENTDOCKEYWORDERROR; } -static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[], +static bool matchKeyword(unsigned int start, WordList &keywords, Accessor &styler, int keywordtype) { + bool FoundKeyword = false; + + for (unsigned int i = 0; + strlen(keywords[i]) > 0 && !FoundKeyword; + i++) { + if (atoi(keywords[i]) == keywordtype) { + FoundKeyword = styler.Match(start, ((char *)keywords[i]) + 2); + } + } + return FoundKeyword; +} + +static bool IsCommentLine(int line, Accessor &styler) { + unsigned int Pos = styler.LineStart(line); + while (styler.GetLine(Pos) == line) { + int PosStyle = styler.StyleAt(Pos); + + if ( !IsStreamCommentStyle(PosStyle) + && + PosStyle != SCE_C_COMMENTLINEDOC + && + PosStyle != SCE_C_COMMENTLINE + && + !IsASpace(styler.SafeGetCharAt(Pos)) + ) + return false; + Pos++; + } + + return true; +} + +static void FoldBoxCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords4 = *keywordlists[3]; + + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + bool firstLine = true; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + int levelPrevPrev; + int levelFlags = 0; + int levelUnindent = 0; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + + if (lineCurrent == 0) { + levelPrevPrev = levelPrev; + } else { + levelPrevPrev = styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK; + } + + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + + if (foldComment && IsStreamCommentStyle(style)) { + if (!IsStreamCommentStyle(stylePrev)) { + levelCurrent++; + } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { + // Comments don't end at end of line and the next character may be unstyled. + levelCurrent--; + } + } + + if (foldComment && (style == SCE_C_COMMENTLINE)) { + if ((ch == '/') && (chNext == '/')) { + char chNext2 = styler.SafeGetCharAt(i + 2); + if (chNext2 == '{') { + levelCurrent++; + } else if (chNext2 == '}') { + levelCurrent--; + } + } + } + + if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { + if (ch == '#') { + unsigned int j = i + 1; + while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { + j++; + } + + if (styler.Match(j, "region") || styler.Match(j, "if")) { + levelCurrent++; + } else if (styler.Match(j, "end")) { + levelCurrent--; + } + } + } + + if (style == SCE_C_OPERATOR + || + style == SCE_C_COMMENT + || + style == SCE_C_COMMENTLINE) { + + if (ch == '{') { + levelCurrent++; + // Special handling if line has closing brace followed by opening brace. + if (levelCurrent == levelPrev) { + if (firstLine) + levelUnindent = 1; + else + levelUnindent = -1; + } + } else if (ch == '}') { + levelCurrent--; + } + } + + /* Check for fold header keyword at beginning of word */ + if ((style == SCE_C_WORD || style == SCE_C_COMMENT || style == SCE_C_COMMENTLINE) + && + (style != stylePrev)) { + if (matchKeyword(i, keywords4, styler, KEYWORD_BOXHEADER)) { + int line; + /* Loop backwards all empty or comment lines */ + for (line = lineCurrent - 1; + line >= 0 + && + levelCurrent == (styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK) + && + (styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0 + && + IsCommentLine(line, styler); + line--) { + /* just loop backwards */; + } + + line++; + /* Set Box header flag (if the previous line has no footer line) */ + if ((styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0) { + if (line == lineCurrent) { + /* in current line */ + levelFlags |= SC_FOLDLEVELBOXHEADERFLAG; + } else { + /* at top of all preceding comment lines */ + styler.SetLevel(line, styler.LevelAt(line) + | SC_FOLDLEVELBOXHEADERFLAG); + } + } + } + } + + if (matchKeyword(i, keywords4, styler, KEYWORD_FOLDCONTRACTED)) { + levelFlags |= SC_FOLDLEVELCONTRACTED; + } + + if (atEOL) { + int lev; + // Compute level correction for special case: '} else {' + if (levelUnindent < 0) { + levelPrev += levelUnindent; + } else { + levelCurrent += levelUnindent; + } + + lev = levelPrev; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + // Produce additional footer line (e.g. after closed if) + if (visibleChars == 0 + && + (levelPrev < levelPrevPrev)) + lev |= SC_FOLDLEVELBOXFOOTERFLAG; + // Produce footer line at line before (special handling for '} else {' + if (levelPrev < levelPrevPrev) { + styler.SetLevel(lineCurrent - 1, + styler.LevelAt(lineCurrent - 1) | SC_FOLDLEVELBOXFOOTERFLAG); + } + // Mark the fold header (the line that is always visible) + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + // Show a footer line at end of fold + if (levelCurrent < levelPrev) + lev |= SC_FOLDLEVELBOXFOOTERFLAG; + /* Show a footer line at the end of each procedure (level == SC_FOLDLEVELBASE) */ + if ((levelPrev == SC_FOLDLEVELBASE) + && + (levelPrevPrev > SC_FOLDLEVELBASE) + && + (visibleChars == 0)) { + lev |= SC_FOLDLEVELBOXFOOTERFLAG; + } + + lev |= levelFlags; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + + lineCurrent++; + levelPrevPrev = levelPrev; + levelPrev = levelCurrent; + levelUnindent = 0; + visibleChars = 0; + levelFlags = 0; + firstLine = false; + } + + if (!isspacechar(ch)) + visibleChars++; + } + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + +static void FoldNoBoxCppDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; @@ -308,8 +540,8 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis } if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { if (ch == '#') { - unsigned int j=i+1; - while ((j +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + + + +static inline bool IsAWordChar(const unsigned int ch) { + return (isalnum(ch) || ch == '-' || ch >= 161); +} + +inline bool IsCssOperator(const char ch) { + if (!isalnum(ch) && (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' || ch == '.' || ch == '#' || ch == '!' || ch == '@')) + return true; + return false; +} + +static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { + WordList &keywords = *keywordlists[0]; + WordList &pseudoClasses = *keywordlists[1]; + + StyleContext sc(startPos, length, initStyle, styler); + + int lastState = -1; // before operator + int lastStateC = -1; // before comment + int op = ' '; // last operator + + for (; sc.More(); sc.Forward()) { + if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) { + if (lastStateC == -1) { + // backtrack to get last state + unsigned int i = startPos; + for (; i > 0; i--) { + if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) { + if (lastStateC == SCE_CSS_OPERATOR) { + op = styler.SafeGetCharAt(i-1); + while (--i) { + lastState = styler.StyleAt(i-1); + if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT) + break; + } + if (i == 0) + lastState = SCE_CSS_DEFAULT; + } + break; + } + } + if (i == 0) + lastStateC = SCE_CSS_DEFAULT; + } + sc.Forward(); + sc.ForwardSetState(lastStateC); + } + + if (sc.state == SCE_CSS_COMMENT) + continue; + + if (sc.state == SCE_CSS_OPERATOR) { + if (op == ' ') { + unsigned int i = startPos; + op = styler.SafeGetCharAt(i-1); + while (--i) { + lastState = styler.StyleAt(i-1); + if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT) + break; + } + } + switch (op) { + case '@': + if (lastState == SCE_CSS_DEFAULT) + sc.SetState(SCE_CSS_DIRECTIVE); + break; + case '{': + if (lastState == SCE_CSS_DIRECTIVE) + sc.SetState(SCE_CSS_DEFAULT); + else if (lastState == SCE_CSS_TAG) + sc.SetState(SCE_CSS_IDENTIFIER); + break; + case '}': + if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT || lastState == SCE_CSS_IDENTIFIER) + sc.SetState(SCE_CSS_DEFAULT); + break; + case ':': + if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID) + sc.SetState(SCE_CSS_PSEUDOCLASS); + else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_UNKNOWN_IDENTIFIER) + sc.SetState(SCE_CSS_VALUE); + break; + case '.': + if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT) + sc.SetState(SCE_CSS_CLASS); + break; + case '#': + if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT) + sc.SetState(SCE_CSS_ID); + break; + case ',': + if (lastState == SCE_CSS_TAG) + sc.SetState(SCE_CSS_DEFAULT); + break; + case ';': + if (lastState == SCE_CSS_DIRECTIVE) + sc.SetState(SCE_CSS_DEFAULT); + else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT) + sc.SetState(SCE_CSS_IDENTIFIER); + break; + case '!': + if (lastState == SCE_CSS_VALUE) + sc.SetState(SCE_CSS_IMPORTANT); + break; + } + } + + if (IsAWordChar(sc.ch)) { + if (sc.state == SCE_CSS_DEFAULT) + sc.SetState(SCE_CSS_TAG); + continue; + } + + if (IsAWordChar(sc.chPrev) && ( + sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER + || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS + || sc.state == SCE_CSS_IMPORTANT + )) { + char s[100]; + sc.GetCurrentLowered(s, sizeof(s)); + char *s2 = s; + while (*s2 && !IsAWordChar(*s2)) + s2++; + switch (sc.state) { + case SCE_CSS_IDENTIFIER: + if (!keywords.InList(s2)) + sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER); + break; + case SCE_CSS_UNKNOWN_IDENTIFIER: + if (keywords.InList(s2)) + sc.ChangeState(SCE_CSS_IDENTIFIER); + break; + case SCE_CSS_PSEUDOCLASS: + if (!pseudoClasses.InList(s2)) + sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS); + break; + case SCE_CSS_UNKNOWN_PSEUDOCLASS: + if (pseudoClasses.InList(s2)) + sc.ChangeState(SCE_CSS_PSEUDOCLASS); + break; + case SCE_CSS_IMPORTANT: + if (strcmp(s2, "important") != 0) + sc.ChangeState(SCE_CSS_VALUE); + break; + } + } + + if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS || sc.state == SCE_CSS_ID)) + sc.SetState(SCE_CSS_TAG); + + if (sc.Match('/', '*')) { + lastStateC = sc.state; + sc.SetState(SCE_CSS_COMMENT); + sc.Forward(); + continue; + } + + if (IsCssOperator(static_cast(sc.ch)) + && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!') + && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{') + ) { + if (sc.state != SCE_CSS_OPERATOR) + lastState = sc.state; + sc.SetState(SCE_CSS_OPERATOR); + op = sc.ch; + } + } + + sc.Complete(); +} + +static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = styler[startPos]; + bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT); + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int style = styler.StyleAt(i); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (foldComment) { + if (!inComment && (style == SCE_CSS_COMMENT)) + levelCurrent++; + else if (inComment && (style != SCE_CSS_COMMENT)) + levelCurrent--; + inComment = (style == SCE_CSS_COMMENT); + } + if (style == SCE_CSS_OPERATOR) { + if (ch == '{') { + levelCurrent++; + } else if (ch == '}') { + levelCurrent--; + } + } + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelPrev = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + +LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc); diff --git a/contrib/src/stc/scintilla/src/LexCrontab.cxx b/contrib/src/stc/scintilla/src/LexCrontab.cxx index 37729cbfdd..3c28830585 100644 --- a/contrib/src/stc/scintilla/src/LexCrontab.cxx +++ b/contrib/src/stc/scintilla/src/LexCrontab.cxx @@ -62,7 +62,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi state = SCE_NNCRONTAB_TASK; styler.ColourTo(i,SCE_NNCRONTAB_TASK); } - else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' || + else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' || styler.SafeGetCharAt(i+1) == '\t')) { // signals the start of an extended comment... state = SCE_NNCRONTAB_COMMENT; diff --git a/contrib/src/stc/scintilla/src/LexEiffel.cxx b/contrib/src/stc/scintilla/src/LexEiffel.cxx index a0bf26a5ea..3eac2f0358 100644 --- a/contrib/src/stc/scintilla/src/LexEiffel.cxx +++ b/contrib/src/stc/scintilla/src/LexEiffel.cxx @@ -28,7 +28,7 @@ static inline bool isEiffelOperator(unsigned int ch) { ch == '{' || ch == '}' || ch == '~' || ch == '[' || ch == ']' || ch == ';' || ch == '<' || ch == '>' || ch == ',' || - ch == '.' || ch == '^' || ch == '%' || ch == ':' || + ch == '.' || ch == '^' || ch == '%' || ch == ':' || ch == '!' || ch == '@' || ch == '?'; } @@ -187,19 +187,19 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init s[j] = '\0'; if ( - (strcmp(s, "check") == 0) || - (strcmp(s, "debug") == 0) || - (strcmp(s, "deferred") == 0) || - (strcmp(s, "do") == 0) || + (strcmp(s, "check") == 0) || + (strcmp(s, "debug") == 0) || + (strcmp(s, "deferred") == 0) || + (strcmp(s, "do") == 0) || (strcmp(s, "from") == 0) || (strcmp(s, "if") == 0) || - (strcmp(s, "inspect") == 0) || + (strcmp(s, "inspect") == 0) || (strcmp(s, "once") == 0) ) levelCurrent++; if (!lastDeferred && (strcmp(s, "class") == 0)) levelCurrent++; - if (strcmp(s, "end") == 0) + if (strcmp(s, "end") == 0) levelCurrent--; lastDeferred = strcmp(s, "deferred") == 0; } diff --git a/contrib/src/stc/scintilla/src/LexFortran.cxx b/contrib/src/stc/scintilla/src/LexFortran.cxx new file mode 100644 index 0000000000..e2109a0ab5 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexFortran.cxx @@ -0,0 +1,310 @@ +// Scintilla source code edit control +/** @file LexFortran.cxx + ** Lexer for Fortran. + ** Writen by Chuan-jian Shen, Last changed Nov. 2002 + **/ +// Copyright 1998-2001 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%'); +} + +static inline bool IsAWordStart(const int ch) { + return (ch < 0x80) && (isalnum(ch)); +} + +inline bool IsABlank(unsigned int ch) { + return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; +} +static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler, bool isFixFormat) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + + int posLineStart = 0, prevState = 0; + int endPos = startPos + length; + + // backtrack to the beginning of the document, this may be slow for big documents. + // initStyle = SCE_F_DEFAULT; + // StyleContext sc(0, startPos+length, initStyle, styler); + + // backtrack to the nearest keyword + while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) { + startPos--; + } + startPos = styler.LineStart(styler.GetLine(startPos)); + initStyle = styler.StyleAt(startPos - 1); + StyleContext sc(startPos, endPos-startPos, initStyle, styler); + + for (; sc.More(); sc.Forward()) { + + // remember the position of the line + if (sc.atLineStart) { + posLineStart = sc.currentPos; + sc.SetState(SCE_F_DEFAULT); + } + + // Handle line continuation generically. + if (sc.ch == '&') { + char chTemp = ' '; + int j = 1; + while (IsABlank(chTemp) && j<132) { + chTemp = static_cast(sc.GetRelative(j)); + j ++; + } + if (chTemp == '!') { + sc.SetState(SCE_F_CONTINUATION); + if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT); + } else if (chTemp == '\r' || chTemp == '\n') { + int currentState = sc.state; + sc.SetState(SCE_F_CONTINUATION); + if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) { + sc.ForwardSetState(SCE_F_DEFAULT); + while (IsASpace(sc.ch) && sc.More()) sc.Forward(); + if (sc.ch == '&') { + sc.SetState(SCE_F_CONTINUATION); + sc.Forward(); + } + sc.SetState(currentState); + } + } + continue; + } + + // Determine if the current state should terminate. + if (sc.state == SCE_F_OPERATOR) { + sc.SetState(SCE_F_DEFAULT); + } else if (sc.state == SCE_F_NUMBER) { + if (!IsAWordChar(sc.ch)) { + sc.SetState(SCE_F_DEFAULT); + } + } else if (sc.state == SCE_F_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '%')) { + char s[100]; + sc.GetCurrentLowered(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_F_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_F_WORD2); + } else if (keywords3.InList(s)) { + sc.ChangeState(SCE_F_WORD3); + } + sc.SetState(SCE_F_DEFAULT); + } + } else if (sc.state == SCE_F_COMMENT) { + if (sc.ch == '\r' || sc.ch == '\n') { + sc.SetState(SCE_F_DEFAULT); + } + } else if (sc.state == SCE_F_STRING1) { + prevState = sc.state; + if (sc.ch == '\'') { + if (sc.chNext == '\'') { + sc.Forward(); + } else { + sc.ForwardSetState(SCE_F_DEFAULT); + prevState = SCE_F_DEFAULT; + } + } else if (sc.atLineEnd) { + if (isFixFormat) { + sc.ForwardSetState(SCE_F_DEFAULT); + posLineStart = sc.currentPos; + } else { + sc.ChangeState(SCE_F_STRINGEOL); + sc.ForwardSetState(SCE_F_DEFAULT); + } + } + } else if (sc.state == SCE_F_STRING2) { + prevState = sc.state; + if (sc.atLineEnd) { + if (isFixFormat) { + sc.ForwardSetState(SCE_F_DEFAULT); + posLineStart = sc.currentPos; + } else { + sc.ChangeState(SCE_F_STRINGEOL); + sc.ForwardSetState(SCE_F_DEFAULT); + } + } else if (sc.ch == '\"') { + if (sc.chNext == '\"') { + sc.Forward(); + } else { + sc.ForwardSetState(SCE_F_DEFAULT); + prevState = SCE_F_DEFAULT; + } + } + } else if (sc.state == SCE_F_OPERATOR2) { + if (sc.ch == '.') { + sc.ForwardSetState(SCE_F_DEFAULT); + } + } else if (sc.state == SCE_F_CONTINUATION) { + sc.SetState(SCE_F_DEFAULT); + } else if (sc.state == SCE_F_LABEL) { + if (sc.currentPos >= static_cast(posLineStart+5)) { + sc.SetState(SCE_F_DEFAULT); + } + } + + // Determine if a new state should be entered. + if (sc.state == SCE_F_DEFAULT) { + int toLineStart = sc.currentPos - posLineStart; + if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) { + if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') { + sc.SetState(SCE_F_COMMENT); + } else if (toLineStart > 72) { + sc.SetState(SCE_F_COMMENT); + } else if (toLineStart < 5 && !IsASpace(sc.ch)) { + sc.SetState(SCE_F_LABEL); + } else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) { + sc.SetState(SCE_F_CONTINUATION); + sc.ForwardSetState(prevState); + } + } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_F_NUMBER); + } else if (sc.ch == '.' && isalpha(sc.chNext)) { + sc.SetState(SCE_F_OPERATOR2); + } else if (IsAWordStart(sc.ch)) { + sc.SetState(SCE_F_IDENTIFIER); + } else if (sc.ch == '!') { + sc.SetState(SCE_F_COMMENT); + } else if (sc.ch == '\"') { + sc.SetState(SCE_F_STRING2); + } else if (sc.ch == '\'') { + sc.SetState(SCE_F_STRING1); + } else if (isoperator(static_cast(sc.ch))) { + sc.SetState(SCE_F_OPERATOR); + } + } + } + sc.Complete(); +} + +// The folding depends on the mercy of the programer. +static int classifyFoldPointFortran(const char* s, const char* prevWord) { + int lev = 0; + if (strcmp(prevWord, "end") == 0) return lev; + if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) + return -1; + if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 + || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 + || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 + || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0 + || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0 + || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0 + || strcmp(s, "then") == 0 || strcmp(s, "where") == 0) { + lev = 1; + } else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0 + || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0 + || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0 + || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0 + || strcmp(s, "endif") == 0 + || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0 + || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0 + || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0 + || strcmp(s, "endwhere") == 0 || strcmp(s, "procedure") == 0 ) { + lev = -1; + } + return lev; +} +static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { + //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + // Do not know how to fold the comment at the moment. + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + + int lastStart = 0; + char prevWord[32] = ""; + + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + + if (stylePrev == SCE_F_DEFAULT && style == SCE_F_WORD) + { + // Store last word start point. + lastStart = i; + } + + if (style == SCE_F_WORD) { + if(iswordchar(ch) && !iswordchar(chNext)) { + char s[32]; + unsigned int j; + for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) { + s[j] = static_cast(tolower(styler[lastStart + j])); + } + s[j] = '\0'; + levelCurrent += classifyFoldPointFortran(s, prevWord); + strcpy(prevWord, s); + } + } + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelPrev = levelCurrent; + visibleChars = 0; + strcpy(prevWord, ""); + } + + if (!isspacechar(ch)) + visibleChars++; + } + + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + +static const char * const FortranWordLists[] = { + "Primary keywords and identifiers", + "Intrinsic functions", + "Extended and user defined functions", + 0, +}; + +static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false); +} + +static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true); +} + + +LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists); +LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists); diff --git a/contrib/src/stc/scintilla/src/LexHTML.cxx b/contrib/src/stc/scintilla/src/LexHTML.cxx index 545bbfd553..345b15edcb 100644 --- a/contrib/src/stc/scintilla/src/LexHTML.cxx +++ b/contrib/src/stc/scintilla/src/LexHTML.cxx @@ -2,7 +2,7 @@ /** @file LexHTML.cxx ** Lexer for HTML. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -197,16 +197,30 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k } static int classifyTagHTML(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { - char s[30 + 1]; + WordList &keywords, Accessor &styler, bool &tagDontFold, + bool caseSensitive) { + char s[30 + 2]; // Copy after the '<' unsigned int i = 0; for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) { char ch = styler[cPos]; - if ((ch != '<') && (ch != '/')) - s[i++] = static_cast(tolower(ch)); + if ((ch != '<') && (ch != '/')) { + s[i++] = caseSensitive ? ch : static_cast(tolower(ch)); + } } + + //The following is only a quick hack, to see if this whole thing would work + //we first need the tagname with a trailing space... + s[i] = ' '; + s[i+1] = '\0'; + + //...to find it in the list of no-container-tags + // (There are many more. We will need a keywordlist in the property file for this) + tagDontFold = (NULL != strstr("meta link img area br hr input ",s)); + + //now we can remove the trailing space s[i] = '\0'; + bool isScript = false; char chAttr = SCE_H_TAGUNKNOWN; if (s[0] == '!') { @@ -368,6 +382,14 @@ static inline bool issgmlwordchar(char ch) { return isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '['; } +static inline bool IsPhpWordStart(const unsigned char ch) { + return isalpha(ch) || (ch == '_') || (ch >= 0x7f); +} + +static inline bool IsPhpWordChar(char ch) { + return isdigit(ch) || IsPhpWordStart(ch); +} + static bool InTagState(int state) { return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || state == SCE_H_SCRIPT || @@ -433,6 +455,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag + bool tagDontFold = false; //some HTML tags should not be folded script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state @@ -440,8 +463,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty script_type scriptLanguage = ScriptOfState(state); const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0; - const bool fold = foldHTML && styler.GetPropertyInt("fold"); + const bool fold = foldHTML && styler.GetPropertyInt("fold", 0); + const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1); const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0; int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; @@ -481,7 +506,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty case eScriptPHP: //not currently supported case eScriptVBS: - if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC)) { + if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) { + //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle); + //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) { if ((ch == '{') || (ch == '}')) { levelCurrent += (ch == '{') ? 1 : -1; } @@ -600,9 +627,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty else inScriptType = eNonHtmlPreProc; // fold whole script - levelCurrent++; - if (scriptLanguage == eScriptXML) - levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case) + if (foldHTMLPreprocessor){ + levelCurrent++; + if (scriptLanguage == eScriptXML) + levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case) + } // should be better ch = styler.SafeGetCharAt(i); continue; @@ -640,7 +669,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty scriptLanguage = eScriptVBS; styler.ColourTo(i, SCE_H_ASP); // fold whole script - levelCurrent++; + if (foldHTMLPreprocessor) + levelCurrent++; // should be better ch = styler.SafeGetCharAt(i); continue; @@ -665,8 +695,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_H_SGML_COMMAND; // wait for a pending command } // fold whole tag (-- when closing the tag) - - levelCurrent++; + if (foldHTMLPreprocessor) + levelCurrent++; continue; } @@ -723,7 +753,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty inScriptType = eHtml; scriptLanguage = eScriptNone; // unfold all scripting languages - levelCurrent--; + if (foldHTMLPreprocessor) + levelCurrent--; continue; } ///////////////////////////////////// @@ -904,7 +935,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty break; case SCE_H_TAGUNKNOWN: if (!ishtmlwordchar(ch) && !((ch == '/') && (chPrev == '<')) && ch != '[') { - int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); + int eClass = classifyTagHTML(styler.GetStartSegment(), + i - 1, keywords, styler, tagDontFold, caseSensitive); if (eClass == SCE_H_SCRIPT) { if (!tagClosing) { inScriptType = eNonHtmlScript; @@ -923,10 +955,12 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_H_DEFAULT; } tagOpened = false; - if (tagClosing) { - levelCurrent--; - } else { - levelCurrent++; + if (!tagDontFold){ + if (tagClosing) { + levelCurrent--; + } else { + levelCurrent++; + } } tagClosing = false; } else if (ch == '/' && chNext == '>') { @@ -969,10 +1003,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_H_DEFAULT; } tagOpened = false; - if (tagClosing) - levelCurrent--; - else - levelCurrent++; + if (!tagDontFold){ + if (tagClosing){ + levelCurrent--; + } else { + levelCurrent++; + } + } tagClosing = false; } else if (ch == '=') { styler.ColourTo(i, SCE_H_OTHER); @@ -992,10 +1029,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_H_DEFAULT; } tagOpened = false; - if (tagClosing) - levelCurrent--; - else - levelCurrent++; + if (!tagDontFold){ + if (tagClosing){ + levelCurrent--; + } else { + levelCurrent++; + } + } tagClosing = false; } else if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); @@ -1044,10 +1084,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty break; case SCE_H_VALUE: if (!ishtmlwordchar(ch)) { - if (ch == '\"') { + if (ch == '\"' && chPrev == '=') { // Should really test for being first character state = SCE_H_DOUBLESTRING; - } else if (ch == '\'') { + } else if (ch == '\'' && chPrev == '=') { state = SCE_H_SINGLESTRING; } else { if (IsNumber(styler.GetStartSegment(), styler)) { @@ -1063,10 +1103,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_H_DEFAULT; } tagOpened = false; - if (tagClosing) - levelCurrent--; - else - levelCurrent++; + if (!tagDontFold){ + if (tagClosing){ + levelCurrent--; + } else { + levelCurrent++; + } + } tagClosing = false; } else { state = SCE_H_OTHER; @@ -1397,7 +1440,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty break; ///////////// start - PHP state handling case SCE_HPHP_WORD: - if (!iswordstart(ch)) { + if (!iswordchar(ch)) { classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); if (ch == '/' && chNext == '*') { i++; @@ -1411,7 +1454,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HPHP_HSTRING; } else if (ch == '\'') { state = SCE_HPHP_SIMPLESTRING; - } else if (ch == '$') { + } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (isoperator(ch)) { state = SCE_HPHP_OPERATOR; @@ -1430,7 +1473,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } break; case SCE_HPHP_VARIABLE: - if (!iswordstart(ch)) { + if (!IsPhpWordChar(ch)) { styler.ColourTo(i - 1, SCE_HPHP_VARIABLE); if (isoperator(ch)) state = SCE_HPHP_OPERATOR; @@ -1454,7 +1497,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty if (ch == '\\') { // skip the next char i++; - } else if (ch == '$') { + } else if (ch == '$' && IsPhpWordStart(chNext)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HPHP_HSTRING_VARIABLE; } else if (ch == '\"') { @@ -1472,7 +1515,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } break; case SCE_HPHP_HSTRING_VARIABLE: - if (!iswordstart(ch)) { + if (!IsPhpWordChar(ch)) { styler.ColourTo(i - 1, StateToPrint); i--; // strange but it works state = SCE_HPHP_HSTRING; @@ -1497,7 +1540,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HPHP_HSTRING; } else if (ch == '\'') { state = SCE_HPHP_SIMPLESTRING; - } else if (ch == '$') { + } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (isoperator(ch)) { state = SCE_HPHP_OPERATOR; @@ -1553,7 +1596,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } StateToPrint = statePrintForState(state, inScriptType); - styler.ColourTo(lengthDoc - 1, StateToPrint); + styler.ColourTo(lengthDoc - 1, StateToPrint); // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (fold) { @@ -1701,9 +1744,9 @@ static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) { sc.SetState(SCE_H_ENTITY); } } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) { - if (sc.ch == '\"') { + if (sc.ch == '\"' && sc.chPrev == '=') { sc.SetState(SCE_H_DOUBLESTRING); - } else if (sc.ch == '\'') { + } else if (sc.ch == '\'' && sc.chPrev == '=') { sc.SetState(SCE_H_SINGLESTRING); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_H_NUMBER); @@ -1780,7 +1823,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) { // Handle some PHP script if (sc.state == SCE_HPHP_WORD) { - if (!IsAWordStart(sc.ch)) { + if (!IsPhpWordChar(static_cast(sc.ch))) { sc.SetState(SCE_HPHP_DEFAULT); } } else if (sc.state == SCE_HPHP_COMMENTLINE) { @@ -1802,7 +1845,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) { sc.ForwardSetState(SCE_HPHP_DEFAULT); } } else if (sc.state == SCE_HPHP_VARIABLE) { - if (!IsAWordStart(sc.ch)) { + if (!IsPhpWordChar(static_cast(sc.ch))) { sc.SetState(SCE_HPHP_DEFAULT); } } else if (sc.state == SCE_HPHP_OPERATOR) { @@ -1822,7 +1865,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) { } } if (sc.state == SCE_HPHP_DEFAULT) { - if (IsAWordStart(sc.ch)) { + if (IsPhpWordStart(static_cast(sc.ch))) { sc.SetState(SCE_HPHP_WORD); } else if (sc.ch == '#') { sc.SetState(SCE_HPHP_COMMENTLINE); @@ -1836,7 +1879,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) { sc.SetState(SCE_HPHP_HSTRING); } else if (sc.ch == '\'') { sc.SetState(SCE_HPHP_SIMPLESTRING); - } else if (sc.ch == '$') { + } else if (sc.ch == '$' && IsPhpWordStart(static_cast(sc.chNext))) { sc.SetState(SCE_HPHP_VARIABLE); } else if (isoperator(static_cast(sc.ch))) { sc.SetState(SCE_HPHP_OPERATOR); diff --git a/contrib/src/stc/scintilla/src/LexLisp.cxx b/contrib/src/stc/scintilla/src/LexLisp.cxx index cb150ff76d..16898a3df1 100644 --- a/contrib/src/stc/scintilla/src/LexLisp.cxx +++ b/contrib/src/stc/scintilla/src/LexLisp.cxx @@ -98,7 +98,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W if (isLispwordstart(ch)) { styler.ColourTo(i - 1, state); state = SCE_LISP_IDENTIFIER; - } + } else if (ch == ';') { styler.ColourTo(i - 1, state); state = SCE_LISP_COMMENT; @@ -107,7 +107,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_LISP_OPERATOR); } - + else if (ch == '\"') { state = SCE_LISP_STRING; } @@ -115,12 +115,12 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W if (!isLispwordstart(ch)) { classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_LISP_DEFAULT; - } /*else*/ + } /*else*/ if (isLispoperator(ch) || ch=='\'') { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_LISP_OPERATOR); } - + } else { if (state == SCE_LISP_COMMENT) { if (atEOL) { diff --git a/contrib/src/stc/scintilla/src/LexLua.cxx b/contrib/src/stc/scintilla/src/LexLua.cxx index fc9607e25d..b7920ef209 100644 --- a/contrib/src/stc/scintilla/src/LexLua.cxx +++ b/contrib/src/stc/scintilla/src/LexLua.cxx @@ -23,8 +23,6 @@ #include "Scintilla.h" #include "SciLexer.h" -#define SCE_LUA_LAST_STYLE SCE_LUA_WORD6 - static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } @@ -61,14 +59,16 @@ static void ColouriseLuaDoc( WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; - // Must initialize the literal string nesting level, if we are inside such a string. + int currentLine = styler.GetLine(startPos); + // Initialize the literal string [[ ... ]] nesting level, if we are inside such a string. int literalStringLevel = 0; if (initStyle == SCE_LUA_LITERALSTRING) { - literalStringLevel = 1; + literalStringLevel = styler.GetLineState(currentLine - 1); } - // We use states above the last one to indicate nesting level of literal strings - if (initStyle > SCE_LUA_LAST_STYLE) { - literalStringLevel = initStyle - SCE_LUA_LAST_STYLE + 1; + // Initialize the block comment --[[ ... ]] nesting level, if we are inside such a comment + int blockCommentLevel = 0; + if (initStyle == SCE_LUA_COMMENT) { + blockCommentLevel = styler.GetLineState(currentLine - 1); } // Do not leak onto next line @@ -78,9 +78,28 @@ static void ColouriseLuaDoc( StyleContext sc(startPos, length, initStyle, styler); if (startPos == 0 && sc.ch == '#') { + // shbang line: # is a comment only if first char of the script sc.SetState(SCE_LUA_COMMENTLINE); } for (; sc.More(); sc.Forward()) { + if (sc.atLineEnd) { + // Update the line state, so it can be seen by next line + currentLine = styler.GetLine(sc.currentPos); + switch (sc.state) { + case SCE_LUA_LITERALSTRING: + // Inside a literal string, we set the line state + styler.SetLineState(currentLine, literalStringLevel); + break; + case SCE_LUA_COMMENT: // Block comment + // Inside a block comment, we set the line state + styler.SetLineState(currentLine, blockCommentLevel); + break; + default: + // Reset the line state + styler.SetLineState(currentLine, 0); + break; + } + } if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) { // Prevent SCE_LUA_STRINGEOL from leaking back to previous line sc.SetState(SCE_LUA_STRING); @@ -88,7 +107,7 @@ static void ColouriseLuaDoc( // Handle string line continuation if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) && - sc.ch == '\\') { + sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { @@ -154,22 +173,31 @@ static void ColouriseLuaDoc( sc.ChangeState(SCE_LUA_STRINGEOL); sc.ForwardSetState(SCE_LUA_DEFAULT); } - } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state > SCE_LUA_LAST_STYLE) { + } else if (sc.state == SCE_LUA_LITERALSTRING) { if (sc.Match('[', '[')) { literalStringLevel++; - sc.SetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1); + sc.Forward(); + sc.SetState(SCE_LUA_LITERALSTRING); } else if (sc.Match(']', ']') && literalStringLevel > 0) { literalStringLevel--; sc.Forward(); if (literalStringLevel == 0) { sc.ForwardSetState(SCE_LUA_DEFAULT); - } else if (literalStringLevel == 1) { - sc.ForwardSetState(SCE_LUA_LITERALSTRING); - } else { - sc.ForwardSetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1); + } + } + } else if (sc.state == SCE_LUA_COMMENT) { // Lua 5.0's block comment + if (sc.Match('[', '[')) { + blockCommentLevel++; + sc.Forward(); + } else if (sc.Match(']', ']') && blockCommentLevel > 0) { + blockCommentLevel--; + sc.Forward(); + if (blockCommentLevel == 0) { + sc.ForwardSetState(SCE_LUA_DEFAULT); } } } + // Determine if a new state should be entered. if (sc.state == SCE_LUA_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { @@ -184,12 +212,16 @@ static void ColouriseLuaDoc( literalStringLevel = 1; sc.SetState(SCE_LUA_LITERALSTRING); sc.Forward(); + } else if (sc.Match("--[[")) { // Lua 5.0's block comment + blockCommentLevel = 1; + sc.SetState(SCE_LUA_COMMENT); + sc.Forward(3); } else if (sc.Match('-', '-')) { sc.SetState(SCE_LUA_COMMENTLINE); sc.Forward(); - } else if (sc.Match('$') && sc.atLineStart) { + } else if (sc.atLineStart && sc.Match('$')) { sc.SetState(SCE_LUA_PREPROCESSOR); // Obsolete since Lua 4.0, but still in old code - } else if (isLuaOperator(static_cast(sc.ch))) { + } else if (isLuaOperator(static_cast(sc.ch))) { sc.SetState(SCE_LUA_OPERATOR); } } @@ -197,7 +229,6 @@ static void ColouriseLuaDoc( sc.Complete(); } - static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; diff --git a/contrib/src/stc/scintilla/src/LexMatlab.cxx b/contrib/src/stc/scintilla/src/LexMatlab.cxx index f75d15c7ab..6f2c64bc75 100644 --- a/contrib/src/stc/scintilla/src/LexMatlab.cxx +++ b/contrib/src/stc/scintilla/src/LexMatlab.cxx @@ -2,7 +2,7 @@ /** @file LexMatlab.cxx ** Lexer for Matlab. ** Written by José Fonseca - **/ + **/ // Copyright 1998-2001 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. diff --git a/contrib/src/stc/scintilla/src/LexOthers.cxx b/contrib/src/stc/scintilla/src/LexOthers.cxx index babb3a0d37..be512abbdd 100644 --- a/contrib/src/stc/scintilla/src/LexOthers.cxx +++ b/contrib/src/stc/scintilla/src/LexOthers.cxx @@ -164,13 +164,17 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) { styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (0 == strncmp(lineBuffer, "+++ ", 3)) { styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (0 == strncmp(lineBuffer, "***", 3)) { + } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff + styler.ColourTo(endLine, SCE_DIFF_HEADER); + } else if (0 == strncmp(lineBuffer, "***", 3)) { + styler.ColourTo(endLine, SCE_DIFF_HEADER); + } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (lineBuffer[0] == '@') { styler.ColourTo(endLine, SCE_DIFF_POSITION); - } else if (lineBuffer[0] == '-') { + } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') { styler.ColourTo(endLine, SCE_DIFF_DELETED); - } else if (lineBuffer[0] == '+') { + } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') { styler.ColourTo(endLine, SCE_DIFF_ADDED); } else if (lineBuffer[0] != ' ') { styler.ColourTo(endLine, SCE_DIFF_COMMENT); @@ -264,7 +268,7 @@ static void ColouriseMakeLine( Accessor &styler) { unsigned int i = 0; - unsigned int lastNonSpace = 0; + int lastNonSpace = -1; unsigned int state = SCE_MAKE_DEFAULT; bool bSpecial = false; // Skip initial spaces @@ -291,13 +295,15 @@ static void ColouriseMakeLine( if (lineBuffer[i] == ':') { // We should check that no colouring was made since the beginning of the line, // to avoid colouring stuff like /OUT:file - styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET); + if (lastNonSpace >= 0) + styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET); styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); bSpecial = true; // Only react to the first ':' of the line state = SCE_MAKE_DEFAULT; } else if (lineBuffer[i] == '=') { - styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER); + if (lastNonSpace >= 0) + styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER); styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); bSpecial = true; // Only react to the first '=' of the line @@ -359,6 +365,8 @@ static void ColouriseErrorListLine( styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION); } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { styler.ColourTo(endPos, SCE_ERR_PYTHON); + } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { + styler.ColourTo(endPos, SCE_ERR_PHP); } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { // Borland error message styler.ColourTo(endPos, SCE_ERR_BORLAND); @@ -413,7 +421,7 @@ static void ColouriseErrorListLine( break; } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { state = 99; - } else if ((state == 20) && (lineBuffer[i-1] == '\t') && + } else if ((state == 20) && (lineBuffer[i-1] == '\t') && ((lineBuffer[i] == '/' && lineBuffer[i+1] == '^') || isdigit(lineBuffer[i]))) { state = 24; break; @@ -421,7 +429,7 @@ static void ColouriseErrorListLine( state = 21; } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) { state = 22; - break; + break; } } if (state == 3) { @@ -429,7 +437,7 @@ static void ColouriseErrorListLine( } else if ((state == 13) || (state == 14) || (state == 15)) { styler.ColourTo(endPos, SCE_ERR_MS); } else if (((state == 22) || (state == 24)) && (lineBuffer[0] != '\t')) { - styler.ColourTo(endPos, SCE_ERR_CTAG); + styler.ColourTo(endPos, SCE_ERR_CTAG); } else { styler.ColourTo(endPos, SCE_ERR_DEFAULT); } diff --git a/contrib/src/stc/scintilla/src/LexPascal.cxx b/contrib/src/stc/scintilla/src/LexPascal.cxx index 37e5e995fb..59959290ff 100644 --- a/contrib/src/stc/scintilla/src/LexPascal.cxx +++ b/contrib/src/stc/scintilla/src/LexPascal.cxx @@ -34,7 +34,7 @@ static void getRange(unsigned int start, } static bool IsStreamCommentStyle(int style) { - return style == SCE_C_COMMENT || + return style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC || style == SCE_C_COMMENTDOCKEYWORD || style == SCE_C_COMMENTDOCKEYWORDERROR; @@ -50,7 +50,7 @@ static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList & WordList& keywords = *keywordlists[0]; WordList& classwords = *keywordlists[1]; - + char s[100]; getRange(start, end, styler, s, sizeof(s)); @@ -119,7 +119,7 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, styler.StartSegment(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; - + chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { @@ -329,7 +329,7 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word levelPrev = levelCurrent; visibleChars = 0; } - + if (!isspacechar(ch)) visibleChars++; } diff --git a/contrib/src/stc/scintilla/src/LexPerl.cxx b/contrib/src/stc/scintilla/src/LexPerl.cxx index 1715009c9d..e3167871a7 100644 --- a/contrib/src/stc/scintilla/src/LexPerl.cxx +++ b/contrib/src/stc/scintilla/src/LexPerl.cxx @@ -659,9 +659,64 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(lengthDoc - 1, state); } +static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[], + Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (foldComment && (style == SCE_PL_COMMENTLINE)) { + if ((ch == '/') && (chNext == '/')) { + char chNext2 = styler.SafeGetCharAt(i + 2); + if (chNext2 == '{') { + levelCurrent++; + } else if (chNext2 == '}') { + levelCurrent--; + } + } + } + if (style == SCE_C_OPERATOR) { + if (ch == '{') { + levelCurrent++; + } else if (ch == '}') { + levelCurrent--; + } + } + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelPrev = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + static const char * const perlWordListDesc[] = { "Perl keywords", 0 }; -LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", 0, perlWordListDesc); +LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexPython.cxx b/contrib/src/stc/scintilla/src/LexPython.cxx index bfaa08f0e9..7f5ec8e282 100644 --- a/contrib/src/stc/scintilla/src/LexPython.cxx +++ b/contrib/src/stc/scintilla/src/LexPython.cxx @@ -1,7 +1,7 @@ // Scintilla source code edit control /** @file LexPython.cxx ** Lexer for Python. - **/ + **/ // Copyright 1998-2002 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. @@ -42,7 +42,7 @@ static bool IsPyStringStart(int ch, int chNext, int chNext2) { } /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */ -static int GetPyStringState(Accessor &styler, int i, int *nextIndex) { +static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex) { char ch = styler.SafeGetCharAt(i); char chNext = styler.SafeGetCharAt(i + 1); @@ -99,7 +99,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { - startPos = styler.LineStart(lineCurrent - 1); + lineCurrent--; + startPos = styler.LineStart(lineCurrent); if (startPos == 0) initStyle = SCE_P_DEFAULT; else @@ -139,6 +140,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, } else if (whingeLevel == 4) { chFlags = (spaceFlags & wsTab) ? chBad : chGood; } + sc.SetState(sc.state); styler.SetFlags(chFlags, static_cast(sc.state)); } @@ -148,7 +150,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, (sc.state == SCE_P_TRIPLEDOUBLE)) { // Perform colourisation of white space and triple quoted strings at end of each line to allow // tab marking to work inside white space and triple quoted strings - sc.ForwardSetState(sc.state); + sc.SetState(sc.state); } lineCurrent++; styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); @@ -160,6 +162,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, break; } + bool needEOLCheck = false; + // Check for a state end if (sc.state == SCE_P_OPERATOR) { kwLast = kwOther; @@ -212,8 +216,10 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, sc.Forward(); } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) { sc.ForwardSetState(SCE_P_DEFAULT); + needEOLCheck = true; } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) { sc.ForwardSetState(SCE_P_DEFAULT); + needEOLCheck = true; } } else if (sc.state == SCE_P_TRIPLE) { if (sc.ch == '\\') { @@ -222,6 +228,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_P_DEFAULT); + needEOLCheck = true; } } else if (sc.state == SCE_P_TRIPLEDOUBLE) { if (sc.ch == '\\') { @@ -230,9 +237,18 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_P_DEFAULT); + needEOLCheck = true; } } + // State exit code may have moved on to end of line + if (needEOLCheck && sc.atLineEnd) { + lineCurrent++; + styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); + if (!sc.More()) + break; + } + // Check for a new state starting character if (sc.state == SCE_P_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { @@ -247,7 +263,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, } else if (sc.ch == '#') { sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE); } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) { - int nextIndex = 0; + unsigned int nextIndex = 0; sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex)); while (nextIndex > (sc.currentPos + 1)) { sc.Forward(); @@ -357,34 +373,40 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse lev = lev + 1; } - // Skip past any blank lines for next indent level info; we skip also comments - // starting in column 0 which effectively folds them into surrounding code rather + // Skip past any blank lines for next indent level info; we skip also + // comments (all comments, not just those starting in column 0) + // which effectively folds them into surrounding code rather // than screwing up folding. - const int saveIndentNext = indentNext; + while (!quote && (lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || - (lineNext <= docLines && styler[styler.LineStart(lineNext)] == '#'))) { + (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } - // Next compute max indent level of current line and next non-blank line. - // This is the level to which we set all the intervening blank or comment lines. - const int skip_level = Platform::Maximum(indentCurrentLevel, - indentNext & SC_FOLDLEVELNUMBERMASK); + const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; + const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped - int skipLine = lineCurrent + 1; - int skipIndentNext = saveIndentNext; - while (skipLine < lineNext) { - int skipLineLevel = skip_level; - if (skipIndentNext & SC_FOLDLEVELWHITEFLAG) - skipLineLevel = SC_FOLDLEVELWHITEFLAG | skipLineLevel; - styler.SetLevel(skipLine, skipLineLevel); - skipLine++; - skipIndentNext = styler.IndentAmount(skipLine, &spaceFlags, NULL); + // Do this from end to start. Once we encounter one line + // which is indented more than the line after the end of + // the comment-block, use the level of the block before + + int skipLine = lineNext; + int skipLevel = levelAfterComments; + + while (--skipLine > lineCurrent) { + int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); + + if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) + skipLevel = levelBeforeComments; + + int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; + + styler.SetLevel(skipLine, skipLevel | whiteFlag); } // Set fold header on non-quote/non-comment line @@ -413,5 +435,5 @@ static const char * const pythonWordListDesc[] = { 0 }; -LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, +LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, pythonWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexRuby.cxx b/contrib/src/stc/scintilla/src/LexRuby.cxx index 35804e7107..0549f94064 100644 --- a/contrib/src/stc/scintilla/src/LexRuby.cxx +++ b/contrib/src/stc/scintilla/src/LexRuby.cxx @@ -221,7 +221,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle, } else if (isoperator(ch)) { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_P_OPERATOR); - } + } } else if (state == SCE_P_WORD) { if (!iswordchar(ch)) { ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); @@ -351,5 +351,5 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle, } } } - + LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc); diff --git a/contrib/src/stc/scintilla/src/LexVB.cxx b/contrib/src/stc/scintilla/src/LexVB.cxx index bd1248e044..d247ecbe32 100644 --- a/contrib/src/stc/scintilla/src/LexVB.cxx +++ b/contrib/src/stc/scintilla/src/LexVB.cxx @@ -37,7 +37,7 @@ static inline bool IsAWordStart(const int ch) { } static inline bool IsADateCharacter(const int ch) { - return (ch < 0x80) && + return (ch < 0x80) && (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t'); } @@ -49,7 +49,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, styler.StartAt(startPos); int visibleChars = 0; - + StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { @@ -83,7 +83,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_STRING) { - // VB doubles quotes to preserve them, so just end this string + // VB doubles quotes to preserve them, so just end this string // state now as a following quote will start again if (sc.ch == '\"') { if (tolower(sc.chNext) == 'c') { @@ -104,7 +104,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, sc.ForwardSetState(SCE_B_DEFAULT); } } - + if (sc.state == SCE_B_DEFAULT) { if (sc.ch == '\'') { sc.SetState(SCE_B_COMMENT); @@ -137,7 +137,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_B_OPERATOR); } } - + if (sc.atLineEnd) { visibleChars = 0; } diff --git a/contrib/src/stc/scintilla/src/LineMarker.cxx b/contrib/src/stc/scintilla/src/LineMarker.cxx index 009ea4ea50..ec9c86f74f 100644 --- a/contrib/src/stc/scintilla/src/LineMarker.cxx +++ b/contrib/src/stc/scintilla/src/LineMarker.cxx @@ -2,14 +2,37 @@ /** @file LineMarker.cxx ** Defines the look of a line marker in the margin . **/ -// Copyright 1998-2001 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +#include + #include "Platform.h" #include "Scintilla.h" +#include "XPM.h" #include "LineMarker.h" +void LineMarker::RefreshColourPalette(Palette &pal, bool want) { + pal.WantFind(fore, want); + pal.WantFind(back, want); + if (pxpm) { + pxpm->RefreshColourPalette(pal, want); + } +} + +void LineMarker::SetXPM(const char *textForm) { + delete pxpm; + pxpm = new XPM(textForm); + markType = SC_MARK_PIXMAP; +} + +void LineMarker::SetXPM(const char * const *linesForm) { + delete pxpm; + pxpm = new XPM(linesForm); + markType = SC_MARK_PIXMAP; +} + static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) { PRectangle rc; rc.left = centreX - armSize; @@ -41,6 +64,10 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C } void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) { + if ((markType == SC_MARK_PIXMAP) && (pxpm)) { + pxpm->Draw(surface, rcWhole); + return; + } // Restrict most shapes a bit PRectangle rc = rcWhole; rc.top++; @@ -122,121 +149,121 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac rcSmall.right = rc.right - 1; rcSmall.bottom = rc.bottom - 2; surface->RectangleDraw(rcSmall, fore.allocated, back.allocated); - + } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) { // An invisible marker so don't draw anything - + } else if (markType == SC_MARK_VLINE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_LCORNER) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); - + } else if (markType == SC_MARK_TCORNER) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); surface->MoveTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); - + } else if (markType == SC_MARK_LCORNERCURVE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); - + } else if (markType == SC_MARK_TCORNERCURVE) { surface->PenColour(back.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); - + } else if (markType == SC_MARK_BOXPLUS) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + } else if (markType == SC_MARK_BOXPLUSCONNECTED) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_BOXMINUS) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_BOXMINUSCONNECTED) { surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_CIRCLEPLUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType == SC_MARK_CIRCLEMINUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(back.allocated); DrawMinus(surface, centreX, centreY, blobSize, back.allocated); - + surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - + surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); - + } else if (markType >= SC_MARK_CHARACTER) { char character[1]; character[0] = static_cast(markType - SC_MARK_CHARACTER); int width = surface->WidthText(fontForCharacter, character, 1); rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; - surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, + surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, character, 1, fore.allocated, back.allocated); } else if (markType == SC_MARK_DOTDOTDOT) { diff --git a/contrib/src/stc/scintilla/src/LineMarker.h b/contrib/src/stc/scintilla/src/LineMarker.h index 7897aa7759..50a0331da1 100644 --- a/contrib/src/stc/scintilla/src/LineMarker.h +++ b/contrib/src/stc/scintilla/src/LineMarker.h @@ -2,7 +2,7 @@ /** @file LineMarker.h ** Defines the look of a line marker in the margin . **/ -// Copyright 1998-2001 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef LINEMARKER_H @@ -15,11 +15,34 @@ public: int markType; ColourPair fore; ColourPair back; + XPM *pxpm; LineMarker() { markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); back = ColourDesired(0xff,0xff,0xff); + pxpm = NULL; } + LineMarker(const LineMarker &) { + // Defined to avoid pxpm being blindly copied, not as real copy constructor + markType = SC_MARK_CIRCLE; + fore = ColourDesired(0,0,0); + back = ColourDesired(0xff,0xff,0xff); + pxpm = NULL; + } + ~LineMarker() { + delete pxpm; + } + LineMarker &operator=(const LineMarker &) { + // Defined to avoid pxpm being blindly copied, not as real assignment operator + markType = SC_MARK_CIRCLE; + fore = ColourDesired(0,0,0); + back = ColourDesired(0xff,0xff,0xff); + pxpm = NULL; + return *this; + } + void RefreshColourPalette(Palette &pal, bool want); + void SetXPM(const char *textForm); + void SetXPM(const char * const *linesForm); void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter); }; diff --git a/contrib/src/stc/scintilla/src/PropSet.cxx b/contrib/src/stc/scintilla/src/PropSet.cxx index b527c385ce..20495df960 100644 --- a/contrib/src/stc/scintilla/src/PropSet.cxx +++ b/contrib/src/stc/scintilla/src/PropSet.cxx @@ -2,14 +2,14 @@ /** @file PropSet.cxx ** A Java style properties file module. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. // Maintain a dictionary of properties #include #include -#include +//#include #include #include "Platform.h" @@ -30,6 +30,10 @@ static inline bool IsLetter(char ch) { return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')); } +inline bool IsASpace(unsigned int ch) { + return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); +} + int CompareCaseInsensitive(const char *a, const char *b) { while (*a && *b) { if (*a != *b) { @@ -98,13 +102,13 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) { lenVal = static_cast(strlen(val)); unsigned int hash = HashString(key, lenKey); for (Property *p = props[hash % hashRoots]; p; p = p->next) { - if ((hash == p->hash) && - ((strlen(p->key) == static_cast(lenKey)) && + if ((hash == p->hash) && + ((strlen(p->key) == static_cast(lenKey)) && (0 == strncmp(p->key, key, lenKey)))) { // Replace current value delete [](p->val); p->val = StringDup(val, lenVal); - return ; + return; } } // Not found @@ -119,7 +123,7 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) { } void PropSet::Set(const char *keyVal) { - while (isspace(*keyVal)) + while (IsASpace(*keyVal)) keyVal++; const char *endVal = keyVal; while (*endVal && (*endVal != '\n')) @@ -257,7 +261,7 @@ SString PropSet::GetWild(const char *keybase, const char *filename) { if (keyfile == NULL) keyfile = orgkeyfile; - for (; ; ) { + for (;;) { char *del = strchr(keyfile, ';'); if (del == NULL) del = keyfile + strlen(keyfile); @@ -328,9 +332,9 @@ void PropSet::Clear() { while (p) { Property *pNext = p->next; p->hash = 0; - delete p->key; + delete []p->key; p->key = 0; - delete p->val; + delete []p->val; p->val = 0; delete p; p = pNext; @@ -626,7 +630,7 @@ static unsigned int LengthWord(const char *word, char otherSeparator) { if (endWord > word) { endWord--; // Back from the '(', ':', or '\0' // Move backwards over any spaces - while ((endWord > word) && (isspace(*endWord))) { + while ((endWord > word) && (IsASpace(*endWord))) { endWord--; } } @@ -669,13 +673,13 @@ char *WordList::GetNearestWords( if (!cond) { // Find first match while ((pivot > start) && - (0 == CompareNCaseInsensitive(wordStart, + (0 == CompareNCaseInsensitive(wordStart, wordsNoCase[pivot-1], searchLen))) { --pivot; } // Grab each match while ((pivot <= end) && - (0 == CompareNCaseInsensitive(wordStart, + (0 == CompareNCaseInsensitive(wordStart, wordsNoCase[pivot], searchLen))) { wordlen = LengthWord(wordsNoCase[pivot], otherSeparator) + 1; wordsNear.append(wordsNoCase[pivot], wordlen, ' '); @@ -695,14 +699,14 @@ char *WordList::GetNearestWords( if (!cond) { // Find first match while ((pivot > start) && - (0 == strncmp(wordStart, - words[pivot-1], searchLen))) { + (0 == strncmp(wordStart, + words[pivot-1], searchLen))) { --pivot; } // Grab each match while ((pivot <= end) && - (0 == strncmp(wordStart, - words[pivot], searchLen))) { + (0 == strncmp(wordStart, + words[pivot], searchLen))) { wordlen = LengthWord(words[pivot], otherSeparator) + 1; wordsNear.append(words[pivot], wordlen, ' '); ++pivot; diff --git a/contrib/src/stc/scintilla/src/RESearch.cxx b/contrib/src/stc/scintilla/src/RESearch.cxx index f176bbf19e..ee7f3bfe71 100644 --- a/contrib/src/stc/scintilla/src/RESearch.cxx +++ b/contrib/src/stc/scintilla/src/RESearch.cxx @@ -10,11 +10,11 @@ * Dept. of Computer Science * York University * - * Original code available from http://www.cs.yorku.ca/~oz/ + * Original code available from http://www.cs.yorku.ca/~oz/ * Translation to C++ by Neil Hodgson neilh@scintilla.org * Removed all use of register. * Converted to modern function prototypes. - * Put all global/static variables into an object so this code can be + * Put all global/static variables into an object so this code can be * used from multiple threads etc. * * These routines are the PUBLIC DOMAIN equivalents of regex @@ -30,8 +30,11 @@ * Modification history: * * $Log$ - * Revision 1.5 2002/09/11 00:55:27 RD - * Update to Scintilla 1.48 + * Revision 1.5.2.1 2003/04/08 22:40:19 RD + * Updated wxSTC to Scintilla 1.51 + * + * Revision 1.7 2002/09/28 00:33:28 nyamatongwe + * Fixed problem with character ranges caused by expansion to 8 bits. * * Revision 1.6 2001/04/29 13:32:10 nyamatongwe * Addition of new target methods - versions of ReplaceTarget that take counted @@ -67,17 +70,17 @@ * * Revision 1.2 88/08/28 15:36:04 oz * Use a complement bitmap to represent NCL. - * This removes the need to have seperate - * code in the PMatch case block - it is + * This removes the need to have seperate + * code in the PMatch case block - it is * just CCL code now. - * + * * Use the actual CCL code in the CLO * section of PMatch. No need for a recursive * PMatch call. - * + * * Use a bitmap table to set char bits in an * 8-bit chunk. - * + * * Interfaces: * RESearch::Compile: compile a regular expression into a NFA. * @@ -107,7 +110,7 @@ * void re_fail(msg, op) * char *msg; * char op; - * + * * Regular Expressions: * * [1] char matches itself, unless it is a special @@ -117,20 +120,20 @@ * * [3] \ matches the character following it, except * when followed by a left or right round bracket, - * a digit 1 to 9 or a left or right angle bracket. + * a digit 1 to 9 or a left or right angle bracket. * (see [7], [8] and [9]) - * It is used as an escape character for all + * It is used as an escape character for all * other meta-characters, and itself. When used * in a set ([4]), it is treated as an ordinary * character. * * [4] [set] matches one of the characters in the set. * If the first character in the set is "^", - * it matches a character NOT in the set, i.e. - * complements the set. A shorthand S-E is - * used to specify a set of characters S upto - * E, inclusive. The special characters "]" and - * "-" have no special meaning if they appear + * it matches a character NOT in the set, i.e. + * complements the set. A shorthand S-E is + * used to specify a set of characters S upto + * E, inclusive. The special characters "]" and + * "-" have no special meaning if they appear * as the first chars in the set. * examples: match: * @@ -195,8 +198,8 @@ * Notes: * * This implementation uses a bit-set representation for character - * classes for speed and compactness. Each character is represented - * by one bit in a 128-bit block. Thus, CCL always takes a + * classes for speed and compactness. Each character is represented + * by one bit in a 128-bit block. Thus, CCL always takes a * constant 16 bytes in the internal nfa, and RESearch::Execute does a single * bit comparison to locate the character in the set. * @@ -206,7 +209,7 @@ * compile: CHR f CHR o CLO CHR o END CLO ANY END END * matches: fo foo fooo foobar fobar foxx ... * - * pattern: fo[ob]a[rz] + * pattern: fo[ob]a[rz] * compile: CHR f CHR o CCL bitset CHR a CCL bitset END * matches: fobar fooar fobaz fooaz * @@ -254,7 +257,7 @@ const char bitarr[] = {1,2,4,8,16,32,64,'\200'}; #define badpat(x) (*nfa = END, x) - + RESearch::RESearch() { Init(); } @@ -343,7 +346,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { int n; char mask; /* xor mask -CCL/NCL */ int c1, c2; - + if (!pat || !length) if (sta) return 0; @@ -383,7 +386,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; if (*++p == '^') { - mask = '\377'; + mask = '\377'; i++; p++; } else @@ -427,7 +430,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { for (n = 0; n < BITBLK; bittab[n++] = (char) 0) *mp++ = static_cast(mask ^ bittab[n]); - + break; case '*': /* match 0 or more.. */ @@ -555,7 +558,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { * RESearch::Execute: * execute nfa to find a match. * - * special cases: (nfa[0]) + * special cases: (nfa[0]) * BOL * Match only once, starting from the * beginning. @@ -580,7 +583,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { bol = lp; failure = 0; - + Clear(); switch(*ap) { @@ -621,7 +624,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { return 1; } -/* +/* * PMatch: internal routine for the hard part * * This code is partly snarfed from an early grep written by @@ -647,7 +650,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { * * At the end of a successful match, bopat[n] and eopat[n] * are set to the beginning and end of subpatterns matched - * by tagged expressions (n = 1 to 9). + * by tagged expressions (n = 1 to 9). * */ @@ -658,23 +661,23 @@ extern void re_fail(char *,char); * and EOW. the reason for not using ctype macros is that we can * let the user add into our own table. see RESearch::ModifyWord. This table * is not in the bitset form, since we may wish to extend it in the - * future for other character classifications. + * future for other character classifications. * * TRUE for 0-9 A-Z a-z _ */ static char chrtyp[MAXCHR] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; @@ -688,7 +691,7 @@ static char chrtyp[MAXCHR] = { #define ANYSKIP 2 /* [CLO] ANY END ... */ #define CHRSKIP 3 /* [CLO] CHR chr END ... */ -#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */ +#define CCLSKIP 34 /* [CLO] CCL 32bytes END ... */ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) { int op, c, n; @@ -796,10 +799,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) { * the compact bitset representation for the default table] */ -static char deftab[16] = { - 0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207', - '\376', '\377', '\377', 007 -}; +static char deftab[16] = { + 0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207', + '\376', '\377', '\377', 007 +}; void RESearch::ModifyWord(char *s) { int i; @@ -846,7 +849,7 @@ int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) { pin = c - '0'; break; } - + default: *dst++ = c; continue; diff --git a/contrib/src/stc/scintilla/src/RESearch.h b/contrib/src/stc/scintilla/src/RESearch.h index 28238bfb7c..4b3e1b5d49 100644 --- a/contrib/src/stc/scintilla/src/RESearch.h +++ b/contrib/src/stc/scintilla/src/RESearch.h @@ -13,12 +13,12 @@ * The following defines are not meant to be changeable. * They are for readability only. */ -#define MAXCHR 128 +#define MAXCHR 256 #define CHRBIT 8 #define BITBLK MAXCHR/CHRBIT class CharacterIndexer { -public: +public: virtual char CharAt(int index)=0; }; diff --git a/contrib/src/stc/scintilla/src/SVector.h b/contrib/src/stc/scintilla/src/SVector.h index c8edb513bc..9c3235d580 100644 --- a/contrib/src/stc/scintilla/src/SVector.h +++ b/contrib/src/stc/scintilla/src/SVector.h @@ -15,18 +15,18 @@ */ class SVector { enum { allocSize = 4000 }; - + int *v; ///< The vector unsigned int size; ///< Number of elements allocated unsigned int len; ///< Number of elements used in vector bool allocFailure; ///< A memory allocation call has failed - + /** Internally allocate more elements than the user wants * to avoid thrashing the memory allocator. */ void SizeTo(int newSize) { if (newSize < allocSize) newSize += allocSize; - else + else newSize = (newSize * 3) / 2; int* newv = new int[newSize]; if (!newv) { @@ -44,7 +44,7 @@ class SVector { delete []v; v = newv; } - + public: SVector() { allocFailure = false; diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.cxx b/contrib/src/stc/scintilla/src/ScintillaBase.cxx index ab6e9a19b4..a112a4af65 100644 --- a/contrib/src/stc/scintilla/src/ScintillaBase.cxx +++ b/contrib/src/stc/scintilla/src/ScintillaBase.cxx @@ -2,7 +2,7 @@ /** @file ScintillaBase.cxx ** An enhanced subclass of Editor with calltips, autocomplete and context menu. **/ -// Copyright 1998-2002 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -26,6 +26,7 @@ #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" +#include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" @@ -211,7 +212,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { return; } } - ac.Start(wMain, idAutoComplete, currentPos, lenEntered); + ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode()); PRectangle rcClient = GetClientRectangle(); Point pt = LocationFromPosition(currentPos - lenEntered); @@ -224,7 +225,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { pt = LocationFromPosition(currentPos); } PRectangle rcac; - rcac.left = pt.x - 5; + rcac.left = pt.x - ac.lb->CaretFromEdge(); if (pt.y >= rcClient.bottom - heightLB && // Wont fit below. pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above. rcac.top = pt.y - heightLB; @@ -237,19 +238,19 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { } rcac.right = rcac.left + widthLB; rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom); - ac.lb.SetPositionRelative(rcac, wMain); - ac.lb.SetFont(vs.styles[STYLE_DEFAULT].font); - ac.lb.SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth); - ac.lb.SetDoubleClickAction(AutoCompleteDoubleClick, this); + ac.lb->SetPositionRelative(rcac, wMain); + ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); + ac.lb->SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth); + ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this); ac.SetList(list); // Fiddle the position of the list so it is right next to the target and wide enough for all its strings - PRectangle rcList = ac.lb.GetDesiredRect(); + PRectangle rcList = ac.lb->GetDesiredRect(); int heightAlloced = rcList.bottom - rcList.top; widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); // Make an allowance for large strings in list - rcList.left = pt.x - 5; + rcList.left = pt.x - ac.lb->CaretFromEdge(); rcList.right = rcList.left + widthLB; if (((pt.y + vs.lineHeight) >= (rcClient.bottom - heightAlloced)) && // Wont fit below. ((pt.y + vs.lineHeight / 2) >= (rcClient.bottom + rcClient.top) / 2)) { // and there is more room above. @@ -258,7 +259,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { rcList.top = pt.y + vs.lineHeight; } rcList.bottom = rcList.top + heightAlloced; - ac.lb.SetPositionRelative(rcList, wMain); + ac.lb->SetPositionRelative(rcList, wMain); ac.Show(); if (lenEntered != 0) { AutoCompleteMoveToCurrentWord(); @@ -304,10 +305,10 @@ void ScintillaBase::AutoCompleteCharacterDeleted() { } void ScintillaBase::AutoCompleteCompleted() { - int item = ac.lb.GetSelection(); + int item = ac.lb->GetSelection(); char selected[1000]; if (item != -1) { - ac.lb.GetValue(item, selected, sizeof(selected)); + ac.lb->GetValue(item, selected, sizeof(selected)); } ac.Cancel(); @@ -509,6 +510,21 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara case SCI_AUTOCGETDROPRESTOFWORD: return ac.dropRestOfWord; + case SCI_REGISTERIMAGE: + ac.lb->RegisterImage(wParam, reinterpret_cast(lParam)); + break; + + case SCI_CLEARREGISTEREDIMAGES: + ac.lb->ClearRegisteredImages(); + break; + + case SCI_AUTOCSETTYPESEPARATOR: + ac.SetTypesep(static_cast(wParam)); + break; + + case SCI_AUTOCGETTYPESEPARATOR: + return ac.GetTypesep(); + case SCI_CALLTIPSHOW: { AutoCompleteCancel(); if (!ct.wCallTip.Created()) { diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.h b/contrib/src/stc/scintilla/src/ScintillaBase.h index e68aeb6084..9a9433dd78 100644 --- a/contrib/src/stc/scintilla/src/ScintillaBase.h +++ b/contrib/src/stc/scintilla/src/ScintillaBase.h @@ -43,7 +43,7 @@ protected: int lexLanguage; const LexerModule *lexCurrent; PropSet props; - enum {numWordLists=6}; + enum {numWordLists=9}; WordList *keyWordLists[numWordLists+1]; void SetLexer(uptr_t wParam); void SetLexerLanguage(const char *languageName); diff --git a/contrib/src/stc/scintilla/src/Style.cxx b/contrib/src/stc/scintilla/src/Style.cxx index 2ee09f57d2..5ac1d8469f 100644 --- a/contrib/src/stc/scintilla/src/Style.cxx +++ b/contrib/src/stc/scintilla/src/Style.cxx @@ -66,8 +66,8 @@ Style &Style::operator=(const Style &source) { void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_) { fore.desired = fore_; back.desired = back_; @@ -100,7 +100,7 @@ void Style::ClearTo(const Style &source) { source.eolFilled, source.underline, source.caseForce, - source.visible, + source.visible, source.changeable); } diff --git a/contrib/src/stc/scintilla/src/Style.h b/contrib/src/stc/scintilla/src/Style.h index 63259b1a93..06a5651c87 100644 --- a/contrib/src/stc/scintilla/src/Style.h +++ b/contrib/src/stc/scintilla/src/Style.h @@ -43,13 +43,13 @@ public: void Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_); void ClearTo(const Style &source); bool EquivalentFontTo(const Style *other) const; void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0); - bool IsProtected() { return !(changeable && visible);} ; + bool IsProtected() const { return !(changeable && visible);}; }; #endif diff --git a/contrib/src/stc/scintilla/src/StyleContext.cxx b/contrib/src/stc/scintilla/src/StyleContext.cxx index bdae28196f..64fc7a048e 100644 --- a/contrib/src/stc/scintilla/src/StyleContext.cxx +++ b/contrib/src/stc/scintilla/src/StyleContext.cxx @@ -29,7 +29,7 @@ static void getRange(unsigned int start, s[i] = '\0'; } -void StyleContext::GetCurrent(char *s, int len) { +void StyleContext::GetCurrent(char *s, unsigned int len) { getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len); } @@ -46,6 +46,6 @@ static void getRangeLowered(unsigned int start, s[i] = '\0'; } -void StyleContext::GetCurrentLowered(char *s, int len) { +void StyleContext::GetCurrentLowered(char *s, unsigned int len) { getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len); } diff --git a/contrib/src/stc/scintilla/src/StyleContext.h b/contrib/src/stc/scintilla/src/StyleContext.h index 4c9352916d..d099520d93 100644 --- a/contrib/src/stc/scintilla/src/StyleContext.h +++ b/contrib/src/stc/scintilla/src/StyleContext.h @@ -2,21 +2,35 @@ /** @file StyleContext.cxx ** Lexer infrastructure. **/ -// Copyright 1998-2001 by Neil Hodgson +// Copyright 1998-2002 by Neil Hodgson // This file is in the public domain. // All languages handled so far can treat all characters >= 0x80 as one class // which just continues the current token or starts an identifier if in default. -// DBCS treated specially as the second character can be < 0x80 and hence +// DBCS treated specially as the second character can be < 0x80 and hence // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 class StyleContext { Accessor &styler; - int endPos; + unsigned int endPos; StyleContext& operator=(const StyleContext&) { return *this; } + void GetNextChar(unsigned int pos) { + chNext = static_cast(styler.SafeGetCharAt(pos+1)); + if (styler.IsLeadByte(static_cast(chNext))) { + chNext = chNext << 8; + chNext |= static_cast(styler.SafeGetCharAt(pos+2)); + } + // End of line? + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) + // or on LF alone (Unix). Avoid triggering two times on Dos/Win. + atLineEnd = (ch == '\r' && chNext != '\n') || + (ch == '\n') || + (currentPos >= endPos); + } + public: - int currentPos; + unsigned int currentPos; bool atLineStart; bool atLineEnd; int state; @@ -24,32 +38,27 @@ public: int ch; int chNext; - StyleContext(unsigned int startPos, int length, - int initStyle, Accessor &styler_, char chMask=31) : + StyleContext(unsigned int startPos, unsigned int length, + int initStyle, Accessor &styler_, char chMask=31) : styler(styler_), endPos(startPos + length), - currentPos(startPos), + currentPos(startPos), atLineStart(true), atLineEnd(false), - state(initStyle), + state(initStyle), chPrev(0), - ch(0), + ch(0), chNext(0) { styler.StartAt(startPos, chMask); styler.StartSegment(startPos); - int pos = currentPos; + unsigned int pos = currentPos; ch = static_cast(styler.SafeGetCharAt(pos)); if (styler.IsLeadByte(static_cast(ch))) { pos++; ch = ch << 8; ch |= static_cast(styler.SafeGetCharAt(pos)); } - chNext = static_cast(styler.SafeGetCharAt(pos+1)); - if (styler.IsLeadByte(static_cast(chNext))) { - chNext = chNext << 8; - chNext |= static_cast(styler.SafeGetCharAt(pos+2)); - } - atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos); + GetNextChar(pos); } void Complete() { styler.ColourTo(currentPos - 1, state); @@ -60,21 +69,12 @@ public: void Forward() { if (currentPos < endPos) { atLineStart = atLineEnd; - // A lot of this is repeated from the constructor - TODO: merge code chPrev = ch; currentPos++; if (ch >= 0x100) currentPos++; ch = chNext; - chNext = static_cast(styler.SafeGetCharAt(currentPos+1)); - if (styler.IsLeadByte(static_cast(chNext))) { - chNext = chNext << 8; - chNext |= static_cast(styler.SafeGetCharAt(currentPos + 2)); - } - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) - // Avoid triggering two times on Dos/Win - // End of line - atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos); + GetNextChar(currentPos); } else { atLineStart = false; chPrev = ' '; @@ -83,6 +83,11 @@ public: atLineEnd = true; } } + void Forward(int nb) { + for (int i = 0; i < nb; i++) { + Forward(); + } + } void ChangeState(int state_) { state = state_; } @@ -136,8 +141,8 @@ public: return true; } // Non-inline - void GetCurrent(char *s, int len); - void GetCurrentLowered(char *s, int len); + void GetCurrent(char *s, unsigned int len); + void GetCurrentLowered(char *s, unsigned int len); }; inline bool IsASpace(unsigned int ch) { diff --git a/contrib/src/stc/scintilla/src/ViewStyle.cxx b/contrib/src/stc/scintilla/src/ViewStyle.cxx index 12e1406aa4..1e335ddfad 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.cxx +++ b/contrib/src/stc/scintilla/src/ViewStyle.cxx @@ -2,7 +2,7 @@ /** @file ViewStyle.cxx ** Store information on how the document is to be viewed. **/ -// Copyright 1998-2001 by Neil Hodgson +// Copyright 1998-2003 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include @@ -11,6 +11,7 @@ #include "Scintilla.h" #include "Indicator.h" +#include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" @@ -72,6 +73,12 @@ ViewStyle::ViewStyle(const ViewStyle &source) { selbackset = source.selbackset; selbackground.desired = source.selbackground.desired; selbackground2.desired = source.selbackground2.desired; + + foldmarginColourSet = source.foldmarginColourSet; + foldmarginColour.desired = source.foldmarginColour.desired; + foldmarginHighlightColourSet = source.foldmarginHighlightColourSet; + foldmarginHighlightColour.desired = source.foldmarginHighlightColour.desired; + whitespaceForegroundSet = source.whitespaceForegroundSet; whitespaceForeground.desired = source.whitespaceForeground.desired; whitespaceBackgroundSet = source.whitespaceBackgroundSet; @@ -124,6 +131,12 @@ void ViewStyle::Init() { selbackset = true; selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0); selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0); + + foldmarginColourSet = false; + foldmarginColour.desired = ColourDesired(0xff, 0, 0); + foldmarginHighlightColourSet = false; + foldmarginHighlightColour.desired = ColourDesired(0xc0, 0xc0, 0xc0); + whitespaceForegroundSet = false; whitespaceForeground.desired = ColourDesired(0, 0, 0); whitespaceBackgroundSet = false; @@ -138,6 +151,7 @@ void ViewStyle::Init() { edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0); edgeState = EDGE_NONE; caretWidth = 1; + someStylesProtected = false; leftMarginWidth = 1; rightMarginWidth = 1; @@ -148,9 +162,7 @@ void ViewStyle::Init() { ms[1].width = 16; ms[1].mask = ~SC_MASK_FOLDERS; ms[2].symbol = true; - ms[2].width = 14; // Nice width for arrows - ms[2].mask = SC_MASK_FOLDERS; - ms[2].width = 0; // Nice width for arrows + ms[2].width = 0; ms[2].mask = 0; fixedColumnWidth = leftMarginWidth; symbolMargin = false; @@ -178,12 +190,15 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(indicators[i].fore, want); } for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) { - pal.WantFind(markers[i].fore, want); - pal.WantFind(markers[i].back, want); + markers[i].RefreshColourPalette(pal, want); } pal.WantFind(selforeground, want); pal.WantFind(selbackground, want); pal.WantFind(selbackground2, want); + + pal.WantFind(foldmarginColour, want); + pal.WantFind(foldmarginHighlightColour, want); + pal.WantFind(whitespaceForeground, want); pal.WantFind(whitespaceBackground, want); pal.WantFind(selbar, want); @@ -199,6 +214,7 @@ void ViewStyle::Refresh(Surface &surface) { styles[STYLE_DEFAULT].Realise(surface, zoomLevel); maxAscent = styles[STYLE_DEFAULT].ascent; maxDescent = styles[STYLE_DEFAULT].descent; + someStylesProtected = false; for (unsigned int i=0;i<(sizeof(styles)/sizeof(styles[0]));i++) { if (i != STYLE_DEFAULT) { styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT]); @@ -207,6 +223,9 @@ void ViewStyle::Refresh(Surface &surface) { if (maxDescent < styles[i].descent) maxDescent = styles[i].descent; } + if (styles[i].IsProtected()) { + someStylesProtected = true; + } } lineHeight = maxAscent + maxDescent; @@ -225,7 +244,7 @@ void ViewStyle::Refresh(Surface &surface) { } void ViewStyle::ResetDefaultStyle() { - styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), + styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), ColourDesired(0xff,0xff,0xff), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, @@ -245,3 +264,7 @@ void ViewStyle::ClearStyles() { void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { styles[styleIndex].fontName = fontNames.Save(name); } + +bool ViewStyle::ProtectionActive() const { + return someStylesProtected; +} diff --git a/contrib/src/stc/scintilla/src/ViewStyle.h b/contrib/src/stc/scintilla/src/ViewStyle.h index 887170eaac..135a8b3409 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.h +++ b/contrib/src/stc/scintilla/src/ViewStyle.h @@ -59,6 +59,10 @@ public: ColourPair whitespaceBackground; ColourPair selbar; ColourPair selbarlight; + bool foldmarginColourSet; + ColourPair foldmarginColour; + bool foldmarginHighlightColourSet; + ColourPair foldmarginHighlightColour; /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin enum { margins=3 }; int leftMarginWidth; ///< Spacing margin on left of text @@ -78,7 +82,8 @@ public: ColourPair edgecolour; int edgeState; int caretWidth; - + bool someStylesProtected; + ViewStyle(); ViewStyle(const ViewStyle &source); ~ViewStyle(); @@ -88,6 +93,7 @@ public: void ResetDefaultStyle(); void ClearStyles(); void SetStyleFontName(int styleIndex, const char *name); + bool ProtectionActive() const; }; #endif diff --git a/contrib/src/stc/scintilla/src/WindowAccessor.cxx b/contrib/src/stc/scintilla/src/WindowAccessor.cxx index ce42534e7b..d70ddf5c34 100644 --- a/contrib/src/stc/scintilla/src/WindowAccessor.cxx +++ b/contrib/src/stc/scintilla/src/WindowAccessor.cxx @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include "Platform.h" @@ -24,7 +24,7 @@ bool WindowAccessor::InternalIsLeadByte(char ch) { if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the // same so none is considered a lead byte. - return false; + return false; else return Platform::IsDBCSLeadByte(codePage, ch); } @@ -71,10 +71,10 @@ int WindowAccessor::LevelAt(int line) { return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); } -int WindowAccessor::Length() { - if (lenDoc == -1) +int WindowAccessor::Length() { + if (lenDoc == -1) lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0); - return lenDoc; + return lenDoc; } int WindowAccessor::GetLineState(int line) { @@ -125,7 +125,7 @@ void WindowAccessor::Flush() { startPos = extremePosition; lenDoc = -1; if (validLen > 0) { - Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen, + Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen, styleBuf); validLen = 0; } @@ -134,12 +134,12 @@ void WindowAccessor::Flush() { int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { int end = Length(); int spaceFlags = 0; - - // Determines the indentation level of the current line and also checks for consistent + + // Determines the indentation level of the current line and also checks for consistent // indentation compared to the previous line. - // Indentation is judged consistent when the indentation whitespace of each line lines + // Indentation is judged consistent when the indentation whitespace of each line lines // the same or the indentation of one line is a prefix of the other. - + int pos = LineStart(line); char ch = (*this)[pos]; int indent = 0; @@ -166,7 +166,7 @@ int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsC } ch = (*this)[++pos]; } - + *flags = spaceFlags; indent += SC_FOLDLEVELBASE; // if completely empty line or the start of a comment... diff --git a/contrib/src/stc/scintilla/src/XPM.cxx b/contrib/src/stc/scintilla/src/XPM.cxx new file mode 100644 index 0000000000..c4e4f888ef --- /dev/null +++ b/contrib/src/stc/scintilla/src/XPM.cxx @@ -0,0 +1,297 @@ +// Scintilla source code edit control +/** @file XPM.cxx + ** Define a class that holds data in the X Pixmap (XPM) format, + **/ +// Copyright 1998-2003 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include + +#include "Platform.h" + +#include "XPM.h" + +static const char *NextField(const char *s) { + while (*s && *s != ' ') { + s++; + } + while (*s && *s == ' ') { + s++; + } + return s; +} + +// Data lines in XPM can be terminated either with NUL or " +static size_t MeasureLength(const char *s) { + size_t i = 0; + while (s[i] && (s[i] != '\"')) + i++; + return i; +} + +ColourAllocated XPM::ColourFromCode(int ch) { + return colourCodeTable[ch]->allocated; +#ifdef SLOW + for (int i=0;iFillRectangle(rc, ColourFromCode(code)); + } +} + +XPM::XPM(const char *textForm) : + data(0), codes(0), colours(0), lines(0) { + Init(textForm); +} + +XPM::XPM(const char * const *linesForm) : + data(0), codes(0), colours(0), lines(0) { + Init(linesForm); +} + +XPM::~XPM() { + Clear(); +} + +void XPM::Init(const char *textForm) { + Clear(); + // Test done is two parts to avoid possibility of overstepping the memory + // if memcmp implemented strangely. Must be 4 bytes at least at destination. + if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { + // Build the lines form out of the text form + const char **linesForm = LinesFormFromTextForm(textForm); + Init(linesForm); + delete []linesForm; + } else { + // It is really in line form + Init(reinterpret_cast(textForm)); + } +} + +void XPM::Init(const char * const *linesForm) { + Clear(); + height = 1; + width = 1; + nColours = 1; + data = NULL; + codeTransparent = ' '; + codes = NULL; + colours = NULL; + lines = NULL; + if (!linesForm) + return; + + const char *line0 = linesForm[0]; + width = atoi(line0); + line0 = NextField(line0); + height = atoi(line0); + line0 = NextField(line0); + nColours = atoi(line0); + codes = new char[nColours]; + colours = new ColourPair[nColours]; + + int strings = 1+height+nColours; + lines = new char *[strings]; + int allocation = 0; + for (int i=0; i(codes[c])] = &(colours[c]); + } +} + +void XPM::Clear() { + delete []data; + data = 0; + delete []codes; + codes = 0; + delete []colours; + colours = 0; + delete []lines; + lines = 0; +} + +void XPM::RefreshColourPalette(Palette &pal, bool want) { + if (!data || !codes || !colours || !lines) { + return; + } + for (int i=0;iGetId() == id) { + set[i]->Init(textForm); + return; + } + } + + // No present, so add to end + XPM *pxpm = new XPM(textForm); + if (pxpm) { + pxpm->SetId(id); + pxpm->CopyDesiredColours(); + if (len == maximum) { + int lenNew = len + 100; + XPM **setNew = new XPM *[lenNew]; + for (int i=0; iGetId() == id) { + return set[i]; + } + } + return 0; +} + +int XPMSet::GetHeight() { + if (height < 0) { + for (int i=0; iGetHeight()) { + height = set[i]->GetHeight(); + } + } + } + return (height > 0) ? height : 0; +} + +int XPMSet::GetWidth() { + if (width < 0) { + for (int i=0; iGetWidth()) { + width = set[i]->GetWidth(); + } + } + } + return (width > 0) ? width : 0; +} diff --git a/contrib/src/stc/scintilla/src/XPM.h b/contrib/src/stc/scintilla/src/XPM.h new file mode 100644 index 0000000000..948e557a92 --- /dev/null +++ b/contrib/src/stc/scintilla/src/XPM.h @@ -0,0 +1,67 @@ +// Scintilla source code edit control +/** @file XPM.h + ** Define a class that holds data in the X Pixmap (XPM) format, + **/ +// Copyright 1998-2003 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef XPM_H +#define XPM_H + +/** + * Hold a pixmap in XPM format. + */ +class XPM { + int id; // Assigned by container + int height; + int width; + int nColours; + char *data; + char codeTransparent; + char *codes; + ColourPair *colours; + ColourAllocated ColourFromCode(int ch); + void FillRun(Surface *surface, int code, int startX, int y, int x); + char **lines; + ColourPair *colourCodeTable[256]; +public: + XPM(const char *textForm); + XPM(const char * const *linesForm); + ~XPM(); + void Init(const char *textForm); + void Init(const char * const *linesForm); + void Clear(); + // Similar to same named method in ViewStyle: + void RefreshColourPalette(Palette &pal, bool want); + // No palette used, so just copy the desired colours to the allocated colours: + void CopyDesiredColours(); + // Decompose image into runs and use FillRectangle for each run: + void Draw(Surface *surface, PRectangle &rc); + char **InLinesForm() { return lines; } + void SetId(int id_) { id = id_; } + int GetId() { return id; } + int GetHeight() { return height; } + int GetWidth() { return width; } + static const char **LinesFormFromTextForm(const char *textForm); +}; + +/** + * A collection of pixmaps indexed by integer id. + */ +class XPMSet { + XPM **set; + int len; + int maximum; + int height; + int width; +public: + XPMSet(); + ~XPMSet(); + void Clear(); + void Add(int id, const char *textForm); + XPM *Get(int id); + int GetHeight(); + int GetWidth(); +}; + +#endif diff --git a/contrib/src/stc/stc.cpp b/contrib/src/stc/stc.cpp index 17cf6ee406..84c2558a02 100644 --- a/contrib/src/stc/stc.cpp +++ b/contrib/src/stc/stc.cpp @@ -21,6 +21,7 @@ #include "ScintillaWX.h" #include +#include //---------------------------------------------------------------------- @@ -201,7 +202,7 @@ int wxStyledTextCtrl::GetLength() { // Returns the character byte at the position. int wxStyledTextCtrl::GetCharAt(int pos) { - return (unsigned char)SendMsg(2007, pos, 0); + return (unsigned char)SendMsg(2007, pos, 0); } // Returns the position of the caret. @@ -216,7 +217,7 @@ int wxStyledTextCtrl::GetAnchor() { // Returns the style byte at the position. int wxStyledTextCtrl::GetStyleAt(int pos) { - return (unsigned char)SendMsg(2010, pos, 0); + return (unsigned char)SendMsg(2010, pos, 0); } // Redoes the next action on the undo history. @@ -243,21 +244,21 @@ void wxStyledTextCtrl::SetSavePoint() { // Retrieve a buffer of cells. wxMemoryBuffer wxStyledTextCtrl::GetStyledText(int startPos, int endPos) { - wxMemoryBuffer buf; - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - int len = endPos - startPos; - if (!len) return buf; - TextRange tr; - tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1); - tr.chrg.cpMin = startPos; - tr.chrg.cpMax = endPos; - len = SendMsg(2015, 0, (long)&tr); - buf.UngetWriteBuf(len); - return buf; + wxMemoryBuffer buf; + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + int len = endPos - startPos; + if (!len) return buf; + TextRange tr; + tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1); + tr.chrg.cpMin = startPos; + tr.chrg.cpMax = endPos; + len = SendMsg(2015, 0, (long)&tr); + buf.UngetWriteBuf(len); + return buf; } // Are there any redoable actions in the undo history? @@ -293,7 +294,7 @@ void wxStyledTextCtrl::SetViewWhiteSpace(int viewWS) { // Find the position from a point within the window. int wxStyledTextCtrl::PositionFromPoint(wxPoint pt) { - return SendMsg(2022, pt.x, pt.y); + return SendMsg(2022, pt.x, pt.y); } // Find the position from a point within the window but return @@ -321,20 +322,20 @@ void wxStyledTextCtrl::SetAnchor(int posAnchor) { // Retrieve the text of the line containing the caret. // Returns the index of the caret on the line. wxString wxStyledTextCtrl::GetCurLine(int* linePos) { - int len = LineLength(GetCurrentLine()); - if (!len) { - if (linePos) *linePos = 0; - return wxEmptyString; - } + int len = LineLength(GetCurrentLine()); + if (!len) { + if (linePos) *linePos = 0; + return wxEmptyString; + } - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); - int pos = SendMsg(2027, len+1, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - if (linePos) *linePos = pos; - return stc2wx(buf); + int pos = SendMsg(2027, len+1, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + if (linePos) *linePos = pos; + return stc2wx(buf); } // Retrieve the position of the last correctly styled character. @@ -399,20 +400,20 @@ void wxStyledTextCtrl::SetCodePage(int codePage) { wxASSERT_MSG(codePage != wxSTC_CP_UTF8, wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off.")); #endif - SendMsg(2037, codePage); + SendMsg(2037, codePage); } // Set the symbol used for a particular marker number, // and optionally the fore and background colours. void wxStyledTextCtrl::MarkerDefine(int markerNumber, int markerSymbol, - const wxColour& foreground, - const wxColour& background) { + const wxColour& foreground, + const wxColour& background) { - SendMsg(2040, markerNumber, markerSymbol); - if (foreground.Ok()) - MarkerSetForeground(markerNumber, foreground); - if (background.Ok()) - MarkerSetBackground(markerNumber, background); + SendMsg(2040, markerNumber, markerSymbol); + if (foreground.Ok()) + MarkerSetForeground(markerNumber, foreground); + if (background.Ok()) + MarkerSetBackground(markerNumber, background); } // Set the foreground colour used for a particular marker number. @@ -455,6 +456,20 @@ int wxStyledTextCtrl::MarkerPrevious(int lineStart, int markerMask) { return SendMsg(2048, lineStart, markerMask); } +// Define a marker from a bitmap +void wxStyledTextCtrl::MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp) { + // convert bmp to a xpm in a string + wxMemoryOutputStream strm; + wxImage(bmp).SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len+1] = 0; + SendMsg(2049, markerNumber, (long)buff); + delete [] buff; + +} + // Set a margin to be either numeric or symbolic. void wxStyledTextCtrl::SetMarginType(int margin, int marginType) { SendMsg(2240, margin, marginType); @@ -572,12 +587,12 @@ void wxStyledTextCtrl::SetCaretForeground(const wxColour& fore) { // When key+modifier combination km is pressed perform msg. void wxStyledTextCtrl::CmdKeyAssign(int key, int modifiers, int cmd) { - SendMsg(2070, MAKELONG(key, modifiers), cmd); + SendMsg(2070, MAKELONG(key, modifiers), cmd); } // When key+modifier combination km do nothing. void wxStyledTextCtrl::CmdKeyClear(int key, int modifiers) { - SendMsg(2071, MAKELONG(key, modifiers)); + SendMsg(2071, MAKELONG(key, modifiers)); } // Drop all key mappings. @@ -587,7 +602,7 @@ void wxStyledTextCtrl::CmdKeyClearAll() { // Set the styles for a segment of the document. void wxStyledTextCtrl::SetStyleBytes(int length, char* styleBytes) { - SendMsg(2073, length, (long)styleBytes); + SendMsg(2073, length, (long)styleBytes); } // Set a style to be visible or not. @@ -818,6 +833,36 @@ bool wxStyledTextCtrl::AutoCompGetDropRestOfWord() { return SendMsg(2271, 0, 0) != 0; } +// Register an image for use in autocompletion lists. +void wxStyledTextCtrl::RegisterImage(int type, const wxBitmap& bmp) { + // convert bmp to a xpm in a string + wxMemoryOutputStream strm; + wxImage(bmp).SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len+1] = 0; + SendMsg(2405, type, (long)buff); + delete [] buff; + +} + +// Clear all the registered images. +void wxStyledTextCtrl::ClearRegisteredImages() { + SendMsg(2408, 0, 0); +} + +// Retrieve the auto-completion list type-separator character. +int wxStyledTextCtrl::AutoCompGetTypeSeparator() { + return SendMsg(2285, 0, 0); +} + +// Change the type-separator character in the string setting up an auto-completion list. +// Default is '?' but can be changed if items contain '?'. +void wxStyledTextCtrl::AutoCompSetTypeSeparator(int separatorCharacter) { + SendMsg(2286, separatorCharacter, 0); +} + // Set the number of spaces used for one level of indentation. void wxStyledTextCtrl::SetIndent(int indentSize) { SendMsg(2122, indentSize, 0); @@ -958,64 +1003,64 @@ int wxStyledTextCtrl::GetPrintColourMode() { // Find some text in the document. int wxStyledTextCtrl::FindText(int minPos, int maxPos, - const wxString& text, - int flags) { - TextToFind ft; - ft.chrg.cpMin = minPos; - ft.chrg.cpMax = maxPos; - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - ft.lpstrText = (char*)(const char*)buf; + const wxString& text, + int flags) { + TextToFind ft; + ft.chrg.cpMin = minPos; + ft.chrg.cpMax = maxPos; + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + ft.lpstrText = (char*)(const char*)buf; - return SendMsg(2150, flags, (long)&ft); + return SendMsg(2150, flags, (long)&ft); } // On Windows, will draw the document into a display context such as a printer. int wxStyledTextCtrl::FormatRange(bool doDraw, - int startPos, - int endPos, - wxDC* draw, - wxDC* target, // Why does it use two? Can they be the same? - wxRect renderRect, - wxRect pageRect) { - RangeToFormat fr; + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect) { + RangeToFormat fr; - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - fr.hdc = draw; - fr.hdcTarget = target; - fr.rc.top = renderRect.GetTop(); - fr.rc.left = renderRect.GetLeft(); - fr.rc.right = renderRect.GetRight(); - fr.rc.bottom = renderRect.GetBottom(); - fr.rcPage.top = pageRect.GetTop(); - fr.rcPage.left = pageRect.GetLeft(); - fr.rcPage.right = pageRect.GetRight(); - fr.rcPage.bottom = pageRect.GetBottom(); - fr.chrg.cpMin = startPos; - fr.chrg.cpMax = endPos; + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + fr.hdc = draw; + fr.hdcTarget = target; + fr.rc.top = renderRect.GetTop(); + fr.rc.left = renderRect.GetLeft(); + fr.rc.right = renderRect.GetRight(); + fr.rc.bottom = renderRect.GetBottom(); + fr.rcPage.top = pageRect.GetTop(); + fr.rcPage.left = pageRect.GetLeft(); + fr.rcPage.right = pageRect.GetRight(); + fr.rcPage.bottom = pageRect.GetBottom(); + fr.chrg.cpMin = startPos; + fr.chrg.cpMax = endPos; - return SendMsg(2151, doDraw, (long)&fr); + return SendMsg(2151, doDraw, (long)&fr); } -// Retrieve the line at the top of the display. +// Retrieve the display line at the top of the display. int wxStyledTextCtrl::GetFirstVisibleLine() { return SendMsg(2152, 0, 0); } // Retrieve the contents of a line. wxString wxStyledTextCtrl::GetLine(int line) { - int len = LineLength(line); - if (!len) return wxEmptyString; + int len = LineLength(line); + if (!len) return wxEmptyString; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(2153, line, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf); + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(2153, line, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf); } // Returns the number of lines in the document. There is always at least one. @@ -1055,40 +1100,40 @@ void wxStyledTextCtrl::SetSelection(int start, int end) { // Retrieve the selected text. wxString wxStyledTextCtrl::GetSelectedText() { - int start; - int end; + int start; + int end; - GetSelection(&start, &end); - int len = end - start; - if (!len) return wxEmptyString; + GetSelection(&start, &end); + int len = end - start; + if (!len) return wxEmptyString; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(2161, 0, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf); + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(2161, 0, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf); } // Retrieve a range of text. wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) { - if (endPos < startPos) { - int temp = startPos; - startPos = endPos; - endPos = temp; - } - int len = endPos - startPos; - if (!len) return wxEmptyString; - wxMemoryBuffer mbuf(len+1); - char* buf = (char*)mbuf.GetWriteBuf(len); - TextRange tr; - tr.lpstrText = buf; - tr.chrg.cpMin = startPos; - tr.chrg.cpMax = endPos; - SendMsg(2162, 0, (long)&tr); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf); + if (endPos < startPos) { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + int len = endPos - startPos; + if (!len) return wxEmptyString; + wxMemoryBuffer mbuf(len+1); + char* buf = (char*)mbuf.GetWriteBuf(len); + TextRange tr; + tr.lpstrText = buf; + tr.chrg.cpMin = startPos; + tr.chrg.cpMax = endPos; + SendMsg(2162, 0, (long)&tr); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf); } // Draw the selection in normal style or with selection highlighted. @@ -1173,13 +1218,13 @@ void wxStyledTextCtrl::SetText(const wxString& text) { // Retrieve all the text in the document. wxString wxStyledTextCtrl::GetText() { - int len = GetTextLength(); - wxMemoryBuffer mbuf(len+1); // leave room for the null... - char* buf = (char*)mbuf.GetWriteBuf(len+1); - SendMsg(2182, len+1, (long)buf); - mbuf.UngetWriteBuf(len); - mbuf.AppendByte(0); - return stc2wx(buf); + int len = GetTextLength(); + wxMemoryBuffer mbuf(len+1); // leave room for the null... + char* buf = (char*)mbuf.GetWriteBuf(len+1); + SendMsg(2182, len+1, (long)buf); + mbuf.UngetWriteBuf(len); + mbuf.AppendByte(0); + return stc2wx(buf); } // Retrieve the number of characters in the document. @@ -1233,9 +1278,9 @@ int wxStyledTextCtrl::GetTargetEnd() { // Text is counted so it can contain nulls. // Returns the length of the replacement text. - int wxStyledTextCtrl::ReplaceTarget(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(2194, strlen(buf), (long)(const char*)buf); + int wxStyledTextCtrl::ReplaceTarget(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(2194, strlen(buf), (long)(const char*)buf); } // Replace the target text with the argument text after \d processing. @@ -1245,18 +1290,18 @@ int wxStyledTextCtrl::GetTargetEnd() { // Returns the length of the replacement text including any change // caused by processing the \d patterns. - int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(2195, strlen(buf), (long)(const char*)buf); + int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(2195, strlen(buf), (long)(const char*)buf); } // Search for a counted string in the target and set the target to the found // range. Text is counted so it can contain nulls. // Returns length of range or -1 for failure in which case target is not moved. - int wxStyledTextCtrl::SearchInTarget(const wxString& text) { - wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); - return SendMsg(2197, strlen(buf), (long)(const char*)buf); + int wxStyledTextCtrl::SearchInTarget(const wxString& text) { + wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text); + return SendMsg(2197, strlen(buf), (long)(const char*)buf); } // Set the search flags used by SearchInTarget. @@ -1366,7 +1411,7 @@ void wxStyledTextCtrl::EnsureVisible(int line) { SendMsg(2232, line, 0); } -// Set some debugging options for folding. +// Set some style options for folding. void wxStyledTextCtrl::SetFoldFlags(int flags) { SendMsg(2233, flags, 0); } @@ -1472,6 +1517,62 @@ int wxStyledTextCtrl::TextHeight(int line) { return SendMsg(2279, line, 0); } +// Show or hide the vertical scroll bar. +void wxStyledTextCtrl::SetUseVerticalScrollBar(bool show) { + SendMsg(2280, show, 0); +} + +// Is the vertical scroll bar visible? +bool wxStyledTextCtrl::GetUseVerticalScrollBar() { + return SendMsg(2281, 0, 0) != 0; +} + +// Append a string to the end of the document without changing the selection. +void wxStyledTextCtrl::AppendText(int length, const wxString& text) { + SendMsg(2282, length, (long)(const char*)wx2stc(text)); +} + +// Is drawing done in two phases with backgrounds drawn before foregrounds? +bool wxStyledTextCtrl::GetTwoPhaseDraw() { + return SendMsg(2283, 0, 0) != 0; +} + +// In twoPhaseDraw mode, drawing is performed in two phases, first the background +// and then the foreground. This avoids chopping off characters that overlap the next run. +void wxStyledTextCtrl::SetTwoPhaseDraw(bool twoPhase) { + SendMsg(2284, twoPhase, 0); +} + +// Make the target range start and end be the same as the selection range start and end. +void wxStyledTextCtrl::TargetFromSelection() { + SendMsg(2287, 0, 0); +} + +// Join the lines in the target. +// This is an experimental feature and may be changed or removed. +void wxStyledTextCtrl::LinesJoin() { + SendMsg(2288, 0, 0); +} + +// Split the lines in the target into lines that are less wide than pixelWidth +// where possible. +void wxStyledTextCtrl::LinesSplit(int pixelWidth) { + SendMsg(2289, pixelWidth, 0); +} + +// Set the colours used as a chequerboard pattern in the fold margin +void wxStyledTextCtrl::SetFoldMarginColour(bool useSetting, const wxColour& back) { + SendMsg(2290, useSetting, wxColourAsLong(back)); +} +void wxStyledTextCtrl::SetFoldMarginHiColour(bool useSetting, const wxColour& fore) { + SendMsg(2291, useSetting, wxColourAsLong(fore)); +} + +// Duplicate the current line. +void wxStyledTextCtrl::LineDuplicate() { + SendMsg(2404, 0, 0); +} + // Move caret to first position on display line. void wxStyledTextCtrl::HomeDisplay() { SendMsg(2345, 0, 0); @@ -1531,12 +1632,12 @@ void wxStyledTextCtrl::SetViewEOL(bool visible) { // Retrieve a pointer to the document object. void* wxStyledTextCtrl::GetDocPointer() { - return (void*)SendMsg(2357); + return (void*)SendMsg(2357); } // Change the document object used. void wxStyledTextCtrl::SetDocPointer(void* docPointer) { - SendMsg(2358, 0, (long)docPointer); + SendMsg(2358, 0, (long)docPointer); } // Set which document modification events are sent to the container. @@ -1624,17 +1725,17 @@ int wxStyledTextCtrl::GetZoom() { // Create a new document object. // Starts with reference count of 1 and not selected into editor. void* wxStyledTextCtrl::CreateDocument() { - return (void*)SendMsg(2375); + return (void*)SendMsg(2375); } // Extend life of document. void wxStyledTextCtrl::AddRefDocument(void* docPointer) { - SendMsg(2376, 0, (long)docPointer); + SendMsg(2376, 0, (long)docPointer); } // Release a reference to the document, deleting document if it fades to black. void wxStyledTextCtrl::ReleaseDocument(void* docPointer) { - SendMsg(2377, 0, (long)docPointer); + SendMsg(2377, 0, (long)docPointer); } // Get which document modification events are sent to the container. @@ -1739,6 +1840,11 @@ int wxStyledTextCtrl::GetXOffset() { return SendMsg(2398, 0, 0); } +// Set the last x chosen value to be the caret x position +void wxStyledTextCtrl::ChooseCaretX() { + SendMsg(2399, 0, 0); +} + // Set the way the caret is kept visible when going sideway. // The exclusion zone is given in pixels. void wxStyledTextCtrl::SetXCaretPolicy(int caretPolicy, int caretSlop) { @@ -1751,6 +1857,16 @@ void wxStyledTextCtrl::SetYCaretPolicy(int caretPolicy, int caretSlop) { SendMsg(2403, caretPolicy, caretSlop); } +// Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE). +void wxStyledTextCtrl::SetPrintWrapMode(int mode) { + SendMsg(2406, mode, 0); +} + +// Is printing line wrapped. +int wxStyledTextCtrl::GetPrintWrapMode() { + return SendMsg(2407, 0, 0); +} + // Start notifying the container of all key presses and commands. void wxStyledTextCtrl::StartRecord() { SendMsg(3001, 0, 0); @@ -1928,9 +2044,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) { void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) { wxPaintDC dc(this); - wxRegion region = GetUpdateRegion(); - - m_swx->DoPaint(&dc, region.GetBox()); + m_swx->DoPaint(&dc, GetUpdateRegion().GetBox()); } void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) { diff --git a/contrib/src/stc/stc.cpp.in b/contrib/src/stc/stc.cpp.in index 0ab9afdc5e..c7895e1f41 100644 --- a/contrib/src/stc/stc.cpp.in +++ b/contrib/src/stc/stc.cpp.in @@ -21,6 +21,7 @@ #include "ScintillaWX.h" #include +#include //---------------------------------------------------------------------- @@ -306,9 +307,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) { void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) { wxPaintDC dc(this); - wxRegion region = GetUpdateRegion(); - - m_swx->DoPaint(&dc, region.GetBox()); + m_swx->DoPaint(&dc, GetUpdateRegion().GetBox()); } void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) { diff --git a/src/stc/StcVC.dsp b/src/stc/StcVC.dsp index a6c2c4ce95..77d23fed0e 100644 --- a/src/stc/StcVC.dsp +++ b/src/stc/StcVC.dsp @@ -282,6 +282,10 @@ SOURCE=.\scintilla\src\LexAda.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexAsm.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexAVE.cxx # End Source File # Begin Source File @@ -306,10 +310,18 @@ SOURCE=.\scintilla\src\LexCrontab.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexCSS.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexEiffel.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexFortran.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexHTML.cxx # End Source File # Begin Source File @@ -446,6 +458,10 @@ SOURCE=.\scintilla\src\WindowAccessor.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\XPM.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\include\WindowAccessor.h # End Source File # End Group diff --git a/src/stc/makefile.b32 b/src/stc/makefile.b32 index 5a9843f863..8e9dfdccff 100644 --- a/src/stc/makefile.b32 +++ b/src/stc/makefile.b32 @@ -34,13 +34,16 @@ OBJECTS = \ KeyWords.obj \ LexAVE.obj \ LexAda.obj \ + LexAsm.obj \ LexBaan.obj \ LexBullant.obj \ LexMatlab.obj \ LexCPP.obj \ LexConf.obj \ LexCrontab.obj \ + LexCSS.obj \ LexEiffel.obj \ + LexFortran.obj \ LexHTML.obj \ LexLisp.obj \ LexLua.obj \ @@ -60,17 +63,19 @@ OBJECTS = \ UniConversion.obj \ ViewStyle.obj \ WindowAccessor.obj \ + XPM.cxx \ \ PlatWX.obj \ ScintillaWX.obj \ stc.obj \ + STCCFG = stc.cfg STCCPPFLAGS=$(DLL_FLAGS) $(EXTRACPPFLAGS) @$(STCCFG) default: $(STCCFG) $(LIBTARGET) -cleancfg: +cleancfg: del $(STCCFG) {$(S)}.cxx.obj: diff --git a/src/stc/makefile.g95 b/src/stc/makefile.g95 index 4ae99521f5..2d8581973c 100644 --- a/src/stc/makefile.g95 +++ b/src/stc/makefile.g95 @@ -22,13 +22,16 @@ OBJECTS = \ $(S)/KeyWords.$(OBJSUFF) \ $(S)/LexAVE.$(OBJSUFF) \ $(S)/LexAda.$(OBJSUFF) \ + $(S)/LexAsm.$(OBJSUFF) \ $(S)/LexBaan.$(OBJSUFF) \ $(S)/LexBullant.$(OBJSUFF) \ $(S)/LexMatlab.$(OBJSUFF) \ $(S)/LexCPP.$(OBJSUFF) \ $(S)/LexConf.$(OBJSUFF) \ $(S)/LexCrontab.$(OBJSUFF) \ + $(S)/LexCSS.$(OBJSUFF) \ $(S)/LexEiffel.$(OBJSUFF) \ + $(S)/LexFortran.$(OBJSUFF) \ $(S)/LexHTML.$(OBJSUFF) \ $(S)/LexLisp.$(OBJSUFF) \ $(S)/LexLua.$(OBJSUFF) \ @@ -48,11 +51,13 @@ OBJECTS = \ $(S)/UniConversion.$(OBJSUFF) \ $(S)/ViewStyle.$(OBJSUFF) \ $(S)/WindowAccessor.$(OBJSUFF) \ + $(S)/XPM.$(OBJSUFF) \ \ PlatWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \ stc.$(OBJSUFF) + LIBTARGET = $(WXDIR)/lib/libstc.a include $(WXDIR)/src/makelib.g95 \ No newline at end of file diff --git a/src/stc/makefile.vc b/src/stc/makefile.vc index 9a3fdc08e7..caad6ade36 100644 --- a/src/stc/makefile.vc +++ b/src/stc/makefile.vc @@ -27,13 +27,16 @@ OBJECTS = \ $(D)\KeyWords.obj \ $(D)\LexAVE.obj \ $(D)\LexAda.obj \ + $(D)\LexAsm.obj \ $(D)\LexBaan.obj \ $(D)\LexBullant.obj \ $(D)\LexMatlab.obj \ $(D)\LexCPP.obj \ $(D)\LexConf.obj \ $(D)\LexCrontab.obj \ + $(D)\LexCSS.obj \ $(D)\LexEiffel.obj \ + $(D)\LexFortran.obj \ $(D)\LexHTML.obj \ $(D)\LexLisp.obj \ $(D)\LexLua.obj \ @@ -53,6 +56,7 @@ OBJECTS = \ $(D)\UniConversion.obj \ $(D)\ViewStyle.obj \ $(D)\WindowAccessor.obj \ + $(D)\XPM.obj \ \ $(D)\PlatWX.obj \ $(D)\ScintillaWX.obj \ diff --git a/src/stc/makefile.wat b/src/stc/makefile.wat index 3a42017756..ac516a0f86 100644 --- a/src/stc/makefile.wat +++ b/src/stc/makefile.wat @@ -31,13 +31,16 @@ OBJECTS = & KeyWords.obj & LexAVE.obj & LexAda.obj & + LexAsm.obj & LexBaan.obj & LexBullant.obj & LexMatlab.obj & LexCPP.obj & LexConf.obj & LexCrontab.obj & + LexCSS.obj & LexEiffel.obj & + LexFortran.obj & LexHTML.obj & LexLisp.obj & LexLua.obj & @@ -57,9 +60,10 @@ OBJECTS = & UniConversion.obj & ViewStyle.obj & WindowAccessor.obj & + XPM.obj & PlatWX.obj & ScintillaWX.obj & - stc.obj + stc.obj all: $(STCLIB) .SYMBOLIC @@ -67,17 +71,17 @@ $(STCLIB): $(OBJECTS) *wlib /b /c /n /P=256 $(STCLIB) $(OBJECTS) clean: .SYMBOLIC - -erase *.obj - -erase *.bak - -erase *.err - -erase *.pch - -erase $(STCLIB) + -erase *.obj + -erase *.bak + -erase *.err + -erase *.pch + -erase $(STCLIB) -erase *.lbc .EXTENSIONS: .cxx .cxx: $(S) .cxx.obj: - $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS) + $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS)