From 9e730a78765d0e70ca5b77512569c94585070fe2 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Sat, 19 Apr 2003 20:00:02 +0000 Subject: [PATCH] Updated Scintilla to 1.52 (on the trunk this time too) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20296 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/include/wx/stc/stc.h | 244 ++- contrib/samples/stc/stctest.cpp | 158 +- contrib/src/stc/Makefile.in | 8 +- contrib/src/stc/PlatWX.cpp | 578 ++++--- contrib/src/stc/ScintillaWX.cpp | 144 +- contrib/src/stc/ScintillaWX.h | 6 + contrib/src/stc/StcVC.dsp | 20 + contrib/src/stc/gen_iface.py | 659 ++++---- contrib/src/stc/makefile.b32 | 8 +- contrib/src/stc/makefile.g95 | 6 + contrib/src/stc/makefile.vc | 5 + contrib/src/stc/makefile.wat | 19 +- contrib/src/stc/scintilla/License.txt | 20 + contrib/src/stc/scintilla/README.txt | 3 +- contrib/src/stc/scintilla/include/Accessor.h | 4 +- contrib/src/stc/scintilla/include/KeyWords.h | 4 +- contrib/src/stc/scintilla/include/Platform.h | 103 +- contrib/src/stc/scintilla/include/PropSet.h | 6 +- contrib/src/stc/scintilla/include/SString.h | 8 +- contrib/src/stc/scintilla/include/SciLexer.h | 84 +- contrib/src/stc/scintilla/include/Scintilla.h | 56 +- .../src/stc/scintilla/include/Scintilla.iface | 221 ++- .../stc/scintilla/include/ScintillaWidget.h | 3 +- .../stc/scintilla/include/WindowAccessor.h | 8 +- .../src/stc/scintilla/src/AutoComplete.cxx | 69 +- contrib/src/stc/scintilla/src/AutoComplete.h | 12 +- contrib/src/stc/scintilla/src/CallTip.cxx | 178 ++- contrib/src/stc/scintilla/src/CallTip.h | 29 +- contrib/src/stc/scintilla/src/CellBuffer.cxx | 1 + contrib/src/stc/scintilla/src/CellBuffer.h | 2 +- contrib/src/stc/scintilla/src/Document.cxx | 298 ++-- contrib/src/stc/scintilla/src/Document.h | 20 +- .../stc/scintilla/src/DocumentAccessor.cxx | 2 +- .../src/stc/scintilla/src/DocumentAccessor.h | 8 +- contrib/src/stc/scintilla/src/Editor.cxx | 1383 ++++++++++++----- contrib/src/stc/scintilla/src/Editor.h | 108 +- contrib/src/stc/scintilla/src/KeyMap.cxx | 11 +- contrib/src/stc/scintilla/src/KeyWords.cxx | 16 +- contrib/src/stc/scintilla/src/LexAVE.cxx | 316 ++-- contrib/src/stc/scintilla/src/LexAda.cxx | 650 ++++++-- contrib/src/stc/scintilla/src/LexAsm.cxx | 142 ++ contrib/src/stc/scintilla/src/LexBullant.cxx | 20 +- contrib/src/stc/scintilla/src/LexCPP.cxx | 317 +++- contrib/src/stc/scintilla/src/LexCSS.cxx | 260 ++++ contrib/src/stc/scintilla/src/LexConf.cxx | 8 +- contrib/src/stc/scintilla/src/LexCrontab.cxx | 11 +- contrib/src/stc/scintilla/src/LexEiffel.cxx | 23 +- contrib/src/stc/scintilla/src/LexFortran.cxx | 310 ++++ contrib/src/stc/scintilla/src/LexHTML.cxx | 135 +- contrib/src/stc/scintilla/src/LexLisp.cxx | 15 +- contrib/src/stc/scintilla/src/LexLua.cxx | 77 +- contrib/src/stc/scintilla/src/LexMatlab.cxx | 9 +- contrib/src/stc/scintilla/src/LexOthers.cxx | 178 ++- contrib/src/stc/scintilla/src/LexPOV.cxx | 222 +++ contrib/src/stc/scintilla/src/LexPascal.cxx | 16 +- contrib/src/stc/scintilla/src/LexPerl.cxx | 59 +- contrib/src/stc/scintilla/src/LexPython.cxx | 70 +- contrib/src/stc/scintilla/src/LexRuby.cxx | 11 +- contrib/src/stc/scintilla/src/LexSQL.cxx | 7 +- contrib/src/stc/scintilla/src/LexVB.cxx | 21 +- contrib/src/stc/scintilla/src/LineMarker.cxx | 83 +- contrib/src/stc/scintilla/src/LineMarker.h | 26 +- contrib/src/stc/scintilla/src/PropSet.cxx | 44 +- contrib/src/stc/scintilla/src/RESearch.cxx | 177 ++- contrib/src/stc/scintilla/src/RESearch.h | 6 +- contrib/src/stc/scintilla/src/SVector.h | 8 +- .../src/stc/scintilla/src/ScintillaBase.cxx | 108 +- contrib/src/stc/scintilla/src/ScintillaBase.h | 4 +- contrib/src/stc/scintilla/src/Style.cxx | 19 +- contrib/src/stc/scintilla/src/Style.h | 9 +- .../src/stc/scintilla/src/StyleContext.cxx | 4 +- contrib/src/stc/scintilla/src/StyleContext.h | 61 +- contrib/src/stc/scintilla/src/ViewStyle.cxx | 53 +- contrib/src/stc/scintilla/src/ViewStyle.h | 13 +- .../src/stc/scintilla/src/WindowAccessor.cxx | 22 +- contrib/src/stc/scintilla/src/XPM.cxx | 297 ++++ contrib/src/stc/scintilla/src/XPM.h | 67 + contrib/src/stc/stc.cpp | 443 ++++-- contrib/src/stc/stc.cpp.in | 23 +- contrib/src/stc/stc.h.in | 16 +- include/wx/stc/stc.h | 244 ++- samples/stc/stctest.cpp | 158 +- src/stc/Makefile.in | 8 +- src/stc/PlatWX.cpp | 578 ++++--- src/stc/ScintillaWX.cpp | 144 +- src/stc/ScintillaWX.h | 6 + src/stc/StcVC.dsp | 20 + src/stc/gen_iface.py | 659 ++++---- src/stc/makefile.b32 | 8 +- src/stc/makefile.g95 | 6 + src/stc/makefile.vc | 5 + src/stc/makefile.wat | 19 +- src/stc/scintilla/License.txt | 20 + src/stc/scintilla/README.txt | 3 +- src/stc/scintilla/include/Accessor.h | 4 +- src/stc/scintilla/include/KeyWords.h | 4 +- src/stc/scintilla/include/Platform.h | 103 +- src/stc/scintilla/include/PropSet.h | 6 +- src/stc/scintilla/include/SString.h | 8 +- src/stc/scintilla/include/SciLexer.h | 84 +- src/stc/scintilla/include/Scintilla.h | 56 +- src/stc/scintilla/include/Scintilla.iface | 221 ++- src/stc/scintilla/include/ScintillaWidget.h | 3 +- src/stc/scintilla/include/WindowAccessor.h | 8 +- src/stc/scintilla/src/AutoComplete.cxx | 69 +- src/stc/scintilla/src/AutoComplete.h | 12 +- src/stc/scintilla/src/CallTip.cxx | 178 ++- src/stc/scintilla/src/CallTip.h | 29 +- src/stc/scintilla/src/CellBuffer.cxx | 1 + src/stc/scintilla/src/CellBuffer.h | 2 +- src/stc/scintilla/src/Document.cxx | 298 ++-- src/stc/scintilla/src/Document.h | 20 +- src/stc/scintilla/src/DocumentAccessor.cxx | 2 +- src/stc/scintilla/src/DocumentAccessor.h | 8 +- src/stc/scintilla/src/Editor.cxx | 1383 ++++++++++++----- src/stc/scintilla/src/Editor.h | 108 +- src/stc/scintilla/src/KeyMap.cxx | 11 +- src/stc/scintilla/src/KeyWords.cxx | 16 +- src/stc/scintilla/src/LexAVE.cxx | 316 ++-- src/stc/scintilla/src/LexAda.cxx | 650 ++++++-- src/stc/scintilla/src/LexAsm.cxx | 142 ++ src/stc/scintilla/src/LexBullant.cxx | 20 +- src/stc/scintilla/src/LexCPP.cxx | 317 +++- src/stc/scintilla/src/LexCSS.cxx | 260 ++++ src/stc/scintilla/src/LexConf.cxx | 8 +- src/stc/scintilla/src/LexCrontab.cxx | 11 +- src/stc/scintilla/src/LexEiffel.cxx | 23 +- src/stc/scintilla/src/LexFortran.cxx | 310 ++++ src/stc/scintilla/src/LexHTML.cxx | 135 +- src/stc/scintilla/src/LexLisp.cxx | 15 +- src/stc/scintilla/src/LexLua.cxx | 77 +- src/stc/scintilla/src/LexMatlab.cxx | 9 +- src/stc/scintilla/src/LexOthers.cxx | 178 ++- src/stc/scintilla/src/LexPOV.cxx | 222 +++ src/stc/scintilla/src/LexPascal.cxx | 16 +- src/stc/scintilla/src/LexPerl.cxx | 59 +- src/stc/scintilla/src/LexPython.cxx | 70 +- src/stc/scintilla/src/LexRuby.cxx | 11 +- src/stc/scintilla/src/LexSQL.cxx | 7 +- src/stc/scintilla/src/LexVB.cxx | 21 +- src/stc/scintilla/src/LineMarker.cxx | 83 +- src/stc/scintilla/src/LineMarker.h | 26 +- src/stc/scintilla/src/PropSet.cxx | 44 +- src/stc/scintilla/src/RESearch.cxx | 177 ++- src/stc/scintilla/src/RESearch.h | 6 +- src/stc/scintilla/src/SVector.h | 8 +- src/stc/scintilla/src/ScintillaBase.cxx | 108 +- src/stc/scintilla/src/ScintillaBase.h | 4 +- src/stc/scintilla/src/Style.cxx | 19 +- src/stc/scintilla/src/Style.h | 9 +- src/stc/scintilla/src/StyleContext.cxx | 4 +- src/stc/scintilla/src/StyleContext.h | 61 +- src/stc/scintilla/src/ViewStyle.cxx | 53 +- src/stc/scintilla/src/ViewStyle.h | 13 +- src/stc/scintilla/src/WindowAccessor.cxx | 22 +- src/stc/scintilla/src/XPM.cxx | 297 ++++ src/stc/scintilla/src/XPM.h | 67 + src/stc/stc.cpp | 443 ++++-- src/stc/stc.cpp.in | 23 +- src/stc/stc.h.in | 16 +- 160 files changed, 13340 insertions(+), 4404 deletions(-) create mode 100644 contrib/src/stc/scintilla/License.txt create mode 100644 contrib/src/stc/scintilla/src/LexAsm.cxx create mode 100644 contrib/src/stc/scintilla/src/LexCSS.cxx create mode 100644 contrib/src/stc/scintilla/src/LexFortran.cxx create mode 100644 contrib/src/stc/scintilla/src/LexPOV.cxx create mode 100644 contrib/src/stc/scintilla/src/XPM.cxx create mode 100644 contrib/src/stc/scintilla/src/XPM.h create mode 100644 src/stc/scintilla/License.txt create mode 100644 src/stc/scintilla/src/LexAsm.cxx create mode 100644 src/stc/scintilla/src/LexCSS.cxx create mode 100644 src/stc/scintilla/src/LexFortran.cxx create mode 100644 src/stc/scintilla/src/LexPOV.cxx create mode 100644 src/stc/scintilla/src/XPM.cxx create mode 100644 src/stc/scintilla/src/XPM.h diff --git a/contrib/include/wx/stc/stc.h b/contrib/include/wx/stc/stc.h index 096949085a..41e36f3e8b 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. @@ -185,10 +189,21 @@ #define wxSTC_FIND_MATCHCASE 4 #define wxSTC_FIND_WORDSTART 0x00100000 #define wxSTC_FIND_REGEXP 0x00200000 +#define wxSTC_FIND_POSIX 0x00400000 #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 +215,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 +323,12 @@ #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 +#define wxSTC_LEX_POV 39 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a // value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -576,6 +597,9 @@ #define wxSTC_ERR_DIFF_ADDITION 11 #define wxSTC_ERR_DIFF_DELETION 12 #define wxSTC_ERR_DIFF_MESSAGE 13 +#define wxSTC_ERR_PHP 14 +#define wxSTC_ERR_ELF 15 +#define wxSTC_ERR_IFC 16 // Lexical states for SCLEX_BATCH #define wxSTC_BAT_DEFAULT 0 @@ -622,24 +646,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 +751,66 @@ #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 +#define wxSTC_CSS_DOUBLESTRING 13 +#define wxSTC_CSS_SINGLESTRING 14 + +// Lexical states for SCLEX_POV +#define wxSTC_POV_DEFAULT 0 +#define wxSTC_POV_COMMENT 1 +#define wxSTC_POV_COMMENTLINE 2 +#define wxSTC_POV_COMMENTDOC 3 +#define wxSTC_POV_NUMBER 4 +#define wxSTC_POV_WORD 5 +#define wxSTC_POV_STRING 6 +#define wxSTC_POV_OPERATOR 7 +#define wxSTC_POV_IDENTIFIER 8 +#define wxSTC_POV_BRACE 9 +#define wxSTC_POV_WORD2 10 + //----------------------------------------- // Commands that can be bound to keystrokes @@ -867,6 +958,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 @@ -897,6 +991,18 @@ // caret position. #define wxSTC_CMD_LINEENDDISPLAYEXTEND 2348 +// These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? +// except they behave differently when word-wrap is enabled: +// They go first to the start / end of the display line, like (Home|LineEnd)Display +// The difference is that, the cursor is already at the point, it goes on to the start +// or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend. +#define wxSTC_CMD_HOMEWRAP 2349 +#define wxSTC_CMD_HOMEWRAPEXTEND 2450 +#define wxSTC_CMD_LINEENDWRAP 2451 +#define wxSTC_CMD_LINEENDWRAPEXTEND 2452 +#define wxSTC_CMD_VCHOMEWRAP 2453 +#define wxSTC_CMD_VCHOMEWRAPEXTEND 2454 + // Move to the previous change in capitalisation. #define wxSTC_CMD_WORDPARTLEFT 2390 @@ -917,6 +1023,12 @@ // Delete forwards from the current position to the end of the line. #define wxSTC_CMD_DELLINERIGHT 2396 +// Move caret between paragraphs (delimited by empty lines) +#define wxSTC_CMD_PARADOWN 2413 +#define wxSTC_CMD_PARADOWNEXTEND 2414 +#define wxSTC_CMD_PARAUP 2415 +#define wxSTC_CMD_PARAUPEXTEND 2416 + // END of generated section //---------------------------------------------------------------------- @@ -1091,8 +1203,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 +1230,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); @@ -1178,6 +1293,9 @@ public: // Set the character set of the font in a style. void StyleSetCharacterSet(int style, int characterSet); + // Set a style to be a hotspot or not. + void StyleSetHotSpot(int style, bool hotspot); + // Set the foreground colour of the selection and whether to use this setting. void SetSelForeground(bool useSetting, const wxColour& fore); @@ -1339,6 +1457,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 +1558,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); - - // Retrieve the line at the top of the display. + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect); + + // Retrieve the display line at the top of the display. int GetFirstVisibleLine(); // Retrieve the contents of a line. @@ -1589,6 +1720,12 @@ public: // Set the background colour for the call tip. void CallTipSetBackground(const wxColour& back); + // Set the foreground colour for the call tip. + void CallTipSetForeground(const wxColour& fore); + + // Set the foreground colour for the highlighted part of the call tip. + void CallTipSetForegroundHighlight(const wxColour& fore); + // Find the display line of a document line taking hidden lines into account. int VisibleFromDocLine(int line); @@ -1630,7 +1767,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 +1833,39 @@ 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. + 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 +2030,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 +2041,21 @@ 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(); + + // Set a fore colour for active hotspots. + void SetHotspotActiveForeground(bool useSetting, const wxColour& fore); + + // Set a back colour for active hotspots. + void SetHotspotActiveBackground(bool useSetting, const wxColour& back); + + // Enable / Disable underlining active hotspots. + void SetHotspotActiveUnderline(bool underline); + // Start notifying the container of all key presses and commands. void StartRecord(); @@ -2005,11 +2193,11 @@ private: void NotifyChange(); void NotifyParent(SCNotification* scn); - -private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxStyledTextCtrl) +protected: + ScintillaWX* m_swx; wxStopWatch m_stopWatch; wxScrollBar* m_vScrollBar; @@ -2128,6 +2316,8 @@ private: #endif }; + + #ifndef SWIG BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650) @@ -2153,6 +2343,9 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER, 1670) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP, 1671) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM, 1672) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK, 1673) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK, 1674) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK, 1675) END_DECLARE_EVENT_TYPES() #else enum { @@ -2179,6 +2372,9 @@ END_DECLARE_EVENT_TYPES() wxEVT_STC_DRAG_OVER, wxEVT_STC_DO_DROP, wxEVT_STC_ZOOM, + wxEVT_STC_HOTSPOT_CLICK, + wxEVT_STC_HOTSPOT_DCLICK, + wxEVT_STC_CALLTIP_CLICK }; #endif @@ -2210,6 +2406,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&); #define EVT_STC_DRAG_OVER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_DO_DROP(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_ZOOM(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), + #endif //---------------------------------------------------------------------- diff --git a/contrib/samples/stc/stctest.cpp b/contrib/samples/stc/stctest.cpp index 578044d546..538d00ef98 100644 --- a/contrib/samples/stc/stctest.cpp +++ b/contrib/samples/stc/stctest.cpp @@ -40,7 +40,26 @@ public: }; //---------------------------------------------------------------------- +// Make an editor class +class MySTC : public wxStyledTextCtrl +{ +public: + MySTC(wxWindow *parent, wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0); + + void OnKeyPressed(wxKeyEvent& evt); + +private: + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(MySTC, wxStyledTextCtrl) + EVT_KEY_DOWN(MySTC::OnKeyPressed) +END_EVENT_TABLE() + +//---------------------------------------------------------------------- // Define a new frame type: this is going to be our main frame class MyFrame : public wxFrame { @@ -51,7 +70,7 @@ public: void OnAbout(wxCommandEvent& event); private: - wxStyledTextCtrl* ed; + MySTC* ed; DECLARE_EVENT_TABLE() }; @@ -79,7 +98,7 @@ IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { MyFrame *frame = new MyFrame(_T("Testing wxStyledTextCtrl"), - wxPoint(5, 5), wxSize(400, 600)); + wxPoint(5, 5), wxSize(600, 600)); frame->Show(TRUE); return TRUE; @@ -123,32 +142,71 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) //---------------------------------------- // Setup the editor - ed = new wxStyledTextCtrl(this, ID_ED); + ed = new MySTC(this, ID_ED); +} + + +// event handlers + +void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) +{ + // TRUE is to force the frame to close + Close(TRUE); +} + +void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ + wxString msg; + msg.Printf( _T("Testing wxStyledTextCtrl...\n")); + wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this); +} + + +//---------------------------------------------------------------------- + +wxChar* keywords = +_T("asm auto bool break case catch char class const \ +const_cast continue default delete do double \ +dynamic_cast else enum explicit export extern \ +false float for friend goto if inline int long \ +mutable namespace new operator private protected \ +public register reinterpret_cast return short signed \ +sizeof static static_cast struct switch template this \ +throw true try typedef typeid typename union unsigned \ +using virtual void volatile wchar_t while"); + + + +MySTC::MySTC(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style) + : wxStyledTextCtrl(parent, id, pos, size, style) +{ // Default font wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL); - ed->StyleSetFont(wxSTC_STYLE_DEFAULT, font); - ed->StyleClearAll(); - - ed->StyleSetForeground(0, wxColour(0x80, 0x80, 0x80)); - ed->StyleSetForeground(1, wxColour(0x00, 0x7f, 0x00)); - //ed->StyleSetForeground(2, wxColour(0x00, 0x7f, 0x00)); - ed->StyleSetForeground(3, wxColour(0x7f, 0x7f, 0x7f)); - ed->StyleSetForeground(4, wxColour(0x00, 0x7f, 0x7f)); - ed->StyleSetForeground(5, wxColour(0x00, 0x00, 0x7f)); - ed->StyleSetForeground(6, wxColour(0x7f, 0x00, 0x7f)); - ed->StyleSetForeground(7, wxColour(0x7f, 0x00, 0x7f)); - ed->StyleSetForeground(8, wxColour(0x00, 0x7f, 0x7f)); - ed->StyleSetForeground(9, wxColour(0x7f, 0x7f, 0x7f)); - ed->StyleSetForeground(10, wxColour(0x00, 0x00, 0x00)); - ed->StyleSetForeground(11, wxColour(0x00, 0x00, 0x00)); - ed->StyleSetBold(5, TRUE); - ed->StyleSetBold(10, TRUE); + StyleSetFont(wxSTC_STYLE_DEFAULT, font); + StyleClearAll(); + + StyleSetForeground(0, wxColour(0x80, 0x80, 0x80)); + StyleSetForeground(1, wxColour(0x00, 0x7f, 0x00)); + //StyleSetForeground(2, wxColour(0x00, 0x7f, 0x00)); + StyleSetForeground(3, wxColour(0x7f, 0x7f, 0x7f)); + StyleSetForeground(4, wxColour(0x00, 0x7f, 0x7f)); + StyleSetForeground(5, wxColour(0x00, 0x00, 0x7f)); + StyleSetForeground(6, wxColour(0x7f, 0x00, 0x7f)); + StyleSetForeground(7, wxColour(0x7f, 0x00, 0x7f)); + StyleSetForeground(8, wxColour(0x00, 0x7f, 0x7f)); + StyleSetForeground(9, wxColour(0x7f, 0x7f, 0x7f)); + StyleSetForeground(10, wxColour(0x00, 0x00, 0x00)); + StyleSetForeground(11, wxColour(0x00, 0x00, 0x00)); + StyleSetBold(5, TRUE); + StyleSetBold(10, TRUE); #ifdef __WXMSW__ - ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9")); + StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9")); #else - ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9")); + StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9")); #endif // give it some text to play with @@ -161,36 +219,36 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) st = wxString::FromAscii(buf); delete[] buf; - ed->InsertText(0, st); - ed->EmptyUndoBuffer(); + InsertText(0, st); + EmptyUndoBuffer(); - ed->SetLexer(wxSTC_LEX_CPP); - ed->SetKeyWords(0, -_T("asm auto bool break case catch char class const \ -const_cast continue default delete do double \ -dynamic_cast else enum explicit export extern \ -false float for friend goto if inline int long \ -mutable namespace new operator private protected \ -public register reinterpret_cast return short signed \ -sizeof static static_cast struct switch template this \ -throw true try typedef typeid typename union unsigned \ -using virtual void volatile wchar_t while")); - -} - - -// event handlers - -void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) -{ - // TRUE is to force the frame to close - Close(TRUE); + SetLexer(wxSTC_LEX_CPP); + SetKeyWords(0, keywords); } -void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +void MySTC::OnKeyPressed(wxKeyEvent& evt) { - wxString msg; - msg.Printf( _T("Testing wxStyledTextCtrl...\n")); - - wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this); + if (CallTipActive()) + CallTipCancel(); + + int key = evt.GetKeyCode(); + if ( key == WXK_SPACE && evt.ControlDown()) { + int pos = GetCurrentPos(); + + if (evt.ShiftDown()) { + // show how to do CallTips + CallTipSetBackground(wxColour(_T("YELLOW"))); + CallTipShow(pos, _T("lots of of text: blah, blah, blah\n\n" + "show some suff, maybe parameters..\n\n" + "fubar(param1, param2)")); + } + else { + // show how to do AutoComplete + AutoCompSetIgnoreCase(false); + AutoCompShow(0, keywords); // reuse the keyword list here + // normally you would build a string of completion texts... + } + } + else + evt.Skip(); } diff --git a/contrib/src/stc/Makefile.in b/contrib/src/stc/Makefile.in index 042da17f87..9df25a3db2 100644 --- a/contrib/src/stc/Makefile.in +++ b/contrib/src/stc/Makefile.in @@ -34,18 +34,22 @@ 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 \ LexOthers.o \ + LexPOV.o \ LexPascal.o \ LexPerl.o \ LexPython.o \ @@ -61,6 +65,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 fbf1faf2a3..80f8f795ce 100644 --- a/contrib/src/stc/PlatWX.cpp +++ b/contrib/src/stc/PlatWX.cpp @@ -8,7 +8,10 @@ #include #include - +#include +#include +#include +#include #include "Platform.h" #include "PlatWX.h" @@ -189,9 +192,6 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b false, stc2wx(faceName), encoding); -#ifdef __WXMAC__ - ((wxFont*)id)->SetNoAntiAliasing( true ) ; -#endif } @@ -216,42 +216,44 @@ public: SurfaceImpl(); ~SurfaceImpl(); - void Init(); - void Init(SurfaceID sid); - 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); - - 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_); - - int SetPalette(Palette *pal, bool inBackGround); - void SetClip(PRectangle rc); - void FlushCachedState(); - - void SetUnicodeMode(bool unicodeMode_); + virtual void Init(WindowID wid); + virtual void Init(SurfaceID sid, WindowID wid); + virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid); + + 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); + + 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_); + + virtual int SetPalette(Palette *pal, bool inBackGround); + virtual void SetClip(PRectangle rc); + virtual void FlushCachedState(); + + virtual void SetUnicodeMode(bool unicodeMode_); + virtual void SetDBCSMode(int codePage); void BrushColour(ColourAllocated back); void SetFont(Font &font_); @@ -268,25 +270,7 @@ 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() { +void SurfaceImpl::Init(WindowID wid) { #if 0 Release(); hdc = new wxMemoryDC(); @@ -295,16 +279,16 @@ void SurfaceImpl::Init() { // On Mac and GTK the DC is not really valid until it has a bitmap // selected into it. So instead of just creating the DC with no bitmap, // go ahead and give it one. - InitPixMap(1,1,NULL); + InitPixMap(1,1,NULL,wid); #endif } -void SurfaceImpl::Init(SurfaceID hdc_) { +void SurfaceImpl::Init(SurfaceID hdc_, WindowID) { Release(); hdc = (wxDC*)hdc_; } -void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) { +void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID) { Release(); hdc = new wxMemoryDC(); hdcOwned = true; @@ -314,6 +298,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)); } @@ -401,7 +405,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... @@ -414,28 +418,36 @@ 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) { + +void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase, + const char *s, int len, + ColourAllocated fore) { + SetFont(font); - int w; - int h; + hdc->SetTextForeground(wxColourFromCA(fore)); + hdc->SetBackgroundMode(wxTRANSPARENT); - hdc->GetTextExtent(stc2wx(s, len), &w, &h); - return w; + // 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); } void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) { + wxString str = stc2wx(s, len); SetFont(font); +#ifndef __WXMAC__ // Calculate the position of each character based on the widths of // the previous characters int* tpos = new int[len]; @@ -447,9 +459,26 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio totalWidth += w; tpos[i] = totalWidth; } +#else + // 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 necessarily + // (and probably not) the same as the whole string width. + int* tpos = new int[len]; + size_t i; + for (i=0; iGetTextExtent(str.Left(i+1), &w, &h); + tpos[i] = w; + } +#endif + #if wxUSE_UNICODE // Map the widths for UCS-2 characters back to the UTF-8 input string + // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2 + // so figure it out and fix it! i = 0; size_t ui = 0; while (i < len) { @@ -475,6 +504,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; @@ -545,6 +584,11 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { #endif } +void SurfaceImpl::SetDBCSMode(int codePage) { + // dbcsMode = codePage == SC_CP_DBCS; +} + + Surface *Surface::Allocate() { return new SurfaceImpl; } @@ -559,8 +603,10 @@ Window::~Window() { } void Window::Destroy() { - if (id) + if (id) { + Show(FALSE); GETWIN(id)->Destroy(); + } id = 0; } @@ -569,6 +615,7 @@ bool Window::HasFocus() { } PRectangle Window::GetPosition() { + if (! id) return PRectangle(); wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize()); return PRectangleFromwxRect(rc); } @@ -583,6 +630,7 @@ void Window::SetPositionRelative(PRectangle rc, Window) { } PRectangle Window::GetClientPosition() { + if (! id) return PRectangle(); wxSize sz = GETWIN(id)->GetClientSize(); return PRectangle(0, 0, sz.x, sz.y); } @@ -631,6 +679,8 @@ void Window::SetCursor(Cursor curs) { case cursorReverseArrow: cursorId = wxCURSOR_RIGHT_ARROW; break; + case cursorHand: + cursorId = wxCURSOR_HAND; default: cursorId = wxCURSOR_ARROW; break; @@ -653,199 +703,347 @@ void Window::SetTitle(const char *s) { // Helper classes for ListBox -#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)); - Hide(); - } + 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(); } - wxListBox* GetLB() { return this; } - private: DECLARE_EVENT_TABLE() }; - -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox) - EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus) +BEGIN_EVENT_TABLE(wxSTCListBox, wxListView) + EVT_SET_FOCUS( wxSTCListBox::OnFocus) END_EVENT_TABLE() -#else - -class wxSTCListBox : public wxListBox { +// A window to place the wxSTCListBox upon +class wxSTCListBoxWin : public wxWindow { +private: + wxListView* lv; + CallBackAction doubleClickAction; + void* doubleClickActionData; 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); + wxSTCListBoxWin(wxWindow* parent, wxWindowID id) : + wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxNO_BORDER ) + { + + SetBackgroundColour(*wxBLACK); + lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize, + wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER); + lv->SetCursor(wxCursor(wxCURSOR_ARROW)); + lv->InsertColumn(0, wxEmptyString); + lv->InsertColumn(1, wxEmptyString); + Hide(); } -private: - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox) - EVT_KEY_DOWN(wxSTCListBox::OnKeyDown) - EVT_CHAR(wxSTCListBox::OnKeyDown) -END_EVENT_TABLE() - + int IconWidth() { + wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL); + if (il != NULL) { + int w, h; + il->GetSize(0, w, h); + return w; + } + return 0; + } -#undef wxSTC_USE_POPUP -#define wxSTC_USE_POPUP 0 // wxPopupWindow just doesn't work well in this case... + void SetDoubleClickAction(CallBackAction action, void *data) { + doubleClickAction = action; + doubleClickActionData = data; + } -// 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 OnFocus(wxFocusEvent& event) { + GetParent()->SetFocus(); + event.Skip(); + } void OnSize(wxSizeEvent& event) { - lb->SetSize(GetSize()); + // resize the child, leaving a 1 pixel border + wxSize sz = GetClientSize(); + lv->SetSize(1, 1, sz.x-2, sz.y-2); + // reset the column widths + lv->SetColumnWidth(0, IconWidth()+4); + lv->SetColumnWidth(1, sz.x - 2 - 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 + + wxListView* GetLB() { return lv; } private: - wxSTCListBox* lb; DECLARE_EVENT_TABLE() }; -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase) - EVT_SIZE(wxSTCListBoxWin::OnSize) + +BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow) + EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus) + EVT_SIZE ( wxSTCListBoxWin::OnSize) + EVT_LIST_ITEM_ACTIVATED(-1, wxSTCListBoxWin::OnActivate) END_EVENT_TABLE() -#endif -inline wxListBox* GETLB(WindowID win) { - return (((wxSTCListBoxWin*)win)->GetLB()); + + +inline wxSTCListBoxWin* GETLBW(WindowID win) { + return ((wxSTCListBoxWin*)win); +} + +inline wxListView* GETLB(WindowID win) { + return GETLBW(win)->GetLB(); } //---------------------------------------------------------------------- -ListBox::ListBox() { +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) +{ } -ListBox::~ListBox() { +ListBoxImpl::~ListBoxImpl() { + if (imgList) { + delete imgList; + imgList = NULL; + } + if (imgTypeMap) { + delete imgTypeMap; + imgTypeMap = NULL; + } } -void ListBox::Create(Window &parent, int ctrlID) { + +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 ListBox::SetVisibleRows(int rows) { + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + + +void ListBoxImpl::SetVisibleRows(int rows) { desiredVisibleRows = rows; } -PRectangle ListBox::GetDesiredRect() { - wxSize sz = GETLB(id)->GetBestSize(); + +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 + + GETLBW(id)->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; + + // Try to make the size an exact multiple of some number of lines + int lines = maxh / rect.GetHeight(); + maxh = (lines + 1) * rect.GetHeight() + 2; + } + else + maxh = 100; + 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; + rc.right = maxw; + rc.bottom = maxh; return rc; } -void ListBox::SetAverageCharWidth(int width) { - aveCharWidth = width; -} -void ListBox::SetFont(Font &font) { - GETLB(id)->SetFont(*((wxFont*)font.GetID())); +int ListBoxImpl::CaretFromEdge() { + return 4 + GETLBW(id)->IconWidth(); } -void ListBox::Clear() { - GETLB(id)->Clear(); + +void ListBoxImpl::Clear() { + GETLB(id)->DeleteAllItems(); } -void ListBox::Append(char *s) { - GETLB(id)->Append(stc2wx(s)); + +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 ListBox::Length() { - return GETLB(id)->GetCount(); + +int ListBoxImpl::Length() { + return GETLB(id)->GetItemCount(); } -void ListBox::Select(int n) { + +void ListBoxImpl::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 + GETLB(id)->Focus(n); + GETLB(id)->Select(n, select); } -int ListBox::GetSelection() { - return GETLB(id)->GetSelection(); + +int ListBoxImpl::GetSelection() { + return GETLB(id)->GetFirstSelected(); } -int ListBox::Find(const char *prefix) { + +int ListBoxImpl::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); + +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 ListBox::Sort() { +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() { + 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) { + GETLBW(id)->SetDoubleClickAction(action, data); +} + + + +ListBox::ListBox() { +} + +ListBox::~ListBox() { +} + +ListBox *ListBox::Allocate() { + return new ListBoxImpl(); } //---------------------------------------------------------------------- @@ -890,13 +1088,16 @@ const char *Platform::DefaultFont() { } int Platform::DefaultFontSize() { - return 8; + return wxNORMAL_FONT->GetPointSize(); } unsigned int Platform::DoubleClickTime() { return 500; // **** ::GetDoubleClickTime(); } +bool Platform::MouseButtonBounce() { + return FALSE; +} void Platform::DebugDisplay(const char *s) { wxLogDebug(stc2wx(s)); } @@ -998,6 +1199,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 12ad21dafe..9aeda729c7 100644 --- a/contrib/src/stc/ScintillaWX.cpp +++ b/contrib/src/stc/ScintillaWX.cpp @@ -67,26 +67,28 @@ 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 { public: - wxSTCCallTip(wxWindow* parent, CallTip* ct) - : wxSTCCallTipBase(parent, param2) + wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx) + : wxSTCCallTipBase(parent, param2), + m_ct(ct), m_swx(swx) { - m_ct = ct; } ~wxSTCCallTip() { - if (HasCapture()) ReleaseMouse(); } + bool AcceptsFocus() const { return FALSE; } + void OnPaint(wxPaintEvent& evt) { wxPaintDC dc(this); Surface* surfaceWindow = Surface::Allocate(); - surfaceWindow->Init(&dc); + surfaceWindow->Init(&dc, m_ct->wDraw.GetID()); m_ct->PaintCT(surfaceWindow); + surfaceWindow->Release(); delete surfaceWindow; } @@ -95,6 +97,13 @@ public: event.Skip(); } + void OnLeftDown(wxMouseEvent& event) { + wxPoint pt = event.GetPosition(); + Point p(pt.x, pt.y); + m_ct->MouseClick(p); + m_swx->CallTipClick(); + } + #if wxUSE_POPUPWIN && wxSTC_USE_POPUP virtual void DoSetSize(int x, int y, int width, int height, @@ -105,32 +114,18 @@ public: GetParent()->ClientToScreen(NULL, &y); wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags); } - - virtual bool Show( bool show = TRUE ) { - bool retval = wxSTCCallTipBase::Show(show); - if (show) - CaptureMouse(); - else - if (HasCapture()) ReleaseMouse(); - return retval; - } - - void OnLeftDown(wxMouseEvent& ) { - Show(FALSE); - } #endif private: - CallTip* m_ct; + CallTip* m_ct; + ScintillaWX* m_swx; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase) EVT_PAINT(wxSTCCallTip::OnPaint) EVT_SET_FOCUS(wxSTCCallTip::OnFocus) -#if wxUSE_POPUPWIN && wxSTC_USE_POPUP EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown) -#endif END_EVENT_TABLE() @@ -139,6 +134,7 @@ END_EVENT_TABLE() ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) { + capturedMouse = false; wMain = win; stc = win; wheelRotation = 0; @@ -220,15 +216,16 @@ void ScintillaWX::SetTicking(bool on) { void ScintillaWX::SetMouseCapture(bool on) { - if (on && !stc->HasCapture()) + if (on && !capturedMouse) stc->CaptureMouse(); - else if (!on && stc->HasCapture()) + else if (!on && capturedMouse && stc->HasCapture()) stc->ReleaseMouse(); + capturedMouse = on; } bool ScintillaWX::HaveMouseCapture() { - return stc->HasCapture(); + return capturedMouse; } @@ -387,8 +384,10 @@ bool ScintillaWX::CanPaste() { } void ScintillaWX::CreateCallTipWindow(PRectangle) { - ct.wCallTip = new wxSTCCallTip(stc, &ct); - ct.wDraw = ct.wCallTip; + if (! ct.wCallTip.Created() ) { + ct.wCallTip = new wxSTCCallTip(stc, &ct, this); + ct.wDraw = ct.wCallTip; + } } @@ -436,37 +435,37 @@ 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. + Point pt = LocationFromPosition(wParam); + char* defn = reinterpret_cast(lParam); AutoCompleteCancel(); - if (!ct.wCallTip.Created()) { - Point pt = LocationFromPosition(wParam); - pt.y += vs.lineHeight; - PRectangle rc = ct.CallTipStart(currentPos, pt, - reinterpret_cast(lParam), - vs.styles[STYLE_DEFAULT].fontName, - vs.styles[STYLE_DEFAULT].sizeZoomed, - IsUnicodeMode()); - // If the call-tip window would be out of the client - // space, adjust so it displays above the text. - PRectangle rcClient = GetClientRectangle(); - if (rc.bottom > rcClient.bottom) { + pt.y += vs.lineHeight; + PRectangle rc = ct.CallTipStart(currentPos, pt, + defn, + vs.styles[STYLE_DEFAULT].fontName, + vs.styles[STYLE_DEFAULT].sizeZoomed, + IsUnicodeMode(), + wMain); + // If the call-tip window would be out of the client + // space, adjust so it displays above the text. + PRectangle rcClient = GetClientRectangle(); + if (rc.bottom > rcClient.bottom) { #ifdef __WXGTK__ - int offset = int(vs.lineHeight * 1.25) + rc.Height(); + int offset = int(vs.lineHeight * 1.25) + rc.Height(); #else - int offset = vs.lineHeight + rc.Height(); + int offset = vs.lineHeight + rc.Height(); #endif - rc.top -= offset; - rc.bottom -= offset; - } - // Now display the window. - CreateCallTipWindow(rc); - ct.wCallTip.SetPositionRelative(rc, wMain); - ct.wCallTip.Show(); + rc.top -= offset; + rc.bottom -= offset; } - } + // Now display the window. + CreateCallTipWindow(rc); + ct.wCallTip.SetPositionRelative(rc, wMain); + ct.wCallTip.Show(); break; + } default: return ScintillaBase::WndProc(iMessage, wParam, lParam); @@ -483,22 +482,22 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) { paintState = painting; Surface* surfaceWindow = Surface::Allocate(); - surfaceWindow->Init(dc); - PRectangle rcPaint = PRectangleFromwxRect(rect); + surfaceWindow->Init(dc, wMain.GetID()); + 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 } @@ -775,16 +774,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); - Paint(surfaceWindow, rcPaint); - delete surfaceWindow; + surfaceWindow->Init(&dc, wMain.GetID()); -// stc->Refresh(FALSE); + dc.BeginDrawing(); + ClipChildren(dc, rcPaint); + Paint(surfaceWindow, rcPaint); + dc.EndDrawing(); + delete surfaceWindow; paintState = notPainting; } @@ -798,6 +799,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 04b2ac0333..4c6b35c6e3 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,8 +150,10 @@ public: bool GetHideSelection() { return hideSelection; } void DoScrollToLine(int line); void DoScrollToColumn(int column); + void ClipChildren(wxDC& dc, PRectangle rect); private: + bool capturedMouse; wxStyledTextCtrl* stc; #if wxUSE_DRAG_AND_DROP @@ -158,6 +161,9 @@ private: wxDragResult dragResult; #endif int wheelRotation; + + + friend class wxSTCCallTip; }; //---------------------------------------------------------------------- diff --git a/contrib/src/stc/StcVC.dsp b/contrib/src/stc/StcVC.dsp index a6c2c4ce95..7007794571 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 @@ -330,6 +342,10 @@ SOURCE=.\scintilla\src\LexOthers.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexPOV.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexPascal.cxx # End Source File # Begin Source File @@ -446,6 +462,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..885357f398 100644 --- a/contrib/src/stc/gen_iface.py +++ b/contrib/src/stc/gen_iface.py @@ -42,6 +42,9 @@ cmdValues = [ (2300, 2349), (2176, 2180), (2390, 2393), (2395, 2396), + 2404, + (2413, 2416), + (2450, 2454), ] @@ -88,90 +91,114 @@ 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), - - 'GetStyleAt' : ( 0, 0, - '''int %s(int pos) { - return (unsigned char)SendMsg(%s, pos, 0);''', - 0), - - '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;''', - - ('Retrieve a buffer of cells.',)), - - - 'PositionFromPoint' : (0, - 'int %s(wxPoint pt);', - - '''int %s(wxPoint pt) { - return SendMsg(%s, pt.x, pt.y);''', - - 0), - - '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; - } - - 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);''', - - 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), + + '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;''', + + ('Retrieve a buffer of cells.',)), + + + 'PositionFromPoint' : + (0, + 'int %s(wxPoint pt);', + + '''int %s(wxPoint pt) { + return SendMsg(%s, pt.x, pt.y);''', + 0), + + '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; + } + + 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);''', + + 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);''', - - '''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);''', + '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) { + + 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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 +216,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);', - - '''void %s(int length, char* styleBytes) { - SendMsg(%s, length, (long)styleBytes);''', + 'SetStylingEx' : + ('SetStyleBytes', + 'void %s(int length, char* styleBytes);', - 0), + '''void %s(int length, char* styleBytes) { + SendMsg(%s, length, (long)styleBytes);''', + 0), 'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0), @@ -245,129 +273,162 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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);''', - - '''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), - - '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; - - return SendMsg(%s, doDraw, (long)&fr);''', - 0), - - - 'GetLine' : (0, - 'wxString %s(int line);', - - '''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);''', - - ('Retrieve the contents of a line.',)), + '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; + + 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; + + 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), + + + 'GetLine' : + (0, + 'wxString %s(int line);', + + '''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);''', + + ('Retrieve the contents of a line.',)), 'SetSel' : ('SetSelection', 0, 0, 0), - 'GetSelText' : ('GetSelectedText', - 'wxString %s();', - - '''wxString %s() { - int start; - int end; - - GetSelection(&start, &end); - int len = end - start; - if (!len) return wxEmptyString; - - 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);''', - - ('Retrieve the selected 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.',)), + + 'GetSelText' : + ('GetSelectedText', + 'wxString %s();', + + '''wxString %s() { + int start; + int end; + + GetSelection(&start, &end); + int len = end - start; + if (!len) return wxEmptyString; + + 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);''', + + ('Retrieve the selected 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,88 +437,104 @@ 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), - 'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0), - 'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0), - 'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0), - - - '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), - - '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), - - '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), - - - '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), - - '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), - - 'ReleaseDocument' : (0, - 'void %s(void* docPointer);', - '''void %s(void* docPointer) { - SendMsg(%s, 0, (long)docPointer);''', - 0), - 'SetCodePage' : (0, - 0, - '''void %s(int codePage) { + 'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0), + 'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0), + 'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0), + 'CallTipSetFore' : ('CallTipSetForeground', 0, 0, 0), + 'CallTipSetForeHlt' : ('CallTipSetForegroundHighlight', 0, 0, 0), + + 'SetHotspotActiveFore' : ('SetHotspotActiveForeground', 0, 0, 0), + 'SetHotspotActiveBack' : ('SetHotspotActiveBackground', 0, 0, 0), + + + '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), + + '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), + + '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), + + + '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), + + '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), + + '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 +542,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), @@ -474,6 +551,9 @@ methodOverrideMap = { 'GetFocus' : ('GetSTCFocus', 0, 0, 0), + 'LoadLexerLibrary' : (None, 0,0,0), + + # Remove all methods that are key commands since they can be # executed with CmdKeyExecute @@ -522,7 +602,16 @@ methodOverrideMap = { 'LineScrollDown' : (None, 0, 0, 0), 'LineScrollUp' : (None, 0, 0, 0), 'DeleteBackNotLine' : (None, 0, 0, 0), - + 'HomeWrap' : (None, 0, 0, 0), + 'HomeWrapExtend' : (None, 0, 0, 0), + 'LineEndWrap' : (None, 0, 0, 0), + 'LineEndWrapExtend' : (None, 0, 0, 0), + 'VCHomeWrap' : (None, 0, 0, 0), + 'VCHomeWrapExtend' : (None, 0, 0, 0), + 'ParaDown' : (None, 0, 0, 0), + 'ParaDownExtend' : (None, 0, 0, 0), + 'ParaUp' : (None, 0, 0, 0), + 'ParaUpExtend' : (None, 0, 0, 0), diff --git a/contrib/src/stc/makefile.b32 b/contrib/src/stc/makefile.b32 index 5a9843f863..345d659000 100644 --- a/contrib/src/stc/makefile.b32 +++ b/contrib/src/stc/makefile.b32 @@ -34,17 +34,21 @@ 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 \ LexOthers.obj \ + LexPOV.obj \ LexPascal.obj \ LexPerl.obj \ LexPython.obj \ @@ -60,17 +64,19 @@ OBJECTS = \ UniConversion.obj \ ViewStyle.obj \ WindowAccessor.obj \ + XPM.obj \ \ 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..25dd4ad0cd 100644 --- a/contrib/src/stc/makefile.g95 +++ b/contrib/src/stc/makefile.g95 @@ -22,17 +22,21 @@ 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) \ $(S)/LexOthers.$(OBJSUFF) \ + $(S)/LexPOV.$(OBJSUFF) \ $(S)/LexPascal.$(OBJSUFF) \ $(S)/LexPerl.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \ @@ -48,11 +52,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..4aa0e2c352 100644 --- a/contrib/src/stc/makefile.vc +++ b/contrib/src/stc/makefile.vc @@ -27,17 +27,21 @@ 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 \ $(D)\LexOthers.obj \ + $(D)\LexPOV.obj \ $(D)\LexPascal.obj \ $(D)\LexPerl.obj \ $(D)\LexPython.obj \ @@ -53,6 +57,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..76a2985a3b 100644 --- a/contrib/src/stc/makefile.wat +++ b/contrib/src/stc/makefile.wat @@ -31,17 +31,21 @@ 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 & LexOthers.obj & + LexPOV.obj & LexPascal.obj & LexPerl.obj & LexPython.obj & @@ -57,9 +61,10 @@ OBJECTS = & UniConversion.obj & ViewStyle.obj & WindowAccessor.obj & + XPM.obj & PlatWX.obj & ScintillaWX.obj & - stc.obj + stc.obj all: $(STCLIB) .SYMBOLIC @@ -67,17 +72,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/License.txt b/contrib/src/stc/scintilla/License.txt new file mode 100644 index 0000000000..cbe25b2fc2 --- /dev/null +++ b/contrib/src/stc/scintilla/License.txt @@ -0,0 +1,20 @@ +License for Scintilla and SciTE + +Copyright 1998-2003 by Neil Hodgson + +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/contrib/src/stc/scintilla/README.txt b/contrib/src/stc/scintilla/README.txt index 8538707cde..4f5b08f1cb 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.52 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..7f5985c765 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 @@ -109,6 +109,12 @@ public: return (right > other.left) && (left < other.right) && (bottom > other.top) && (top < other.bottom); } + void Move(int xDelta, int yDelta) { + left += xDelta; + top += yDelta; + right += xDelta; + bottom += yDelta; + } int Width() { return right - left; } int Height() { return bottom - top; } }; @@ -136,7 +142,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 +153,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 +227,9 @@ struct ColourPair { desired = desired_; allocated.Set(desired.AsLong()); } + void Copy() { + allocated.Set(desired.AsLong()); + } }; class Window; // Forward declaration for Palette @@ -271,9 +305,9 @@ public: virtual ~Surface() {}; static Surface *Allocate(); - virtual void Init()=0; - virtual void Init(SurfaceID sid)=0; - virtual void InitPixMap(int width, int height, Surface *surface_)=0; + virtual void Init(WindowID wid)=0; + virtual void Init(SurfaceID sid, WindowID wid)=0; + virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; virtual void Release()=0; virtual bool Initialised()=0; @@ -292,6 +326,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 +342,7 @@ public: virtual void FlushCachedState()=0; virtual void SetUnicodeMode(bool unicodeMode_)=0; + virtual void SetDBCSMode(int codePage)=0; }; /** @@ -329,8 +365,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(); @@ -341,7 +377,7 @@ public: void InvalidateAll(); void InvalidateRectangle(PRectangle rc); virtual void SetFont(Font &font); - enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow }; + enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; void SetCursor(Cursor curs); void SetTitle(const char *s); private: @@ -353,38 +389,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; }; /** @@ -426,6 +452,7 @@ public: static const char *DefaultFont(); static int DefaultFontSize(); static unsigned int DoubleClickTime(); + static bool MouseButtonBounce(); static void DebugDisplay(const char *s); static bool IsKeyDown(int key); static long SendScintilla( @@ -433,6 +460,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..e1da492b27 100644 --- a/contrib/src/stc/scintilla/include/SciLexer.h +++ b/contrib/src/stc/scintilla/include/SciLexer.h @@ -48,6 +48,12 @@ #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_POV 39 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -273,6 +279,9 @@ #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_ERR_ELF 15 +#define SCE_ERR_IFC 16 #define SCE_BAT_DEFAULT 0 #define SCE_BAT_COMMENT 1 #define SCE_BAT_WORD 2 @@ -309,22 +318,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 +408,58 @@ #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 +#define SCE_CSS_DOUBLESTRING 13 +#define SCE_CSS_SINGLESTRING 14 +#define SCE_POV_DEFAULT 0 +#define SCE_POV_COMMENT 1 +#define SCE_POV_COMMENTLINE 2 +#define SCE_POV_COMMENTDOC 3 +#define SCE_POV_NUMBER 4 +#define SCE_POV_WORD 5 +#define SCE_POV_STRING 6 +#define SCE_POV_OPERATOR 7 +#define SCE_POV_IDENTIFIER 8 +#define SCE_POV_BRACE 9 +#define SCE_POV_WORD2 10 //--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..c377d07cc2 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 @@ -181,6 +184,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_CASE_LOWER 2 #define SCI_STYLESETCASE 2060 #define SCI_STYLESETCHARACTERSET 2066 +#define SCI_STYLESETHOTSPOT 2409 #define SCI_SETSELFORE 2067 #define SCI_SETSELBACK 2068 #define SCI_SETCARETFORE 2069 @@ -241,6 +245,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 @@ -278,6 +286,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCFIND_MATCHCASE 4 #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 +#define SCFIND_POSIX 0x00400000 #define SCI_FINDTEXT 2150 #define SCI_FORMATRANGE 2151 #define SCI_GETFIRSTVISIBLELINE 2152 @@ -333,11 +342,17 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_CALLTIPPOSSTART 2203 #define SCI_CALLTIPSETHLT 2204 #define SCI_CALLTIPSETBACK 2205 +#define SCI_CALLTIPSETFORE 2206 +#define SCI_CALLTIPSETFOREHLT 2207 #define SCI_VISIBLEFROMDOCLINE 2220 #define SCI_DOCLINEFROMVISIBLE 2221 #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 +365,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 +398,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 +448,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 @@ -426,6 +458,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_HOMEDISPLAYEXTEND 2346 #define SCI_LINEENDDISPLAY 2347 #define SCI_LINEENDDISPLAYEXTEND 2348 +#define SCI_HOMEWRAP 2349 +#define SCI_HOMEWRAPEXTEND 2450 +#define SCI_LINEENDWRAP 2451 +#define SCI_LINEENDWRAPEXTEND 2452 +#define SCI_VCHOMEWRAP 2453 +#define SCI_VCHOMEWRAPEXTEND 2454 #define SCI_MOVECARETINSIDEVIEW 2401 #define SCI_LINELENGTH 2350 #define SCI_BRACEHIGHLIGHT 2351 @@ -464,7 +502,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 +518,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 +526,15 @@ 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_SETHOTSPOTACTIVEFORE 2410 +#define SCI_SETHOTSPOTACTIVEBACK 2411 +#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412 +#define SCI_PARADOWN 2413 +#define SCI_PARADOWNEXTEND 2414 +#define SCI_PARAUP 2415 +#define SCI_PARAUPEXTEND 2416 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 @@ -495,6 +543,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETPROPERTY 4004 #define SCI_SETKEYWORDS 4005 #define SCI_SETLEXERLANGUAGE 4006 +#define SCI_LOADLEXERLIBRARY 4007 #define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_DELETETEXT 0x2 #define SC_MOD_CHANGESTYLE 0x4 @@ -548,6 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCN_DWELLSTART 2016 #define SCN_DWELLEND 2017 #define SCN_ZOOM 2018 +#define SCN_HOTSPOTCLICK 2019 +#define SCN_HOTSPOTDOUBLECLICK 2020 +#define SCN_CALLTIPCLICK 2021 //--Autogenerated -- end of section automatically generated from Scintilla.iface // These structures are defined to be exactly the same shape as the Win32 diff --git a/contrib/src/stc/scintilla/include/Scintilla.iface b/contrib/src/stc/scintilla/include/Scintilla.iface index d6383b103b..c5dacbdf04 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 @@ -405,6 +412,9 @@ set void StyleSetCase=2060(int style, int caseForce) # Set the character set of the font in a style. set void StyleSetCharacterSet=2066(int style, int characterSet) +# Set a style to be a hotspot or not. +set void StyleSetHotSpot=2409(int style, bool hotspot) + # Set the foreground colour of the selection and whether to use this setting. fun void SetSelFore=2067(bool useSetting, colour fore) @@ -578,6 +588,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,) @@ -681,6 +704,7 @@ val SCFIND_WHOLEWORD=2 val SCFIND_MATCHCASE=4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 +val SCFIND_POSIX=0x00400000 # Find some text in the document. fun position FindText=2150(int flags, findtext ft) @@ -688,7 +712,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. @@ -863,6 +887,12 @@ fun void CallTipSetHlt=2204(int start, int end) # Set the background colour for the call tip. set void CallTipSetBack=2205(colour back,) +# Set the foreground colour for the call tip. +set void CallTipSetFore=2206(colour fore,) + +# Set the foreground colour for the highlighted part of the call tip. +set void CallTipSetForeHlt=2207(colour fore,) + # Find the display line of a document line taking hidden lines into account. fun int VisibleFromDocLine=2220(int line,) @@ -873,6 +903,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 +944,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 +1030,38 @@ 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. +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 +1185,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(,) @@ -1141,6 +1218,19 @@ fun void LineEndDisplay=2347(,) # caret position. fun void LineEndDisplayExtend=2348(,) +# These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? +# except they behave differently when word-wrap is enabled: +# They go first to the start / end of the display line, like (Home|LineEnd)Display +# The difference is that, the cursor is already at the point, it goes on to the start +# or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend. + +fun void HomeWrap=2349(,) +fun void HomeWrapExtend=2450(,) +fun void LineEndWrap=2451(,) +fun void LineEndWrapExtend=2452(,) +fun void VCHomeWrap=2453(,) +fun void VCHomeWrapExtend=2454(,) + # Move the caret inside current view if it's not there already. fun void MoveCaretInsideView=2401(,) @@ -1251,7 +1341,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 +1381,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 +1420,27 @@ 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(,) + +# Set a fore colour for active hotspots. +set void SetHotspotActiveFore=2410(bool useSetting, colour fore) + +# Set a back colour for active hotspots. +set void SetHotspotActiveBack=2411(bool useSetting, colour back) + +# Enable / Disable underlining active hotspots. +set void SetHotspotActiveUnderline=2412(bool underline,) + +# Move caret between paragraphs (delimited by empty lines) +fun void ParaDown=2413(,) +fun void ParaDownExtend=2414(,) +fun void ParaUp=2415(,) +fun void ParaUpExtend=2416(,) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) @@ -1351,6 +1465,10 @@ set void SetKeyWords=4005(int keywordSet, string keyWords) # Set the lexing language of the document based on string name. set void SetLexerLanguage=4006(, string language) +# Load a lexer library (dll / so) +# NOT YET IMPLEMENTED +fun void LoadLexerLibrary=4007(, string path) + # Notifications # Type of modification and the action which caused the modification. # These are defined as a bit mask to make it easy to specify which notifications are wanted. @@ -1442,6 +1560,12 @@ 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 +val SCLEX_POV=39 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -1708,6 +1832,9 @@ 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 +val SCE_ERR_ELF=15 +val SCE_ERR_IFC=16 # Lexical states for SCLEX_BATCH lex Batch=SCLEX_BATCH SCE_BAT_ val SCE_BAT_DEFAULT=0 @@ -1754,24 +1881,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,7 +1986,67 @@ 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 +val SCE_CSS_DOUBLESTRING=13 +val SCE_CSS_SINGLESTRING=14 +# Lexical states for SCLEX_POV +lex POV=SCLEX_POV SCE_POV_ +val SCE_POV_DEFAULT=0 +val SCE_POV_COMMENT=1 +val SCE_POV_COMMENTLINE=2 +val SCE_POV_COMMENTDOC=3 +val SCE_POV_NUMBER=4 +val SCE_POV_WORD=5 +val SCE_POV_STRING=6 +val SCE_POV_OPERATOR=7 +val SCE_POV_IDENTIFIER=8 +val SCE_POV_BRACE=9 +val SCE_POV_WORD2=10 # Events evt void StyleNeeded=2000(int position) @@ -1874,6 +2068,9 @@ evt void URIDropped=2015(string text) evt void DwellStart=2016(int position) evt void DwellEnd=2017(int position) evt void Zoom=2018(void) +evt void HotSpotClick=2019(int modifiers, int position) +evt void HotSpotDoubleClick=2020(int modifiers, int position) +evt void CallTipClick=2021(int position) cat Deprecated 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..314f9bfa71 100644 --- a/contrib/src/stc/scintilla/src/CallTip.cxx +++ b/contrib/src/stc/scintilla/src/CallTip.cxx @@ -18,6 +18,9 @@ CallTip::CallTip() { inCallTipMode = false; posStartCallTip = 0; val = 0; + xUp = -100; + xDown = -100; + lineHeight = 1; startHighlight = 0; endHighlight = 0; @@ -35,6 +38,8 @@ CallTip::~CallTip() { val = 0; } +const int widthArrow = 14; + void CallTip::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(colourBG, want); pal.WantFind(colourUnSel, want); @@ -43,24 +48,98 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(colourLight, want); } -void CallTip::PaintCT(Surface *surfaceWindow) { - if (!val) - return ; +void CallTip::DrawChunk(Surface *surface, int &x, const char *s, + int posStart, int posEnd, int ytext, PRectangle rcClient, + bool highlight, bool draw) { + s += posStart; + int len = posEnd - posStart; + int maxEnd = 0; + int ends[10]; + for (int i=0;i 0) + ends[maxEnd++] = i; + ends[maxEnd++] = i+1; + } + } + ends[maxEnd++] = len; + int startSeg = 0; + int xEnd; + for (int seg = 0; seg startSeg) { + if (s[startSeg] <= '\002') { + xEnd = x + widthArrow; + offsetMain = xEnd; + if (draw) { + const int halfWidth = widthArrow / 2 - 3; + const int centreX = x + widthArrow / 2 - 1; + const int centreY = (rcClient.top + rcClient.bottom) / 2; + rcClient.left = x; + rcClient.right = xEnd; + surface->FillRectangle(rcClient, colourBG.allocated); + PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1); + surface->FillRectangle(rcClientInner, colourUnSel.allocated); + + if (s[startSeg] == '\001') { + // Up arrow + Point pts[] = { + Point(centreX - halfWidth, centreY + halfWidth / 2), + Point(centreX + halfWidth, centreY + halfWidth / 2), + Point(centreX, centreY - halfWidth + halfWidth / 2), + }; + surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), + colourBG.allocated, colourBG.allocated); + } else { + // Down arrow + Point pts[] = { + Point(centreX - halfWidth, centreY - halfWidth / 2), + Point(centreX + halfWidth, centreY - halfWidth / 2), + Point(centreX, centreY + halfWidth - halfWidth / 2), + }; + surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), + colourBG.allocated, colourBG.allocated); + } + } else { + if (s[startSeg] == '\001') { + xUp = x+1; + } else { + xDown = x+1; + } + } + } else { + xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg); + if (draw) { + rcClient.left = x; + rcClient.right = xEnd; + surface->DrawTextNoClip(rcClient, font, ytext, + s+startSeg, endSeg - startSeg, + highlight ? colourSel.allocated : colourUnSel.allocated, + colourBG.allocated); + } + } + x = xEnd; + startSeg = endSeg; + } + } +} + +int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { PRectangle rcClientPos = wCallTip.GetClientPosition(); PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, rcClientPos.bottom - rcClientPos.top); PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); - surfaceWindow->FillRectangle(rcClient, colourBG.allocated); // To make a nice small call tip window, it is only sized to fit most normal characters without accents - int lineHeight = surfaceWindow->Height(font); int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight int ytext = rcClient.top + ascent + 1; + rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; char *chunkVal = val; bool moreChunks = true; + int maxWidth = 0; while (moreChunks) { char *chunkEnd = strchr(chunkVal, '\n'); if (chunkEnd == NULL) { @@ -76,36 +155,38 @@ void CallTip::PaintCT(Surface *surfaceWindow) { int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset); thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset); thisEndHighlight -= chunkOffset; - int x = 5; - int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight); - rcClient.left = x; rcClient.top = ytext - ascent - 1; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal, thisStartHighlight, - colourUnSel.allocated, colourBG.allocated); - x = xEnd; - - xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight, - thisEndHighlight - thisStartHighlight); - rcClient.top = ytext; - rcClient.left = x; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight, - colourSel.allocated, colourBG.allocated); - x = xEnd; - - xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight, - chunkLength - thisEndHighlight); - rcClient.left = x; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal + thisEndHighlight, chunkLength - thisEndHighlight, - colourUnSel.allocated, colourBG.allocated); + + int x = 5; + + DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, + ytext, rcClient, false, draw); + DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, + ytext, rcClient, true, draw); + DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, + ytext, rcClient, false, draw); + chunkVal = chunkEnd + 1; ytext += lineHeight; + rcClient.bottom += lineHeight; + maxWidth = Platform::Maximum(maxWidth, x); } + return maxWidth; +} + +void CallTip::PaintCT(Surface *surfaceWindow) { + if (!val) + return; + PRectangle rcClientPos = wCallTip.GetClientPosition(); + PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, + rcClientPos.bottom - rcClientPos.top); + PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); + + surfaceWindow->FillRectangle(rcClient, colourBG.allocated); + + offsetMain = 5; + PaintContents(surfaceWindow, true); + // Draw a raised border around the edges of the window surfaceWindow->MoveTo(0, rcClientSize.bottom - 1); surfaceWindow->PenColour(colourShade.allocated); @@ -116,20 +197,34 @@ void CallTip::PaintCT(Surface *surfaceWindow) { surfaceWindow->LineTo(0, rcClientSize.bottom - 1); } +void CallTip::MouseClick(Point pt) { + clickPlace = 0; + if (pt.y < lineHeight) { + if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) { + clickPlace = 1; + } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) { + clickPlace = 2; + } + } +} + PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, - const char *faceName, int size, bool unicodeMode_) { + const char *faceName, int size, + int codePage_, Window &wParent) { + clickPlace = 0; 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->Init(wParent.GetID()); + surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); + surfaceMeasure->SetDBCSMode(codePage); startHighlight = 0; endHighlight = 0; inCallTipMode = true; @@ -138,23 +233,22 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false); // Look for multiple lines in the text // Only support \n here - simply means container must avoid \r! - int width = 0; int numLines = 1; const char *newline; const char *look = val; + xUp = -100; + xDown = -100; + offsetMain = 5; + int width = PaintContents(surfaceMeasure, false) + 5; while ((newline = strchr(look, '\n')) != NULL) { - int thisWidth = surfaceMeasure->WidthText(font, look, newline - look); - width = Platform::Maximum(width, thisWidth); look = newline + 1; numLines++; } - int lastWidth = surfaceMeasure->WidthText(font, look, static_cast(strlen(look))); - width = Platform::Maximum(width, lastWidth) + 10; - int lineHeight = surfaceMeasure->Height(font); + lineHeight = surfaceMeasure->Height(font); // Extra line for border and an empty line at top and bottom int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2; delete surfaceMeasure; - return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height); + return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height); } void CallTip::CallTipCancel() { diff --git a/contrib/src/stc/scintilla/src/CallTip.h b/contrib/src/stc/scintilla/src/CallTip.h index 9f5025f63b..ffaedb0771 100644 --- a/contrib/src/stc/scintilla/src/CallTip.h +++ b/contrib/src/stc/scintilla/src/CallTip.h @@ -15,9 +15,17 @@ class CallTip { int endHighlight; char *val; Font font; + int xUp; + int xDown; + int lineHeight; + int offsetMain; // Private so CallTip objects can not be copied CallTip(const CallTip &) {} CallTip &operator=(const CallTip &) { return *this; } + void DrawChunk(Surface *surface, int &x, const char *s, + int posStart, int posEnd, int ytext, PRectangle rcClient, + bool highlight, bool draw); + int PaintContents(Surface *surfaceWindow, bool draw); public: Window wCallTip; @@ -29,22 +37,25 @@ public: ColourPair colourSel; ColourPair colourShade; ColourPair colourLight; - bool unicodeMode; - + int codePage; + int clickPlace; + 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); - + + void MouseClick(Point pt); + /// 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_, Window &wParent); + 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..20900bcf97 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++; - } - - - if (atLeadByte) { - // Position is between a lead byte and a trail byte - if (moveDir > 0) - return pos + 1; - else - return pos - 1; + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for(i=0;i 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); } @@ -718,6 +720,33 @@ void Document::ConvertLineEnds(int eolModeSet) { EndUndoAction(); } +int Document::ParaDown(int pos) { + int line = LineFromPosition(pos); + while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines + line++; + } + while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines + line++; + } + if (line < LinesTotal()) + return LineStart(line); + else // end of a document + return LineEnd(line-1); +} + +int Document::ParaUp(int pos) { + int line = LineFromPosition(pos); + line--; + while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines + line--; + } + while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines + line--; + } + line++; + return LineStart(line); +} + Document::charClassification Document::WordCharClass(unsigned char ch) { if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80)) return ccWord; @@ -745,7 +774,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 +827,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) { @@ -845,7 +874,7 @@ public: * Has not been tested with backwards DBCS searches yet. */ long Document::FindText(int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, bool regExp, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length) { if (regExp) { if (!pre) @@ -853,22 +882,16 @@ 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); endPos = MovePositionOutsideChar(endPos, 1, false); - const char *errmsg = pre->Compile(s, *length, caseSensitive); + const char *errmsg = pre->Compile(s, *length, caseSensitive, posix); if (errmsg) { return -1; } @@ -878,7 +901,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,36 +911,54 @@ 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 ((startPos != startOfLine) && (s[0] == '^')) - continue; // Can't match start of line if start position after start of line - startOfLine = startPos; - } - if (line == lineRangeEnd) { - if ((endPos != endOfLine) && (searchEnd == '$')) - continue; // Can't match end of line if end position before end of line - endOfLine = endPos; + if (increment == 1) { + if (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 ((endPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if end position before end of line + endOfLine = endPos; + } + } else { + if (line == lineRangeEnd) { + if ((endPos != startOfLine) && (s[0] == '^')) + continue; // Can't match start of line if end position after start of line + startOfLine = endPos; + } + if (line == lineRangeStart) { + if ((startPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if start position before end of line + endOfLine = startPos; + } } + DocumentIndexer di(this, endOfLine); int success = pre->Execute(di, startOfLine, endOfLine); if (success) { pos = pre->bopat[0]; lenRet = pre->eopat[0] - pre->bopat[0]; + if (increment == -1) { + // Check for the last match on this line. + int repetitions = 1000; // Break out of infinite loop + while (success && (pre->eopat[0] < endOfLine) && (repetitions--)) { + 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 +1076,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 +1111,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 +1136,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 +1251,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 +1266,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 +1312,47 @@ 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; +} + +int Document::ExtendStyleRange(int pos, int delta) { + int sStart = cb.StyleAt(pos); + if (delta < 0) { + while (pos > 0 && (cb.StyleAt(pos) == sStart)) + pos--; + pos++; + } else { + while (pos < (Length()) && (cb.StyleAt(pos) == sStart)) + pos++; } return pos; } diff --git a/contrib/src/stc/scintilla/src/Document.h b/contrib/src/stc/scintilla/src/Document.h index 82931207cf..bcdbe00ca5 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,8 +191,8 @@ 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, - bool caseSensitive, bool word, bool wordStart, bool regExp, int *length); + long FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length); long FindText(int iMessage, unsigned long wParam, long lParam); const char *SubstituteByPosition(const char *text, int *length); int LinesTotal(); @@ -220,9 +220,11 @@ public: bool IsWordPartSeparator(char ch); int WordPartLeft(int pos); int WordPartRight(int pos); + int ExtendStyleRange(int pos, int delta); + int ParaUp(int pos); + int ParaDown(int pos); private: - bool IsDBCS(int pos); charClassification WordCharClass(unsigned char ch); bool IsWordStartAt(int pos); bool IsWordEndAt(int pos); @@ -252,7 +254,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..44399a5fb0 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(); @@ -358,7 +364,7 @@ Editor::Editor() { modEventMask = SC_MODEVENTMASKALL; pdoc = new Document(); - pdoc ->AddRef(); + pdoc->AddRef(); pdoc->AddWatcher(this, 0); recordingMacro = false; @@ -368,7 +374,10 @@ Editor::Editor() { wrapWidth = LineLayout::wrapWidthInfinite; docLineLastWrapped = -1; - llc.SetLevel(LineLayoutCache::llcDocument); + hsStart = -1; + hsEnd = -1; + + llc.SetLevel(LineLayoutCache::llcCaret); } Editor::~Editor() { @@ -414,7 +423,7 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) { void Editor::RefreshStyleData() { if (!stylesValid) { stylesValid = true; - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(this); if (surface) { vs.Refresh(*surface); RefreshColourPalette(palette, true); @@ -474,10 +483,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 +495,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 +526,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(this); + 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 +539,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 +549,6 @@ Point Editor::LocationFromPosition(int pos) { } pt.x += vs.fixedColumnWidth - xOffset; } - llc.Dispose(ll); return pt; } @@ -535,6 +566,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 +582,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(this); + 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 +627,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(this); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -604,18 +636,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 +659,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(this); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); int retVal = 0; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -638,17 +668,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 +849,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; } @@ -845,9 +901,9 @@ int Editor::MovePositionTo(int newPos, bool extend, bool ensureVisible) { } else { SetEmptySelection(newPos); } + ShowCaretAtCurrentPosition(); if (ensureVisible) EnsureCaretVisible(); - ShowCaretAtCurrentPosition(); NotifyMove(newPos); return 0; } @@ -877,7 +933,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 +946,9 @@ void Editor::ScrollTo(int line) { } else { Redraw(); } - SetVerticalScrollPos(); + if (moveThumb) { + SetVerticalScrollPos(); + } } } @@ -916,32 +974,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(this); + 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; } @@ -1092,9 +1149,9 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { } newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos()); if (newTopLine != topLine) { + Redraw(); SetTopLine(newTopLine); SetVerticalScrollPos(); - Redraw(); } } @@ -1166,7 +1223,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 +1258,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 +1314,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 +1330,17 @@ bool Editor::WrapLines() { wrapWidth = rcTextArea.Width(); // Ensure all of the document is styled. pdoc->EnsureStyledTo(pdoc->Length()); - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(this); 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 +1363,63 @@ bool Editor::WrapLines() { return wrapOccurred; } +void Editor::LinesJoin() { + if (!RangeContainsProtected(targetStart, targetEnd)) { + pdoc->BeginUndoAction(); + bool prevNonWS = true; + for (int pos = targetStart; pos < targetEnd; pos++) { + if (IsEOLChar(pdoc->CharAt(pos))) { + targetEnd -= pdoc->LenChar(pos); + pdoc->DelChar(pos); + if (prevNonWS) { + // Ensure at least one space separating previous lines + pdoc->InsertChar(pos, ' '); + } + } else { + prevNonWS = pdoc->CharAt(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(this); + 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) * strlen(eol) + + 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 +1492,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 +1506,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 +1576,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 +1584,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 +1639,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 +1661,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 +1675,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 +1720,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 +1751,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 +1765,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 +1777,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 +1818,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 +1841,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 +1855,71 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } } +ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground, + ColourAllocated background, bool inSelection, bool inHotspot, 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 (inHotspot) + return vsDraw.hotspotBackground.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 +1966,93 @@ 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); + } + 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) || + 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); + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, 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; + } } - for (int i = lineStart; i < lineEnd; i++) { + + 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) || + 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 +2062,27 @@ 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; + //hotspot foreground + if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) { + if (vsDraw.hotspotForegroundSet) + textFore = vsDraw.hotspotForeground.allocated; + } 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; } + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, 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 +2091,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 +2126,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 +2156,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 +2171,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 { @@ -1927,7 +2181,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } } } - if (vsDraw.styles[styleMain].underline) { + if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) { + PRectangle rcUL = rcSegment; + rcUL.top = rcUL.top + vsDraw.maxAscent + 1; + rcUL.bottom = rcUL.top + 1; + if (vsDraw.hotspotForegroundSet) + surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated); + else + surface->FillRectangle(rcUL, textFore); + } else if (vsDraw.styles[styleMain].underline) { PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; @@ -1964,31 +2226,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,47 +2239,48 @@ 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, wMain.GetID()); + // 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); - pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); + pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); PRectangle rcIG(0, 0, 1, vs.lineHeight); pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); @@ -2055,12 +2296,26 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (bufferedDraw) { if (!pixmapLine->Initialised()) { + PRectangle rcClient = GetClientRectangle(); pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(), - surfaceWindow); + surfaceWindow, wMain.GetID()); pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, - rcClient.Height(), surfaceWindow); + rcClient.Height(), surfaceWindow, wMain.GetID()); } } +} + +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 +2345,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 +2382,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface = pixmapLine; } surface->SetUnicodeMode(IsUnicodeMode()); + surface->SetDBCSMode(CodePage()); int visibleLine = topLine + screenLinePaintFirst; @@ -2140,7 +2404,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 +2417,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; } @@ -2170,6 +2433,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { ll->containsCaret = false; } + GetHotSpotRange(ll->hsStart, ll->hsEnd); + PRectangle rcLine = rcClient; rcLine.top = ypos; rcLine.bottom = ypos + vs.lineHeight; @@ -2177,7 +2442,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 +2452,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 +2551,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 +2565,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { visibleLine++; //gdk_flush(); } - llc.Dispose(ll); //if (durPaint < 0.00000001) // durPaint = 0.00000001; @@ -2307,10 +2613,10 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; - AutoSurface surface(pfr->hdc, IsUnicodeMode()); + AutoSurface surface(pfr->hdc, this); if (!surface) return 0; - AutoSurface surfaceMeasure(pfr->hdcTarget, IsUnicodeMode()); + AutoSurface surfaceMeasure(pfr->hdcTarget, this); if (!surfaceMeasure) { return 0; } @@ -2364,8 +2670,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 +2679,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 +2694,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 - while (line <= linePrintLast && ypos < pfr->rc.bottom) { - - // 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(); + int lineDoc = linePrintStart; + + int nPrintPos = pfr->chrg.cpMin; + int visibleLine = 0; + int widthPrint = pfr->rc.Width() - lineNumberWidth; + if (printWrapState == eWrapNone) + widthPrint = LineLayout::wrapWidthInfinite; + + while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { + + // 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(); + + // 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); + + 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; + } + } - // 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; - - PRectangle rcLine; - rcLine.left = pfr->rc.left + lineNumberWidth; - rcLine.top = ypos; - rcLine.right = pfr->rc.right; - rcLine.bottom = ypos + vsPrint.lineHeight; - - 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); + if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) { + visibleLine = -(ll.lines - 1); } + } - // Draw the line + 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(); - DrawLine(surface, vsPrint, line, line, xStart, rcLine, &ll); - - ypos += vsPrint.lineHeight; - line++; + 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(this); if (surface) { return surface->WidthText(vs.styles[style].font, text, strlen(text)); } else { @@ -2451,8 +2797,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 +2844,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 (currentPos < (pdoc->Length() - 1)) { - if ((pdoc->CharAt(currentPos) != '\r') && (pdoc->CharAt(currentPos) != '\n')) { + if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) { + if (currentPos < (pdoc->Length())) { + if (!IsEOLChar(pdoc->CharAt(currentPos))) { pdoc->DelChar(currentPos); } } @@ -2516,7 +2861,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 +2887,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,30 +2898,32 @@ 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 (!SelectionContainsProtected()) { + 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) { + pdoc->BeginUndoAction(); pdoc->DeleteChars(startPos, chars); + pdoc->EndUndoAction(); } } - 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 +2950,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 +2966,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 +2995,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 +3032,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 { @@ -2764,6 +3117,24 @@ void Editor::NotifyDoubleClick(Point, bool) { NotifyParent(scn); } +void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) { + SCNotification scn; + scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; + scn.position = position; + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0); + NotifyParent(scn); +} + +void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) { + SCNotification scn; + scn.nmhdr.code = SCN_HOTSPOTCLICK; + scn.position = position; + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0); + NotifyParent(scn); +} + void Editor::NotifyUpdateUI() { SCNotification scn; scn.nmhdr.code = SCN_UPDATEUI; @@ -2841,23 +3212,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(this); + 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 +3374,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: @@ -3013,8 +3384,12 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_SEARCHPREV: case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: + case SCI_PARADOWN: + case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: + case SCI_PARAUP: + case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: @@ -3031,6 +3406,10 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: + case SCI_HOMEWRAP: + case SCI_HOMEWRAPEXTEND: + case SCI_LINEENDWRAP: + case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: @@ -3047,6 +3426,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: + case SCI_VCHOMEWRAP: + case SCI_VCHOMEWRAPEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: case SCI_DELLINELEFT: @@ -3054,6 +3435,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 +3452,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 +3536,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 +3571,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 +3589,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(this); + 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 { @@ -3234,6 +3626,12 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_LINEDOWNEXTEND: CursorUpOrDown(1, true); break; + case SCI_PARADOWN: + MovePositionTo(pdoc->ParaDown(currentPos)); + break; + case SCI_PARADOWNEXTEND: + MovePositionTo(pdoc->ParaDown(currentPos), true); + break; case SCI_LINESCROLLDOWN: ScrollTo(topLine + 1); MoveCaretInsideView(false); @@ -3244,6 +3642,12 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_LINEUPEXTEND: CursorUpOrDown(-1, true); break; + case SCI_PARAUP: + MovePositionTo(pdoc->ParaUp(currentPos)); + break; + case SCI_PARAUPEXTEND: + MovePositionTo(pdoc->ParaUp(currentPos), true); + break; case SCI_LINESCROLLUP: ScrollTo(topLine - 1); MoveCaretInsideView(false); @@ -3304,6 +3708,38 @@ int Editor::KeyCommand(unsigned int iMessage) { MovePositionTo(pdoc->LineEndPosition(currentPos), true); SetLastXChosen(); break; + case SCI_HOMEWRAP: { + int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if (currentPos <= homePos) + homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos)); + MovePositionTo(homePos); + SetLastXChosen(); + } + break; + case SCI_HOMEWRAPEXTEND: { + int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if (currentPos <= homePos) + homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos)); + MovePositionTo(homePos, true); + SetLastXChosen(); + } + break; + case SCI_LINEENDWRAP: { + int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1); + if (currentPos >= endPos) + endPos = pdoc->LineEndPosition(currentPos); + MovePositionTo(endPos); + SetLastXChosen(); + } + break; + case SCI_LINEENDWRAPEXTEND: { + int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1); + if (currentPos >= endPos) + endPos = pdoc->LineEndPosition(currentPos); + MovePositionTo(endPos, true); + SetLastXChosen(); + } + break; case SCI_DOCUMENTSTART: MovePositionTo(0); SetLastXChosen(); @@ -3321,10 +3757,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 +3774,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; @@ -3376,6 +3812,26 @@ int Editor::KeyCommand(unsigned int iMessage) { MovePositionTo(pdoc->VCHomePosition(currentPos), true); SetLastXChosen(); break; + case SCI_VCHOMEWRAP: { + int homePos = pdoc->VCHomePosition(currentPos); + int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if ((viewLineStart < currentPos) && (viewLineStart > homePos)) + homePos = viewLineStart; + + MovePositionTo(homePos); + SetLastXChosen(); + } + break; + case SCI_VCHOMEWRAPEXTEND: { + int homePos = pdoc->VCHomePosition(currentPos); + int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if ((viewLineStart < currentPos) && (viewLineStart > homePos)) + homePos = viewLineStart; + + MovePositionTo(homePos, true); + SetLastXChosen(); + } + break; case SCI_ZOOMIN: if (vs.zoomLevel < 20) { vs.zoomLevel++; @@ -3438,6 +3894,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 +3921,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,8 +4051,8 @@ 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, - ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. + uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range. TextToFind *ft = reinterpret_cast(lParam); @@ -3603,6 +4062,7 @@ long Editor::FindText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { ft->chrgText.cpMin = pos; @@ -3632,8 +4092,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. @@ -3646,6 +4106,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } else { pos = pdoc->FindText(searchAnchor, 0, txt, @@ -3653,6 +4114,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } @@ -3674,6 +4136,7 @@ long Editor::SearchInTarget(const char *text, int length) { (searchFlags & SCFIND_WHOLEWORD) != 0, (searchFlags & SCFIND_WORDSTART) != 0, (searchFlags & SCFIND_REGEXP) != 0, + (searchFlags & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { targetStart = pos; @@ -3943,7 +4406,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b SetEmptySelection(newPos); bool doubleClick = false; // Stop mouse button bounce changing selection type - if (curTime != lastClickTime) { + if (!Platform::MouseButtonBounce() || curTime != lastClickTime) { if (selectionType == selChar) { selectionType = selWord; doubleClick = true; @@ -3967,13 +4430,15 @@ 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); - if (doubleClick) + if (doubleClick) { NotifyDoubleClick(pt, shift); + if (PositionIsHotspot(newPos)) + NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt); + } } else { // Single click if (inSelMargin) { selType = selStream; @@ -4003,6 +4468,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b SetMouseCapture(true); selectionType = selLine; } else { + if (PositionIsHotspot(newPos)) { + NotifyHotSpotClicked(newPos, shift, ctrl, alt); + } if (!shift) { inDragDrop = PointInSelection(pt); } @@ -4029,6 +4497,53 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b ShowCaretAtCurrentPosition(); } +bool Editor::PositionIsHotspot(int position) { + return vs.styles[pdoc->StyleAt(position)].hotspot; +} + +bool Editor::PointIsHotspot(Point pt) { + int pos = PositionFromLocation(pt); + return PositionIsHotspot(pos); +} + +void Editor::SetHotSpotRange(Point *pt) { + if (pt) { + int pos = PositionFromLocation(*pt); + + // If we don't limit this to word characters then the + // range can encompass more than the run range and then + // the underline will not be drawn properly. + int hsStart_ = pdoc->ExtendStyleRange(pos, -1); + int hsEnd_ = pdoc->ExtendStyleRange(pos, 1); + + // Only invalidate the range if the hotspot range has changed... + if (hsStart_ != hsStart || hsEnd_ != hsEnd) { + if (hsStart != -1) { + InvalidateRange(hsStart, hsEnd); + } + hsStart = hsStart_; + hsEnd = hsEnd_; + InvalidateRange(hsStart, hsEnd); + } + } else { + if (hsStart != -1) { + int hsStart_ = hsStart; + int hsEnd_ = hsEnd; + hsStart = -1; + hsEnd = -1; + InvalidateRange(hsStart_, hsEnd_); + } else { + hsStart = -1; + hsEnd = -1; + } + } +} + +void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) { + hsStart_ = hsStart; + hsEnd_ = hsEnd; +} + void Editor::ButtonMove(Point pt) { if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { DwellEnd(true); @@ -4072,6 +4587,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) { @@ -4081,6 +4599,9 @@ void Editor::ButtonMove(Point pt) { } EnsureCaretVisible(false, false, true); + if (hsStart != -1 && !PositionIsHotspot(movePos)) + SetHotSpotRange(NULL); + } else { if (vs.fixedColumnWidth > 0) { // There is a margin if (PointInSelMargin(pt)) { @@ -4089,10 +4610,15 @@ void Editor::ButtonMove(Point pt) { } } // Display regular (drag) cursor over selection - if (PointInSelection(pt)) + if (PointInSelection(pt)) { DisplayCursor(Window::cursorArrow); - else + } else if (PointIsHotspot(pt)) { + DisplayCursor(Window::cursorHand); + SetHotSpotRange(&pt); + } else { DisplayCursor(Window::cursorText); + SetHotSpotRange(NULL); + } } } @@ -4104,6 +4630,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { DisplayCursor(Window::cursorReverseArrow); } else { DisplayCursor(Window::cursorText); + SetHotSpotRange(NULL); } xEndSelect = pt.x - vs.fixedColumnWidth + xOffset; ptMouseLast = pt; @@ -4117,7 +4644,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 +4696,8 @@ void Editor::Tick() { } } if ((dwellDelay < SC_TIME_FOREVER) && - (ticksToDwell > 0) && - (!HaveMouseCapture())) { + (ticksToDwell > 0) && + (!HaveMouseCapture())) { ticksToDwell -= timer.tickSize; if (ticksToDwell <= 0) { dwelling = true; @@ -4185,6 +4712,7 @@ void Editor::SetFocusState(bool focusState) { if (hasFocus) { ShowCaretAtCurrentPosition(); } else { + CancelModes(); DropCaret(); } } @@ -4329,6 +4857,13 @@ void Editor::SetDocPointer(Document *document) { pdoc = document; } pdoc->AddRef(); + + // Ensure all positions within document + currentPos = 0; + anchor = 0; + targetStart = 0; + targetEnd = 0; + // Reset the contraction state to fully shown. cs.Clear(); cs.InsertLines(0, pdoc->LinesTotal() - 1); @@ -4337,7 +4872,10 @@ void Editor::SetDocPointer(Document *document) { pdoc->AddWatcher(this, 0); Redraw(); - SetScrollBars(); + // Removed because of reentrance problems of GTK+ 2.x + // where changing a scroll bar position causes synchronous + // painting before lexer and styling state is set up. + //SetScrollBars(); } // Recursively expand a fold, making lines visible except where they have an unexpanded parent @@ -4407,7 +4945,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 +4982,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 +5006,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 +5019,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 +5136,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 +5170,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 +5206,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 +5321,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 +5410,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 +5517,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 +5530,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,8 +5629,16 @@ 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(wParam <= STYLE_MAX); PLATFORM_ASSERT(lParam); return TextWidth(wParam, CharPtrFromSPtr(lParam)); @@ -5061,7 +5646,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 +5670,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 +5770,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); @@ -5305,6 +5909,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); } break; + case SCI_STYLESETHOTSPOT: + if (wParam <= STYLE_MAX) { + vs.styles[wParam].hotspot = lParam != 0; + InvalidateStyleRedraw(); + } + break; case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); @@ -5412,10 +6022,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 +6080,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 @@ -5516,8 +6128,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: + case SCI_PARADOWN: + case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: + case SCI_PARAUP: + case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: @@ -5530,6 +6146,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: + case SCI_HOMEWRAP: + case SCI_HOMEWRAPEXTEND: + case SCI_LINEENDWRAP: + case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: @@ -5547,6 +6167,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: + case SCI_VCHOMEWRAP: + case SCI_VCHOMEWRAPEXTEND: case SCI_ZOOMIN: case SCI_ZOOMOUT: case SCI_DELWORDLEFT: @@ -5556,6 +6178,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: @@ -5629,12 +6252,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return reinterpret_cast(pdoc); case SCI_SETDOCPOINTER: + CancelModes(); SetDocPointer(reinterpret_cast(lParam)); return 0; case SCI_CREATEDOCUMENT: { Document *doc = new Document(); - doc->AddRef(); + if (doc) { + doc->AddRef(); + } return reinterpret_cast(doc); } @@ -5716,6 +6342,35 @@ 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; + + case SCI_SETHOTSPOTACTIVEFORE: + vs.hotspotForegroundSet = wParam != 0; + vs.hotspotForeground.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + + case SCI_SETHOTSPOTACTIVEBACK: + vs.hotspotBackgroundSet = wParam != 0; + vs.hotspotBackground.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + + case SCI_SETHOTSPOTACTIVEUNDERLINE: + vs.hotspotUnderline = wParam != 0; + 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..2cc7930c47 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 @@ -58,6 +58,10 @@ public: int *positions; char bracePreviousStyles[2]; + // Hotspot support + int hsStart; + int hsEnd; + // Wrapped line support int widthLine; int lines; @@ -131,38 +135,6 @@ public: } }; -/** - * A smart pointer class to ensure Surfaces are set up and deleted correctly. - */ -class AutoSurface { -private: - Surface *surf; -public: - AutoSurface(bool unicodeMode) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(); - surf->SetUnicodeMode(unicodeMode); - } - } - AutoSurface(SurfaceID sid, bool unicodeMode) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(sid); - surf->SetUnicodeMode(unicodeMode); - } - } - ~AutoSurface() { - delete surf; - } - Surface *operator->() const { - return surf; - } - operator Surface *() const { - return surf; - } -}; - /** */ class Editor : public DocWatcher { @@ -184,6 +156,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int printMagnification; int printColourMode; + int printWrapState; int cursorMode; int controlCharSymbol; @@ -196,11 +169,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; @@ -275,6 +252,10 @@ protected: // ScintillaBase subclass needs access to much of Editor int foldFlags; ContractionState cs; + // Hotspot support + int hsStart; + int hsEnd; + // Wrapping support enum { eWrapNone, eWrapWord } wrapState; int wrapWidth; @@ -321,12 +302,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 +321,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, bool inHotspot, 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); @@ -385,6 +376,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, bool shift); + void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); + void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyUpdateUI(); void NotifyPainted(); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); @@ -403,6 +396,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 +450,13 @@ 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); + bool PositionIsHotspot(int position); + bool PointIsHotspot(Point pt); + void SetHotSpotRange(Point *pt); + void GetHotSpotRange(int& hsStart, int& hsEnd); + + int CodePage() const; + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; public: @@ -465,6 +466,45 @@ public: virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); // Public so scintilla_set_id can use it. int ctrlID; + friend class AutoSurface; +}; + +/** + * A smart pointer class to ensure Surfaces are set up and deleted correctly. + */ +class AutoSurface { +private: + Surface *surf; +public: + AutoSurface(Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + AutoSurface(SurfaceID sid, Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(sid, ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + ~AutoSurface() { + delete surf; + } + Surface *operator->() const { + return surf; + } + operator Surface *() const { + return surf; + } }; #endif diff --git a/contrib/src/stc/scintilla/src/KeyMap.cxx b/contrib/src/stc/scintilla/src/KeyMap.cxx index c91e6c6ccc..12249e5f3c 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); } @@ -66,9 +66,13 @@ const KeyToCommand KeyMap::MapDefault[] = { {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_ALT, SCI_PARADOWN}, + {SCK_DOWN, SCI_ASHIFT, SCI_PARADOWNEXTEND}, {SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, + {SCK_UP, SCI_ALT, SCI_PARAUP}, + {SCK_UP, SCI_ASHIFT, SCI_PARAUPEXTEND}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_CTRL, SCI_WORDLEFT}, @@ -109,7 +113,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 +131,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..73ecddf50d 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); @@ -166,6 +171,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmLatex); LINK_LEXER(lmPascal); LINK_LEXER(lmPerl); + LINK_LEXER(lmPOV); LINK_LEXER(lmPython); LINK_LEXER(lmRuby); LINK_LEXER(lmSQL); 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]; + + // Do not leak onto next line + if (initStyle == SCE_AVE_STRINGEOL) { + initStyle = SCE_AVE_DEFAULT; + } - styler.StartAt(startPos); + StyleContext sc(startPos, length, initStyle, styler); - bool fold = styler.GetPropertyInt("fold") != 0; - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + 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); + } - 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); - 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; + // 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); } - 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; + } else if (sc.state == SCE_AVE_ENUM) { + if (!IsEnumChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); } - visibleChars = 0; - } - if (!isspace(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 (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 (state == SCE_AVE_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; + } else if (sc.state == SCE_AVE_COMMENT) { + if (sc.atLineEnd) { + sc.SetState(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 (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); } } - 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; + + // 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(); } } - 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; - } + } + sc.Complete(); +} - 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; - } +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; + char chNext = static_cast(tolower(styler[startPos])); + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + int styleNext = styler.StyleAt(startPos); + char s[10]; - if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0)) - { - chAttr = SCE_AVE_KEYWORD; + for (unsigned int i = startPos; i < lengthDoc; i++) { + 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 (keywords.InList(s)) - { - chAttr = SCE_AVE_WORD; - } + if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { + levelCurrent++; } - 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); + if ((strcmp(s, "end") == 0)) { + levelCurrent--; } } + } 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; + visibleChars = 0; + } + if (!isspacechar(ch)) { + visibleChars++; + } } - 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..263f7da456 100644 --- a/contrib/src/stc/scintilla/src/LexAda.cxx +++ b/contrib/src/stc/scintilla/src/LexAda.cxx @@ -1,198 +1,520 @@ -// 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" + +/* + * Interface + */ + +static void ColouriseDocument( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler); + +static const char * const adaWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc); + +/* + * 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); -inline void classifyWordAda(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; - static const unsigned KEWORD_LEN_MAX = 30; + sc.SetState(SCE_ADA_CHARACTER); - 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])); + // 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(); } - wordLower[i] = '\0'; - -// int levelChange = 0; - char chAttr = SCE_ADA_IDENTIFIER; - if (keywords.InList(wordLower)) { - chAttr = SCE_ADA_WORD; -// 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; + if (!sc.atLineEnd) { + sc.ForwardSetState(SCE_ADA_DEFAULT); + } else { + sc.ChangeState(stateEOL); } - styler.ColourTo(end, chAttr); - -// return levelChange; } +static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { + // Apostrophe meaning is not changed, but the parameter is present for uniformity -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); - } -} - - -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); - - 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; + + StyleContext sc(startPos, length, initStyle, styler); + + int lineCurrent = styler.GetLine(startPos); + bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; + + 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 (!isspacechar(ch)) - // visibleChars++; - if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; + // 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); + } + } + + sc.Complete(); +} + +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; + } - 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); + // 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; } - } else if (state == SCE_ADA_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_ADA_DEFAULT; + } + + 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; } - } 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; + } + + 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; } - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_ADA_STRINGEOL); - state = SCE_ADA_STRINGEOL; + canBeSpecial = true; + + } else if (ch == '#' && canBeSpecial) { + break; + + } else { + return false; } - } 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; + } + + 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 } - } 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); + } + + 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; } - 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); -// } + // if i == length, number was parsed successfully. + return i == length; +} + +static inline bool IsWordCharacter(int ch) { + return IsWordStartCharacter(ch) || isdigit(ch); } -LexerModule lmAda(SCLEX_ADA, ColouriseAdaDoc, "ada"); +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..1eecf9b31a --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexAsm.cxx @@ -0,0 +1,142 @@ +// 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(); +} + +static const char * const asmWordListDesc[] = { + "CPU instructions", + "FPU instructions", + "Registers", + "Directives", + "Directive operands", + 0 +}; + +LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc); + diff --git a/contrib/src/stc/scintilla/src/LexBullant.cxx b/contrib/src/stc/scintilla/src/LexBullant.cxx index 1f76ffcf00..902f89c1e4 100644 --- a/contrib/src/stc/scintilla/src/LexBullant.cxx +++ b/contrib/src/stc/scintilla/src/LexBullant.cxx @@ -30,18 +30,6 @@ static int classifyWordBullant(unsigned int start, unsigned int end, WordList &k else { if (keywords.InList(s)) { chAttr = SCE_C_WORD; -/* if (strcmp(s, "end method") == 0 || - strcmp(s, "end case") == 0 || - strcmp(s, "end class") == 0 || - strcmp(s, "end debug") == 0 || - strcmp(s, "end test") == 0 || - strcmp(s, "end if") == 0 || - strcmp(s, "end lock") == 0 || - strcmp(s, "end transaction") == 0 || - strcmp(s, "end trap") == 0 || - strcmp(s, "end until") == 0 || - strcmp(s, "end while") == 0) - lev = -1;*/ if (strcmp(s, "end") == 0) lev = -1; else if (strcmp(s, "method") == 0 || @@ -80,7 +68,6 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int visibleChars = 0; - // int blockChange = 0; styler.StartSegment(startPos); int endFoundThisLine = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { @@ -230,4 +217,9 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle } } -LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant"); +static const char * const bullantWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc); 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 == '_' || ch >= 161); // _ is not in fact correct CSS word-character +} + +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_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) { + if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\'')) + continue; + unsigned int i = sc.currentPos; + while (i && styler[i-1] == '\\') + i--; + if ((sc.currentPos - i) % 2 == 1) + continue; + sc.ForwardSetState(SCE_CSS_VALUE); + } + + 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_PSEUDOCLASS || 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_ID)) + sc.SetState(SCE_CSS_TAG); + + if (sc.Match('/', '*')) { + lastStateC = sc.state; + sc.SetState(SCE_CSS_COMMENT); + sc.Forward(); + } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) { + sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING)); + } else 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); +} + +static const char * const cssWordListDesc[] = { + "Keywords", + "Pseudo classes", + 0 +}; + +LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexConf.cxx b/contrib/src/stc/scintilla/src/LexConf.cxx index c8441f41ec..c33cdb5ce6 100644 --- a/contrib/src/stc/scintilla/src/LexConf.cxx +++ b/contrib/src/stc/scintilla/src/LexConf.cxx @@ -175,4 +175,10 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k delete []buffer; } -LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf"); +static const char * const confWordListDesc[] = { + "Directives", + "Parameters", + 0 +}; + +LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexCrontab.cxx b/contrib/src/stc/scintilla/src/LexCrontab.cxx index 37729cbfdd..d139bb4f14 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; @@ -208,4 +208,11 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi delete []buffer; } -LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab"); +static const char * const cronWordListDesc[] = { + "Section keywords and Forth words", + "nnCrontab keywords", + "Modifiers", + 0 +}; + +LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexEiffel.cxx b/contrib/src/stc/scintilla/src/LexEiffel.cxx index a0bf26a5ea..974efd9a72 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; } @@ -226,5 +226,10 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent); -LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords); +static const char * const eiffelWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc); +LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc); 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..9cd5433c89 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) { @@ -192,4 +192,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc); +static const char * const lispWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexLua.cxx b/contrib/src/stc/scintilla/src/LexLua.cxx index fc9607e25d..159bc1585d 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; @@ -266,4 +297,14 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc); +static const char * const luaWordListDesc[] = { + "Keywords", + "Basic functions", + "String & math functions", + "I/O & system facilities", + "XXX", + "XXX", + 0 +}; + +LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexMatlab.cxx b/contrib/src/stc/scintilla/src/LexMatlab.cxx index f75d15c7ab..5f4dff3b8e 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. @@ -165,4 +165,9 @@ static void FoldMatlabDoc(unsigned int startPos, int length, int, } } -LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc); +static const char * const matlabWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexOthers.cxx b/contrib/src/stc/scintilla/src/LexOthers.cxx index babb3a0d37..6d537c9b6c 100644 --- a/contrib/src/stc/scintilla/src/LexOthers.cxx +++ b/contrib/src/stc/scintilla/src/LexOthers.cxx @@ -20,6 +20,14 @@ #include "Scintilla.h" #include "SciLexer.h" +static bool Is0To9(char ch) { + return (ch >= '0') && (ch <= '9'); +} + +static bool Is1To9(char ch) { + return (ch >= '1') && (ch <= '9'); +} + static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); @@ -85,7 +93,7 @@ static void ColouriseBatchLine( while (offset < lengthLine) { if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset - 1, state); - if (isdigit(lineBuffer[offset + 1])) { + if (Is0To9(lineBuffer[offset + 1])) { styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); offset += 2; } else if (lineBuffer[offset + 1] == '%' && @@ -164,13 +172,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 +276,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 +303,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 @@ -337,12 +351,17 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[ } } +static bool strstart(char *haystack, char *needle) { + return strncmp(haystack, needle, strlen(needle)) == 0; +} + static void ColouriseErrorListLine( char *lineBuffer, unsigned int lengthLine, // unsigned int startLine, unsigned int endPos, Accessor &styler) { + const int unRecognized = 99; if (lineBuffer[0] == '>') { // Command or return status styler.ColourTo(endPos, SCE_ERR_CMD); @@ -359,10 +378,19 @@ 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 (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { + } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { + styler.ColourTo(endPos, SCE_ERR_PHP); + } else if ((strstart(lineBuffer, "Error ") || + strstart(lineBuffer, "Warning ")) && + strstr(lineBuffer, " at (") && + strstr(lineBuffer, ") : ") && + (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { + // Intel Fortran Compiler error/warning message + styler.ColourTo(endPos, SCE_ERR_IFC); + } else if (strstart(lineBuffer, "Error ")) { // Borland error message styler.ColourTo(endPos, SCE_ERR_BORLAND); - } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { + } else if (strstart(lineBuffer, "Warning ")) { // Borland warning message styler.ColourTo(endPos, SCE_ERR_BORLAND); } else if (strstr(lineBuffer, "at line " ) && @@ -374,54 +402,87 @@ static void ColouriseErrorListLine( } else if (strstr(lineBuffer, " at " ) && (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) && strstr(lineBuffer, " line ") && - (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine))) { + (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && + (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) { // perl error message styler.ColourTo(endPos, SCE_ERR_PERL); } else if ((memcmp(lineBuffer, " at ", 6) == 0) && strstr(lineBuffer, ":line ")) { // A .NET traceback styler.ColourTo(endPos, SCE_ERR_NET); + } else if (strstart(lineBuffer, "Line ") && + strstr(lineBuffer, ", file ")) { + // Essential Lahey Fortran error message + styler.ColourTo(endPos, SCE_ERR_ELF); } else { - // Look for ::message - // Look for (line)message - // Look for (line,pos)message + // Look for GCC ::message + // Look for Microsoft (line) :message + // Look for Microsoft (line,pos)message + // Look for CTags \tmessage int state = 0; for (unsigned int i = 0; i < lengthLine; i++) { - if ((state == 0) && (lineBuffer[i] == ':') && isdigit(lineBuffer[i + 1])) { - state = 1; - } else if ((state == 0) && (lineBuffer[i] == '(')) { - state = 10; - } else if ((state == 0) && (lineBuffer[i] == '\t')) { - state = 20; - } else if ((state == 1) && isdigit(lineBuffer[i])) { - state = 2; - } else if ((state == 2) && (lineBuffer[i] == ':')) { - state = 3; - break; - } else if ((state == 2) && !isdigit(lineBuffer[i])) { - state = 99; - } else if ((state == 10) && isdigit(lineBuffer[i])) { - state = 11; - } else if ((state == 11) && (lineBuffer[i] == ',')) { - state = 14; - } else if ((state == 11) && (lineBuffer[i] == ')')) { - state = 12; - } else if ((state == 12) && (lineBuffer[i] == ':')) { - state = 13; - } else if ((state == 14) && (lineBuffer[i] == ')')) { - state = 15; - break; - } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { - state = 99; - } else if ((state == 20) && (lineBuffer[i-1] == '\t') && - ((lineBuffer[i] == '/' && lineBuffer[i+1] == '^') || isdigit(lineBuffer[i]))) { - state = 24; - break; - } else if ((state == 20) && ((lineBuffer[i] == '/') && (lineBuffer[i+1] == '^'))) { - state = 21; + char ch = lineBuffer[i]; + char chNext = ' '; + if ((i+1) < lengthLine) + chNext = lineBuffer[i+1]; + if (state == 0) { + if (ch == ':') { + // May be GCC + if ((chNext != '\\') && (chNext != '/')) { + // This check is not completely accurate as may be on + // GTK+ with a file name that includes ':'. + state = 1; + } + } else if ((ch == '(') && Is1To9(chNext)) { + // May be Microsoft + // Check againt '0' often removes phone numbers + state = 10; + } else if (ch == '\t') { + // May be CTags + state = 20; + } + } else if (state == 1) { + state = Is1To9(ch) ? 2 : unRecognized; + } else if (state == 2) { + if (ch == ':') { + state = 3; // :9.*: is GCC + break; + } else if (!Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 10) { + state = Is0To9(ch) ? 11 : unRecognized; + } else if (state == 11) { + if (ch == ',') { + state = 14; + } else if (ch == ')') { + state = 12; + } else if ((ch != ' ') && !Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 12) { + if ((ch == ' ') && (chNext == ':')) + state = 13; + else + state = unRecognized; + } else if (state == 14) { + if (ch == ')') { + state = 15; + break; + } else if ((ch != ' ') && !Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 20) { + if ((lineBuffer[i-1] == '\t') && + ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) { + state = 24; + break; + } else if ((ch == '/') && (lineBuffer[i+1] == '^')) { + state = 21; + } } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) { state = 22; - break; + break; } } if (state == 3) { @@ -429,7 +490,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); } @@ -553,12 +614,21 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, } } } - styler.ColourTo(lengthDoc, state); + styler.ColourTo(lengthDoc-1, state); } -LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch"); -LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff"); -LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props"); -LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile"); -LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist"); -LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex"); +static const char * const batchWordListDesc[] = { + "Keywords", + 0 +}; + +static const char * const emptyWordListDesc[] = { + 0 +}; + +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc); +LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", 0, emptyWordListDesc); +LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", 0, emptyWordListDesc); +LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); +LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexPOV.cxx b/contrib/src/stc/scintilla/src/LexPOV.cxx new file mode 100644 index 0000000000..1e44450bbc --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexPOV.cxx @@ -0,0 +1,222 @@ +// Scintilla source code edit control +/** @file LexPOV.cxx + ** Lexer for POV-Ray, based on lexer for C++. + **/ +// Copyright 2003 by Steven te Brinke +// 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" + +#define KEYWORD_BOXHEADER 1 +#define KEYWORD_FOLDCONTRACTED 2 + +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) || ch == '_'); +} + +static inline bool IsStateComment(const int state) { + return ((state == SCE_POV_COMMENT) || + (state == SCE_POV_COMMENTLINE) || + (state == SCE_POV_COMMENTDOC)); +} + +static inline bool IsStateString(const int state) { + return ((state == SCE_POV_STRING)); +} + +static void ColourisePOVDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + + // Do not leak onto next line + /*if (initStyle == SCE_POV_STRINGEOL) + initStyle = SCE_POV_DEFAULT;*/ + + StyleContext sc(startPos, length, initStyle, styler); + + bool caseSensitive = styler.GetPropertyInt("pov.case.sensitive", 1) != 0; + + for (; sc.More(); sc.Forward()) { + + /*if (sc.atLineStart && (sc.state == SCE_POV_STRING)) { + // Prevent SCE_POV_STRINGEOL from leaking back to previous line + sc.SetState(SCE_POV_STRING); + }*/ + + // Handle line continuation generically. + if (sc.ch == '\\') { + if (sc.chNext == '\n' || sc.chNext == '\r') { + sc.Forward(); + if (sc.ch == '\r' && sc.chNext == '\n') { + sc.Forward(); + } + continue; + } + } + + // Determine if the current state should terminate. + if (sc.state == SCE_POV_OPERATOR || sc.state == SCE_POV_BRACE) { + sc.SetState(SCE_POV_DEFAULT); + } else if (sc.state == SCE_POV_NUMBER) { + if (!IsADigit(sc.ch) || sc.ch != '.') { + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { + char s[100]; + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } + if (keywords.InList(s)) { + sc.ChangeState(SCE_POV_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_POV_WORD2); + } + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENT) { + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENTDOC) { + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENTLINE) { + if (sc.atLineEnd) { + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_STRING) { + if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } + + // Determine if a new state should be entered. + if (sc.state == SCE_POV_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_POV_NUMBER); + } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) { + sc.SetState(SCE_POV_IDENTIFIER); + } else if (sc.Match('/', '*')) { + sc.SetState(SCE_POV_COMMENT); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } else if (sc.Match('/', '/')) { + sc.SetState(SCE_POV_COMMENTLINE); + } else if (sc.ch == '\"') { + sc.SetState(SCE_POV_STRING); + //} else if (isoperator(static_cast(sc.ch))) { + } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') { + sc.SetState(SCE_POV_OPERATOR); + } else if (sc.ch == '{' || sc.ch == '}') { + sc.SetState(SCE_POV_BRACE); + } + } + + } + sc.Complete(); +} + +static bool IsStreamCommentStyle(int style) { + return style == SCE_POV_COMMENT || + style == SCE_POV_COMMENTDOC; +} + +static void FoldNoBoxPOVDoc(unsigned int startPos, int length, int initStyle, + Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 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); + int style = initStyle; + 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 (style == SCE_POV_BRACE) { + 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 void FoldPOVDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { + FoldNoBoxPOVDoc(startPos, length, initStyle, styler); +} + +static const char * const POVWordLists[] = { + "Primary keywords and identifiers", + "Secondary keywords and identifiers", + 0, + }; + +static void ColourisePOVDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + ColourisePOVDoc(startPos, length, initStyle, keywordlists, styler); +} + +LexerModule lmPOV(SCLEX_POV, ColourisePOVDocSensitive, "pov", FoldPOVDoc, POVWordLists); diff --git a/contrib/src/stc/scintilla/src/LexPascal.cxx b/contrib/src/stc/scintilla/src/LexPascal.cxx index 37e5e995fb..c3bea6773d 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++; } @@ -339,4 +339,10 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc); +static const char * const pascalWordListDesc[] = { + "Keywords", + "Classwords", + 0 +}; + +LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexPerl.cxx b/contrib/src/stc/scintilla/src/LexPerl.cxx index 1715009c9d..211c3b8751 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", + "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..47974d1bce 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 @@ -409,9 +431,9 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse } static const char * const pythonWordListDesc[] = { - "Python keywords", + "Keywords", 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..43a874968d 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,10 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle, } } } - -LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc); + +static const char * const rubyWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexSQL.cxx b/contrib/src/stc/scintilla/src/LexSQL.cxx index 5af86d9f4a..0520c00ed6 100644 --- a/contrib/src/stc/scintilla/src/LexSQL.cxx +++ b/contrib/src/stc/scintilla/src/LexSQL.cxx @@ -155,4 +155,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, styler.ColourTo(lengthDoc - 1, state); } -LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql"); +static const char * const sqlWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc); diff --git a/contrib/src/stc/scintilla/src/LexVB.cxx b/contrib/src/stc/scintilla/src/LexVB.cxx index bd1248e044..72fdb9c3cf 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); @@ -116,7 +116,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, } else if (sc.ch == '#') { int n = 1; int chSeek = ' '; - while (chSeek == ' ' || chSeek == '\t') { + while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) { chSeek = sc.GetRelative(n); n++; } @@ -137,7 +137,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_B_OPERATOR); } } - + if (sc.atLineEnd) { visibleChars = 0; } @@ -200,6 +200,11 @@ static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyl ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true); } -LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc); -LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc); +static const char * const vbWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc); +LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc); 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..ef5924f751 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,35 @@ 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); + delete pxpm; + 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..18544aef23 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')) @@ -181,7 +185,8 @@ SString PropSet::GetExpanded(const char *key) { SString PropSet::Expand(const char *withVars) { char *base = StringDup(withVars); char *cpvar = strstr(base, "$("); - while (cpvar) { + int maxExpands = 1000; // Avoid infinite expansion of recursive definitions + while (cpvar && (maxExpands > 0)) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() @@ -197,6 +202,7 @@ SString PropSet::Expand(const char *withVars) { base = newbase; } cpvar = strstr(base, "$("); + maxExpands--; } SString sret = base; delete []base; @@ -257,7 +263,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); @@ -300,7 +306,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) { SString PropSet::GetNewExpand(const char *keybase, const char *filename) { char *base = StringDup(GetWild(keybase, filename).c_str()); char *cpvar = strstr(base, "$("); - while (cpvar) { + int maxExpands = 1000; // Avoid infinite expansion of recursive definitions + while (cpvar && (maxExpands > 0)) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() @@ -316,6 +323,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { base = newbase; } cpvar = strstr(base, "$("); + maxExpands--; } SString sret = base; delete []base; @@ -328,9 +336,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 +634,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 +677,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 +703,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..656570a24b 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,23 @@ * Modification history: * * $Log$ - * Revision 1.5 2002/09/11 00:55:27 RD - * Update to Scintilla 1.48 + * Revision 1.6 2003/04/19 19:59:49 RD + * Updated Scintilla to 1.52 (on the trunk this time too) + * + * Revision 1.9 2003/03/21 10:36:08 nyamatongwe + * Detect patterns too long in regular expression search. + * + * Revision 1.8 2003/03/04 10:53:59 nyamatongwe + * Patch from Jakub to optionally implement more POSIX compatible regular + * expressions. \(..\) changes to (..) + * Fixes problem where find previous would not find earlier matches on same + * line. + * + * Revision 1.8 2003/03/03 20:12:56 vrana + * Added posix syntax. + * + * 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 +82,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 +122,7 @@ * void re_fail(msg, op) * char *msg; * char op; - * + * * Regular Expressions: * * [1] char matches itself, unless it is a special @@ -117,20 +132,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 +210,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 +221,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 +269,7 @@ const char bitarr[] = {1,2,4,8,16,32,64,'\200'}; #define badpat(x) (*nfa = END, x) - + RESearch::RESearch() { Init(); } @@ -332,10 +347,11 @@ const char escapeValue(char ch) { return 0; } -const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { +const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) { char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer.. */ char *sp=nfa; /* another one.. */ + char *mpMax = mp + MAXNFA - BITBLK - 10; int tagi = 0; /* tag stack index */ int tagc = 1; /* actual tag count */ @@ -343,7 +359,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; @@ -353,6 +369,8 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { const char *p=pat; /* pattern pointer */ for (int i=0; i mpMax) + return badpat("Pattern too long"); lp = mp; switch(*p) { @@ -383,7 +401,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; if (*++p == '^') { - mask = '\377'; + mask = '\377'; i++; p++; } else @@ -427,7 +445,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.. */ @@ -467,25 +485,6 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; switch(*++p) { - case '(': - if (tagc < MAXTAG) { - tagstk[++tagi] = tagc; - *mp++ = BOT; - *mp++ = static_cast(tagc++); - } - else - return badpat("Too many \\(\\) pairs"); - break; - case ')': - if (*sp == BOT) - return badpat("Null pattern inside \\(\\)"); - if (tagi > 0) { - *mp++ = static_cast(EOT); - *mp++ = static_cast(tagstk[tagi--]); - } - else - return badpat("Unmatched \\)"); - break; case '<': *mp++ = BOW; break; @@ -524,13 +523,49 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { *mp++ = escapeValue(*p); break; default: - *mp++ = CHR; - *mp++ = *p; + if (!posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast(tagc++); + } + else + return badpat("Too many \\(\\) pairs"); + } else if (!posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside \\(\\)"); + if (tagi > 0) { + *mp++ = static_cast(EOT); + *mp++ = static_cast(tagstk[tagi--]); + } + else + return badpat("Unmatched \\)"); + } else { + *mp++ = CHR; + *mp++ = *p; + } } break; default : /* an ordinary char */ - if (caseSensitive) { + if (posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast(tagc++); + } + else + return badpat("Too many () pairs"); + } else if (posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside ()"); + if (tagi > 0) { + *mp++ = static_cast(EOT); + *mp++ = static_cast(tagstk[tagi--]); + } + else + return badpat("Unmatched )"); + } else if (caseSensitive) { *mp++ = CHR; *mp++ = *p; } else { @@ -545,7 +580,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { sp = lp; } if (tagi > 0) - return badpat("Unmatched \\("); + return badpat((posix ? "Unmatched (" : "Unmatched \\(")); *mp = END; sta = OKP; return 0; @@ -555,7 +590,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 +615,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { bol = lp; failure = 0; - + Clear(); switch(*ap) { @@ -621,7 +656,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 +682,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 +693,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 +723,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 +831,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 +881,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..d676e0f318 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; }; @@ -32,7 +32,7 @@ public: bool GrabMatches(CharacterIndexer &ci); void ChSet(char c); void ChSetWithCase(char c, bool caseSensitive); - const char *Compile(const char *pat, int length, bool caseSensitive); + const char *Compile(const char *pat, int length, bool caseSensitive, bool posix); int Execute(CharacterIndexer &ci, int lp, int endp); void ModifyWord(char *s); int Substitute(CharacterIndexer &ci, char *src, char *dst); 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..ea2e2d1d6d 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,11 @@ void ScintillaBase::AutoCompleteCharacterDeleted() { } void ScintillaBase::AutoCompleteCompleted() { - int item = ac.lb.GetSelection(); + int item = ac.lb->GetSelection(); char selected[1000]; + selected[0] = '\0'; if (item != -1) { - ac.lb.GetValue(item, selected, sizeof(selected)); + ac.lb->GetValue(item, selected, sizeof(selected)); } ac.Cancel(); @@ -343,6 +345,36 @@ void ScintillaBase::AutoCompleteCompleted() { pdoc->EndUndoAction(); } +void ScintillaBase::CallTipShow(Point pt, const char *defn) { + AutoCompleteCancel(); + pt.y += vs.lineHeight; + PRectangle rc = ct.CallTipStart(currentPos, pt, + defn, + vs.styles[STYLE_DEFAULT].fontName, + vs.styles[STYLE_DEFAULT].sizeZoomed, + IsUnicodeMode(), + wMain); + // If the call-tip window would be out of the client + // space, adjust so it displays above the text. + PRectangle rcClient = GetClientRectangle(); + if (rc.bottom > rcClient.bottom) { + int offset = vs.lineHeight + rc.Height(); + rc.top -= offset; + rc.bottom -= offset; + } + // Now display the window. + CreateCallTipWindow(rc); + ct.wCallTip.SetPositionRelative(rc, wMain); + ct.wCallTip.Show(); +} + +void ScintillaBase::CallTipClick() { + SCNotification scn; + scn.nmhdr.code = SCN_CALLTIPCLICK; + scn.position = ct.clickPlace; + NotifyParent(scn); +} + void ScintillaBase::ContextMenu(Point pt) { if (displayPopupMenu) { bool writable = !WndProc(SCI_GETREADONLY, 0, 0); @@ -509,30 +541,24 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara case SCI_AUTOCGETDROPRESTOFWORD: return ac.dropRestOfWord; - case SCI_CALLTIPSHOW: { - AutoCompleteCancel(); - if (!ct.wCallTip.Created()) { - Point pt = LocationFromPosition(wParam); - pt.y += vs.lineHeight; - PRectangle rc = ct.CallTipStart(currentPos, pt, - reinterpret_cast(lParam), - vs.styles[STYLE_DEFAULT].fontName, - vs.styles[STYLE_DEFAULT].sizeZoomed, - IsUnicodeMode()); - // If the call-tip window would be out of the client - // space, adjust so it displays above the text. - PRectangle rcClient = GetClientRectangle(); - if (rc.bottom > rcClient.bottom) { - int offset = vs.lineHeight + rc.Height(); - rc.top -= offset; - rc.bottom -= offset; - } - // Now display the window. - CreateCallTipWindow(rc); - ct.wCallTip.SetPositionRelative(rc, wMain); - ct.wCallTip.Show(); - } - } + 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: + CallTipShow(LocationFromPosition(wParam), + reinterpret_cast(lParam)); break; case SCI_CALLTIPCANCEL: @@ -554,6 +580,16 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara InvalidateStyleRedraw(); break; + case SCI_CALLTIPSETFORE: + ct.colourUnSel = ColourDesired(wParam); + InvalidateStyleRedraw(); + break; + + case SCI_CALLTIPSETFOREHLT: + ct.colourSel = ColourDesired(wParam); + InvalidateStyleRedraw(); + break; + case SCI_USEPOPUP: displayPopupMenu = wParam != 0; break; diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.h b/contrib/src/stc/scintilla/src/ScintillaBase.h index e68aeb6084..bf0b92d57d 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); @@ -71,6 +71,8 @@ protected: void AutoCompleteMoveToCurrentWord(); static void AutoCompleteDoubleClick(void* p); + void CallTipClick(); + void CallTipShow(Point pt, const char *defn); virtual void CreateCallTipWindow(PRectangle rc) = 0; virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; diff --git a/contrib/src/stc/scintilla/src/Style.cxx b/contrib/src/stc/scintilla/src/Style.cxx index 2ee09f57d2..40a8dba6a4 100644 --- a/contrib/src/stc/scintilla/src/Style.cxx +++ b/contrib/src/stc/scintilla/src/Style.cxx @@ -16,13 +16,13 @@ Style::Style() { aliasOfDefaultFont = true; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); } Style::Style(const Style &source) { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, 0, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -34,6 +34,7 @@ Style::Style(const Style &source) { caseForce = source.caseForce; visible = source.visible; changeable = source.changeable; + hotspot = source.hotspot; } Style::~Style() { @@ -49,7 +50,7 @@ Style &Style::operator=(const Style &source) { return * this; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -66,9 +67,9 @@ 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 visible_, bool changeable_) { + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, + bool visible_, bool changeable_, bool hotspot_) { fore.desired = fore_; back.desired = back_; characterSet = characterSet_; @@ -81,6 +82,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, caseForce = caseForce_; visible = visible_; changeable = changeable_; + hotspot = hotspot_; if (aliasOfDefaultFont) font.SetID(0); else @@ -100,8 +102,9 @@ void Style::ClearTo(const Style &source) { source.eolFilled, source.underline, source.caseForce, - source.visible, - source.changeable); + source.visible, + source.changeable, + source.hotspot); } bool Style::EquivalentFontTo(const Style *other) const { diff --git a/contrib/src/stc/scintilla/src/Style.h b/contrib/src/stc/scintilla/src/Style.h index 63259b1a93..2f1e575860 100644 --- a/contrib/src/stc/scintilla/src/Style.h +++ b/contrib/src/stc/scintilla/src/Style.h @@ -26,6 +26,7 @@ public: ecaseForced caseForce; bool visible; bool changeable; + bool hotspot; Font font; int sizeZoomed; @@ -43,13 +44,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 visible_, bool changeable_); + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, + bool visible_, bool changeable_, bool hotspot_); 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..f2f8305c94 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 + ((ch >= 0x100) ? 1 : 0)); } 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..eb8e54f2f8 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,18 @@ 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; + + hotspotForegroundSet = source.hotspotForegroundSet; + hotspotForeground.desired = source.hotspotForeground.desired; + hotspotBackgroundSet = source.hotspotBackgroundSet; + hotspotBackground.desired = source.hotspotBackground.desired; + hotspotUnderline = source.hotspotUnderline; + whitespaceForegroundSet = source.whitespaceForegroundSet; whitespaceForeground.desired = source.whitespaceForeground.desired; whitespaceBackgroundSet = source.whitespaceBackgroundSet; @@ -124,6 +137,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 +157,13 @@ void ViewStyle::Init() { edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0); edgeState = EDGE_NONE; caretWidth = 1; + someStylesProtected = false; + + hotspotForegroundSet = false; + hotspotForeground.desired = ColourDesired(0, 0, 0xff); + hotspotBackgroundSet = false; + hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff); + hotspotUnderline = true; leftMarginWidth = 1; rightMarginWidth = 1; @@ -148,9 +174,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 +202,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); @@ -191,6 +218,8 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(caretcolour, want); pal.WantFind(caretLineBackground, want); pal.WantFind(edgecolour, want); + pal.WantFind(hotspotForeground, want); + pal.WantFind(hotspotBackground, want); } void ViewStyle::Refresh(Surface &surface) { @@ -199,6 +228,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 +237,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,11 +258,11 @@ 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, - false, false, false, false, Style::caseMixed, true, true); + false, false, false, false, Style::caseMixed, true, true, false); } void ViewStyle::ClearStyles() { @@ -245,3 +278,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..ff38efef2e 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.h +++ b/contrib/src/stc/scintilla/src/ViewStyle.h @@ -59,6 +59,15 @@ public: ColourPair whitespaceBackground; ColourPair selbar; ColourPair selbarlight; + bool foldmarginColourSet; + ColourPair foldmarginColour; + bool foldmarginHighlightColourSet; + ColourPair foldmarginHighlightColour; + bool hotspotForegroundSet; + ColourPair hotspotForeground; + bool hotspotBackgroundSet; + ColourPair hotspotBackground; + bool hotspotUnderline; /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin enum { margins=3 }; int leftMarginWidth; ///< Spacing margin on left of text @@ -78,7 +87,8 @@ public: ColourPair edgecolour; int edgeState; int caretWidth; - + bool someStylesProtected; + ViewStyle(); ViewStyle(const ViewStyle &source); ~ViewStyle(); @@ -88,6 +98,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..c4a9d0c4e1 100644 --- a/contrib/src/stc/stc.cpp +++ b/contrib/src/stc/stc.cpp @@ -20,7 +20,10 @@ #include "wx/stc/stc.h" #include "ScintillaWX.h" +#include #include +#include +#include //---------------------------------------------------------------------- @@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG ) DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER ) DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP ) DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK ) + BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) @@ -201,7 +208,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 +223,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 +250,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 +300,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 +328,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 +406,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 +462,21 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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); @@ -555,6 +577,11 @@ void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet) { SendMsg(2066, style, characterSet); } +// Set a style to be a hotspot or not. +void wxStyledTextCtrl::StyleSetHotSpot(int style, bool hotspot) { + SendMsg(2409, style, hotspot); +} + // Set the foreground colour of the selection and whether to use this setting. void wxStyledTextCtrl::SetSelForeground(bool useSetting, const wxColour& fore) { SendMsg(2067, useSetting, wxColourAsLong(fore)); @@ -572,12 +599,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 +614,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 +845,37 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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 +1016,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; - - 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); -} - -// Retrieve the line at the top of the display. + 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; + + return SendMsg(2151, doDraw, (long)&fr); +} + +// 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 +1113,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 +1231,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 +1291,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 +1303,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. @@ -1299,6 +1357,16 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& back) { SendMsg(2205, wxColourAsLong(back), 0); } +// Set the foreground colour for the call tip. +void wxStyledTextCtrl::CallTipSetForeground(const wxColour& fore) { + SendMsg(2206, wxColourAsLong(fore), 0); +} + +// Set the foreground colour for the highlighted part of the call tip. +void wxStyledTextCtrl::CallTipSetForegroundHighlight(const wxColour& fore) { + SendMsg(2207, wxColourAsLong(fore), 0); +} + // Find the display line of a document line taking hidden lines into account. int wxStyledTextCtrl::VisibleFromDocLine(int line) { return SendMsg(2220, line, 0); @@ -1366,7 +1434,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 +1540,61 @@ 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. +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 +1654,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 +1747,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 +1862,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 +1879,31 @@ 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); +} + +// Set a fore colour for active hotspots. +void wxStyledTextCtrl::SetHotspotActiveForeground(bool useSetting, const wxColour& fore) { + SendMsg(2410, useSetting, wxColourAsLong(fore)); +} + +// Set a back colour for active hotspots. +void wxStyledTextCtrl::SetHotspotActiveBackground(bool useSetting, const wxColour& back) { + SendMsg(2411, useSetting, wxColourAsLong(back)); +} + +// Enable / Disable underlining active hotspots. +void wxStyledTextCtrl::SetHotspotActiveUnderline(bool underline) { + SendMsg(2412, underline, 0); +} + // Start notifying the container of all key presses and commands. void wxStyledTextCtrl::StartRecord() { SendMsg(3001, 0, 0); @@ -1928,9 +2081,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) { @@ -2196,6 +2347,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetEventType(wxEVT_STC_ZOOM); break; + case SCN_HOTSPOTCLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK); + break; + + case SCN_HOTSPOTDOUBLECLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK); + break; + + case SCN_CALLTIPCLICK: + evt.SetEventType(wxEVT_STC_CALLTIP_CLICK); + break; + default: return; } diff --git a/contrib/src/stc/stc.cpp.in b/contrib/src/stc/stc.cpp.in index 0ab9afdc5e..6643474798 100644 --- a/contrib/src/stc/stc.cpp.in +++ b/contrib/src/stc/stc.cpp.in @@ -20,7 +20,10 @@ #include "wx/stc/stc.h" #include "ScintillaWX.h" +#include #include +#include +#include //---------------------------------------------------------------------- @@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG ) DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER ) DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP ) DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK ) + BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) @@ -306,9 +313,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) { @@ -574,6 +579,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetEventType(wxEVT_STC_ZOOM); break; + case SCN_HOTSPOTCLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK); + break; + + case SCN_HOTSPOTDOUBLECLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK); + break; + + case SCN_CALLTIPCLICK: + evt.SetEventType(wxEVT_STC_CALLTIP_CLICK); + break; + default: return; } diff --git a/contrib/src/stc/stc.h.in b/contrib/src/stc/stc.h.in index 7a54289b2c..baeaf0d437 100644 --- a/contrib/src/stc/stc.h.in +++ b/contrib/src/stc/stc.h.in @@ -225,11 +225,11 @@ private: void NotifyChange(); void NotifyParent(SCNotification* scn); - -private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxStyledTextCtrl) +protected: + ScintillaWX* m_swx; wxStopWatch m_stopWatch; wxScrollBar* m_vScrollBar; @@ -348,6 +348,8 @@ private: #endif }; + + #ifndef SWIG BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650) @@ -373,6 +375,9 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER, 1670) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP, 1671) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM, 1672) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK, 1673) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK, 1674) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK, 1675) END_DECLARE_EVENT_TYPES() #else enum { @@ -399,6 +404,9 @@ END_DECLARE_EVENT_TYPES() wxEVT_STC_DRAG_OVER, wxEVT_STC_DO_DROP, wxEVT_STC_ZOOM, + wxEVT_STC_HOTSPOT_CLICK, + wxEVT_STC_HOTSPOT_DCLICK, + wxEVT_STC_CALLTIP_CLICK }; #endif @@ -430,6 +438,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&); #define EVT_STC_DRAG_OVER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_DO_DROP(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_ZOOM(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), + #endif //---------------------------------------------------------------------- diff --git a/include/wx/stc/stc.h b/include/wx/stc/stc.h index 096949085a..41e36f3e8b 100644 --- a/include/wx/stc/stc.h +++ b/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. @@ -185,10 +189,21 @@ #define wxSTC_FIND_MATCHCASE 4 #define wxSTC_FIND_WORDSTART 0x00100000 #define wxSTC_FIND_REGEXP 0x00200000 +#define wxSTC_FIND_POSIX 0x00400000 #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 +215,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 +323,12 @@ #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 +#define wxSTC_LEX_POV 39 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a // value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -576,6 +597,9 @@ #define wxSTC_ERR_DIFF_ADDITION 11 #define wxSTC_ERR_DIFF_DELETION 12 #define wxSTC_ERR_DIFF_MESSAGE 13 +#define wxSTC_ERR_PHP 14 +#define wxSTC_ERR_ELF 15 +#define wxSTC_ERR_IFC 16 // Lexical states for SCLEX_BATCH #define wxSTC_BAT_DEFAULT 0 @@ -622,24 +646,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 +751,66 @@ #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 +#define wxSTC_CSS_DOUBLESTRING 13 +#define wxSTC_CSS_SINGLESTRING 14 + +// Lexical states for SCLEX_POV +#define wxSTC_POV_DEFAULT 0 +#define wxSTC_POV_COMMENT 1 +#define wxSTC_POV_COMMENTLINE 2 +#define wxSTC_POV_COMMENTDOC 3 +#define wxSTC_POV_NUMBER 4 +#define wxSTC_POV_WORD 5 +#define wxSTC_POV_STRING 6 +#define wxSTC_POV_OPERATOR 7 +#define wxSTC_POV_IDENTIFIER 8 +#define wxSTC_POV_BRACE 9 +#define wxSTC_POV_WORD2 10 + //----------------------------------------- // Commands that can be bound to keystrokes @@ -867,6 +958,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 @@ -897,6 +991,18 @@ // caret position. #define wxSTC_CMD_LINEENDDISPLAYEXTEND 2348 +// These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? +// except they behave differently when word-wrap is enabled: +// They go first to the start / end of the display line, like (Home|LineEnd)Display +// The difference is that, the cursor is already at the point, it goes on to the start +// or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend. +#define wxSTC_CMD_HOMEWRAP 2349 +#define wxSTC_CMD_HOMEWRAPEXTEND 2450 +#define wxSTC_CMD_LINEENDWRAP 2451 +#define wxSTC_CMD_LINEENDWRAPEXTEND 2452 +#define wxSTC_CMD_VCHOMEWRAP 2453 +#define wxSTC_CMD_VCHOMEWRAPEXTEND 2454 + // Move to the previous change in capitalisation. #define wxSTC_CMD_WORDPARTLEFT 2390 @@ -917,6 +1023,12 @@ // Delete forwards from the current position to the end of the line. #define wxSTC_CMD_DELLINERIGHT 2396 +// Move caret between paragraphs (delimited by empty lines) +#define wxSTC_CMD_PARADOWN 2413 +#define wxSTC_CMD_PARADOWNEXTEND 2414 +#define wxSTC_CMD_PARAUP 2415 +#define wxSTC_CMD_PARAUPEXTEND 2416 + // END of generated section //---------------------------------------------------------------------- @@ -1091,8 +1203,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 +1230,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); @@ -1178,6 +1293,9 @@ public: // Set the character set of the font in a style. void StyleSetCharacterSet(int style, int characterSet); + // Set a style to be a hotspot or not. + void StyleSetHotSpot(int style, bool hotspot); + // Set the foreground colour of the selection and whether to use this setting. void SetSelForeground(bool useSetting, const wxColour& fore); @@ -1339,6 +1457,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 +1558,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); - - // Retrieve the line at the top of the display. + int startPos, + int endPos, + wxDC* draw, + wxDC* target, // Why does it use two? Can they be the same? + wxRect renderRect, + wxRect pageRect); + + // Retrieve the display line at the top of the display. int GetFirstVisibleLine(); // Retrieve the contents of a line. @@ -1589,6 +1720,12 @@ public: // Set the background colour for the call tip. void CallTipSetBackground(const wxColour& back); + // Set the foreground colour for the call tip. + void CallTipSetForeground(const wxColour& fore); + + // Set the foreground colour for the highlighted part of the call tip. + void CallTipSetForegroundHighlight(const wxColour& fore); + // Find the display line of a document line taking hidden lines into account. int VisibleFromDocLine(int line); @@ -1630,7 +1767,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 +1833,39 @@ 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. + 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 +2030,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 +2041,21 @@ 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(); + + // Set a fore colour for active hotspots. + void SetHotspotActiveForeground(bool useSetting, const wxColour& fore); + + // Set a back colour for active hotspots. + void SetHotspotActiveBackground(bool useSetting, const wxColour& back); + + // Enable / Disable underlining active hotspots. + void SetHotspotActiveUnderline(bool underline); + // Start notifying the container of all key presses and commands. void StartRecord(); @@ -2005,11 +2193,11 @@ private: void NotifyChange(); void NotifyParent(SCNotification* scn); - -private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxStyledTextCtrl) +protected: + ScintillaWX* m_swx; wxStopWatch m_stopWatch; wxScrollBar* m_vScrollBar; @@ -2128,6 +2316,8 @@ private: #endif }; + + #ifndef SWIG BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650) @@ -2153,6 +2343,9 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER, 1670) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP, 1671) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM, 1672) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK, 1673) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK, 1674) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK, 1675) END_DECLARE_EVENT_TYPES() #else enum { @@ -2179,6 +2372,9 @@ END_DECLARE_EVENT_TYPES() wxEVT_STC_DRAG_OVER, wxEVT_STC_DO_DROP, wxEVT_STC_ZOOM, + wxEVT_STC_HOTSPOT_CLICK, + wxEVT_STC_HOTSPOT_DCLICK, + wxEVT_STC_CALLTIP_CLICK }; #endif @@ -2210,6 +2406,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&); #define EVT_STC_DRAG_OVER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_DO_DROP(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_ZOOM(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), + #endif //---------------------------------------------------------------------- diff --git a/samples/stc/stctest.cpp b/samples/stc/stctest.cpp index 578044d546..538d00ef98 100644 --- a/samples/stc/stctest.cpp +++ b/samples/stc/stctest.cpp @@ -40,7 +40,26 @@ public: }; //---------------------------------------------------------------------- +// Make an editor class +class MySTC : public wxStyledTextCtrl +{ +public: + MySTC(wxWindow *parent, wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0); + + void OnKeyPressed(wxKeyEvent& evt); + +private: + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(MySTC, wxStyledTextCtrl) + EVT_KEY_DOWN(MySTC::OnKeyPressed) +END_EVENT_TABLE() + +//---------------------------------------------------------------------- // Define a new frame type: this is going to be our main frame class MyFrame : public wxFrame { @@ -51,7 +70,7 @@ public: void OnAbout(wxCommandEvent& event); private: - wxStyledTextCtrl* ed; + MySTC* ed; DECLARE_EVENT_TABLE() }; @@ -79,7 +98,7 @@ IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { MyFrame *frame = new MyFrame(_T("Testing wxStyledTextCtrl"), - wxPoint(5, 5), wxSize(400, 600)); + wxPoint(5, 5), wxSize(600, 600)); frame->Show(TRUE); return TRUE; @@ -123,32 +142,71 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) //---------------------------------------- // Setup the editor - ed = new wxStyledTextCtrl(this, ID_ED); + ed = new MySTC(this, ID_ED); +} + + +// event handlers + +void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) +{ + // TRUE is to force the frame to close + Close(TRUE); +} + +void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ + wxString msg; + msg.Printf( _T("Testing wxStyledTextCtrl...\n")); + wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this); +} + + +//---------------------------------------------------------------------- + +wxChar* keywords = +_T("asm auto bool break case catch char class const \ +const_cast continue default delete do double \ +dynamic_cast else enum explicit export extern \ +false float for friend goto if inline int long \ +mutable namespace new operator private protected \ +public register reinterpret_cast return short signed \ +sizeof static static_cast struct switch template this \ +throw true try typedef typeid typename union unsigned \ +using virtual void volatile wchar_t while"); + + + +MySTC::MySTC(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style) + : wxStyledTextCtrl(parent, id, pos, size, style) +{ // Default font wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL); - ed->StyleSetFont(wxSTC_STYLE_DEFAULT, font); - ed->StyleClearAll(); - - ed->StyleSetForeground(0, wxColour(0x80, 0x80, 0x80)); - ed->StyleSetForeground(1, wxColour(0x00, 0x7f, 0x00)); - //ed->StyleSetForeground(2, wxColour(0x00, 0x7f, 0x00)); - ed->StyleSetForeground(3, wxColour(0x7f, 0x7f, 0x7f)); - ed->StyleSetForeground(4, wxColour(0x00, 0x7f, 0x7f)); - ed->StyleSetForeground(5, wxColour(0x00, 0x00, 0x7f)); - ed->StyleSetForeground(6, wxColour(0x7f, 0x00, 0x7f)); - ed->StyleSetForeground(7, wxColour(0x7f, 0x00, 0x7f)); - ed->StyleSetForeground(8, wxColour(0x00, 0x7f, 0x7f)); - ed->StyleSetForeground(9, wxColour(0x7f, 0x7f, 0x7f)); - ed->StyleSetForeground(10, wxColour(0x00, 0x00, 0x00)); - ed->StyleSetForeground(11, wxColour(0x00, 0x00, 0x00)); - ed->StyleSetBold(5, TRUE); - ed->StyleSetBold(10, TRUE); + StyleSetFont(wxSTC_STYLE_DEFAULT, font); + StyleClearAll(); + + StyleSetForeground(0, wxColour(0x80, 0x80, 0x80)); + StyleSetForeground(1, wxColour(0x00, 0x7f, 0x00)); + //StyleSetForeground(2, wxColour(0x00, 0x7f, 0x00)); + StyleSetForeground(3, wxColour(0x7f, 0x7f, 0x7f)); + StyleSetForeground(4, wxColour(0x00, 0x7f, 0x7f)); + StyleSetForeground(5, wxColour(0x00, 0x00, 0x7f)); + StyleSetForeground(6, wxColour(0x7f, 0x00, 0x7f)); + StyleSetForeground(7, wxColour(0x7f, 0x00, 0x7f)); + StyleSetForeground(8, wxColour(0x00, 0x7f, 0x7f)); + StyleSetForeground(9, wxColour(0x7f, 0x7f, 0x7f)); + StyleSetForeground(10, wxColour(0x00, 0x00, 0x00)); + StyleSetForeground(11, wxColour(0x00, 0x00, 0x00)); + StyleSetBold(5, TRUE); + StyleSetBold(10, TRUE); #ifdef __WXMSW__ - ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9")); + StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9")); #else - ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9")); + StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9")); #endif // give it some text to play with @@ -161,36 +219,36 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) st = wxString::FromAscii(buf); delete[] buf; - ed->InsertText(0, st); - ed->EmptyUndoBuffer(); + InsertText(0, st); + EmptyUndoBuffer(); - ed->SetLexer(wxSTC_LEX_CPP); - ed->SetKeyWords(0, -_T("asm auto bool break case catch char class const \ -const_cast continue default delete do double \ -dynamic_cast else enum explicit export extern \ -false float for friend goto if inline int long \ -mutable namespace new operator private protected \ -public register reinterpret_cast return short signed \ -sizeof static static_cast struct switch template this \ -throw true try typedef typeid typename union unsigned \ -using virtual void volatile wchar_t while")); - -} - - -// event handlers - -void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) -{ - // TRUE is to force the frame to close - Close(TRUE); + SetLexer(wxSTC_LEX_CPP); + SetKeyWords(0, keywords); } -void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +void MySTC::OnKeyPressed(wxKeyEvent& evt) { - wxString msg; - msg.Printf( _T("Testing wxStyledTextCtrl...\n")); - - wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this); + if (CallTipActive()) + CallTipCancel(); + + int key = evt.GetKeyCode(); + if ( key == WXK_SPACE && evt.ControlDown()) { + int pos = GetCurrentPos(); + + if (evt.ShiftDown()) { + // show how to do CallTips + CallTipSetBackground(wxColour(_T("YELLOW"))); + CallTipShow(pos, _T("lots of of text: blah, blah, blah\n\n" + "show some suff, maybe parameters..\n\n" + "fubar(param1, param2)")); + } + else { + // show how to do AutoComplete + AutoCompSetIgnoreCase(false); + AutoCompShow(0, keywords); // reuse the keyword list here + // normally you would build a string of completion texts... + } + } + else + evt.Skip(); } diff --git a/src/stc/Makefile.in b/src/stc/Makefile.in index 042da17f87..9df25a3db2 100644 --- a/src/stc/Makefile.in +++ b/src/stc/Makefile.in @@ -34,18 +34,22 @@ 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 \ LexOthers.o \ + LexPOV.o \ LexPascal.o \ LexPerl.o \ LexPython.o \ @@ -61,6 +65,8 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ UniConversion.o \ ViewStyle.o \ WindowAccessor.o \ + XPM.o \ + DEPFILES=$(OBJECTS:.o=.d) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index fbf1faf2a3..80f8f795ce 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -8,7 +8,10 @@ #include #include - +#include +#include +#include +#include #include "Platform.h" #include "PlatWX.h" @@ -189,9 +192,6 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b false, stc2wx(faceName), encoding); -#ifdef __WXMAC__ - ((wxFont*)id)->SetNoAntiAliasing( true ) ; -#endif } @@ -216,42 +216,44 @@ public: SurfaceImpl(); ~SurfaceImpl(); - void Init(); - void Init(SurfaceID sid); - 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); - - 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_); - - int SetPalette(Palette *pal, bool inBackGround); - void SetClip(PRectangle rc); - void FlushCachedState(); - - void SetUnicodeMode(bool unicodeMode_); + virtual void Init(WindowID wid); + virtual void Init(SurfaceID sid, WindowID wid); + virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid); + + 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); + + 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_); + + virtual int SetPalette(Palette *pal, bool inBackGround); + virtual void SetClip(PRectangle rc); + virtual void FlushCachedState(); + + virtual void SetUnicodeMode(bool unicodeMode_); + virtual void SetDBCSMode(int codePage); void BrushColour(ColourAllocated back); void SetFont(Font &font_); @@ -268,25 +270,7 @@ 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() { +void SurfaceImpl::Init(WindowID wid) { #if 0 Release(); hdc = new wxMemoryDC(); @@ -295,16 +279,16 @@ void SurfaceImpl::Init() { // On Mac and GTK the DC is not really valid until it has a bitmap // selected into it. So instead of just creating the DC with no bitmap, // go ahead and give it one. - InitPixMap(1,1,NULL); + InitPixMap(1,1,NULL,wid); #endif } -void SurfaceImpl::Init(SurfaceID hdc_) { +void SurfaceImpl::Init(SurfaceID hdc_, WindowID) { Release(); hdc = (wxDC*)hdc_; } -void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) { +void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID) { Release(); hdc = new wxMemoryDC(); hdcOwned = true; @@ -314,6 +298,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)); } @@ -401,7 +405,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... @@ -414,28 +418,36 @@ 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) { + +void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase, + const char *s, int len, + ColourAllocated fore) { + SetFont(font); - int w; - int h; + hdc->SetTextForeground(wxColourFromCA(fore)); + hdc->SetBackgroundMode(wxTRANSPARENT); - hdc->GetTextExtent(stc2wx(s, len), &w, &h); - return w; + // 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); } void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) { + wxString str = stc2wx(s, len); SetFont(font); +#ifndef __WXMAC__ // Calculate the position of each character based on the widths of // the previous characters int* tpos = new int[len]; @@ -447,9 +459,26 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio totalWidth += w; tpos[i] = totalWidth; } +#else + // 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 necessarily + // (and probably not) the same as the whole string width. + int* tpos = new int[len]; + size_t i; + for (i=0; iGetTextExtent(str.Left(i+1), &w, &h); + tpos[i] = w; + } +#endif + #if wxUSE_UNICODE // Map the widths for UCS-2 characters back to the UTF-8 input string + // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2 + // so figure it out and fix it! i = 0; size_t ui = 0; while (i < len) { @@ -475,6 +504,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; @@ -545,6 +584,11 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { #endif } +void SurfaceImpl::SetDBCSMode(int codePage) { + // dbcsMode = codePage == SC_CP_DBCS; +} + + Surface *Surface::Allocate() { return new SurfaceImpl; } @@ -559,8 +603,10 @@ Window::~Window() { } void Window::Destroy() { - if (id) + if (id) { + Show(FALSE); GETWIN(id)->Destroy(); + } id = 0; } @@ -569,6 +615,7 @@ bool Window::HasFocus() { } PRectangle Window::GetPosition() { + if (! id) return PRectangle(); wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize()); return PRectangleFromwxRect(rc); } @@ -583,6 +630,7 @@ void Window::SetPositionRelative(PRectangle rc, Window) { } PRectangle Window::GetClientPosition() { + if (! id) return PRectangle(); wxSize sz = GETWIN(id)->GetClientSize(); return PRectangle(0, 0, sz.x, sz.y); } @@ -631,6 +679,8 @@ void Window::SetCursor(Cursor curs) { case cursorReverseArrow: cursorId = wxCURSOR_RIGHT_ARROW; break; + case cursorHand: + cursorId = wxCURSOR_HAND; default: cursorId = wxCURSOR_ARROW; break; @@ -653,199 +703,347 @@ void Window::SetTitle(const char *s) { // Helper classes for ListBox -#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)); - Hide(); - } + 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(); } - wxListBox* GetLB() { return this; } - private: DECLARE_EVENT_TABLE() }; - -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox) - EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus) +BEGIN_EVENT_TABLE(wxSTCListBox, wxListView) + EVT_SET_FOCUS( wxSTCListBox::OnFocus) END_EVENT_TABLE() -#else - -class wxSTCListBox : public wxListBox { +// A window to place the wxSTCListBox upon +class wxSTCListBoxWin : public wxWindow { +private: + wxListView* lv; + CallBackAction doubleClickAction; + void* doubleClickActionData; 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); + wxSTCListBoxWin(wxWindow* parent, wxWindowID id) : + wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxNO_BORDER ) + { + + SetBackgroundColour(*wxBLACK); + lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize, + wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER); + lv->SetCursor(wxCursor(wxCURSOR_ARROW)); + lv->InsertColumn(0, wxEmptyString); + lv->InsertColumn(1, wxEmptyString); + Hide(); } -private: - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox) - EVT_KEY_DOWN(wxSTCListBox::OnKeyDown) - EVT_CHAR(wxSTCListBox::OnKeyDown) -END_EVENT_TABLE() - + int IconWidth() { + wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL); + if (il != NULL) { + int w, h; + il->GetSize(0, w, h); + return w; + } + return 0; + } -#undef wxSTC_USE_POPUP -#define wxSTC_USE_POPUP 0 // wxPopupWindow just doesn't work well in this case... + void SetDoubleClickAction(CallBackAction action, void *data) { + doubleClickAction = action; + doubleClickActionData = data; + } -// 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 OnFocus(wxFocusEvent& event) { + GetParent()->SetFocus(); + event.Skip(); + } void OnSize(wxSizeEvent& event) { - lb->SetSize(GetSize()); + // resize the child, leaving a 1 pixel border + wxSize sz = GetClientSize(); + lv->SetSize(1, 1, sz.x-2, sz.y-2); + // reset the column widths + lv->SetColumnWidth(0, IconWidth()+4); + lv->SetColumnWidth(1, sz.x - 2 - 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 + + wxListView* GetLB() { return lv; } private: - wxSTCListBox* lb; DECLARE_EVENT_TABLE() }; -BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase) - EVT_SIZE(wxSTCListBoxWin::OnSize) + +BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow) + EVT_SET_FOCUS ( wxSTCListBoxWin::OnFocus) + EVT_SIZE ( wxSTCListBoxWin::OnSize) + EVT_LIST_ITEM_ACTIVATED(-1, wxSTCListBoxWin::OnActivate) END_EVENT_TABLE() -#endif -inline wxListBox* GETLB(WindowID win) { - return (((wxSTCListBoxWin*)win)->GetLB()); + + +inline wxSTCListBoxWin* GETLBW(WindowID win) { + return ((wxSTCListBoxWin*)win); +} + +inline wxListView* GETLB(WindowID win) { + return GETLBW(win)->GetLB(); } //---------------------------------------------------------------------- -ListBox::ListBox() { +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) +{ } -ListBox::~ListBox() { +ListBoxImpl::~ListBoxImpl() { + if (imgList) { + delete imgList; + imgList = NULL; + } + if (imgTypeMap) { + delete imgTypeMap; + imgTypeMap = NULL; + } } -void ListBox::Create(Window &parent, int ctrlID) { + +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 ListBox::SetVisibleRows(int rows) { + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + + +void ListBoxImpl::SetVisibleRows(int rows) { desiredVisibleRows = rows; } -PRectangle ListBox::GetDesiredRect() { - wxSize sz = GETLB(id)->GetBestSize(); + +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 + + GETLBW(id)->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; + + // Try to make the size an exact multiple of some number of lines + int lines = maxh / rect.GetHeight(); + maxh = (lines + 1) * rect.GetHeight() + 2; + } + else + maxh = 100; + 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; + rc.right = maxw; + rc.bottom = maxh; return rc; } -void ListBox::SetAverageCharWidth(int width) { - aveCharWidth = width; -} -void ListBox::SetFont(Font &font) { - GETLB(id)->SetFont(*((wxFont*)font.GetID())); +int ListBoxImpl::CaretFromEdge() { + return 4 + GETLBW(id)->IconWidth(); } -void ListBox::Clear() { - GETLB(id)->Clear(); + +void ListBoxImpl::Clear() { + GETLB(id)->DeleteAllItems(); } -void ListBox::Append(char *s) { - GETLB(id)->Append(stc2wx(s)); + +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 ListBox::Length() { - return GETLB(id)->GetCount(); + +int ListBoxImpl::Length() { + return GETLB(id)->GetItemCount(); } -void ListBox::Select(int n) { + +void ListBoxImpl::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 + GETLB(id)->Focus(n); + GETLB(id)->Select(n, select); } -int ListBox::GetSelection() { - return GETLB(id)->GetSelection(); + +int ListBoxImpl::GetSelection() { + return GETLB(id)->GetFirstSelected(); } -int ListBox::Find(const char *prefix) { + +int ListBoxImpl::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); + +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 ListBox::Sort() { +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() { + 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) { + GETLBW(id)->SetDoubleClickAction(action, data); +} + + + +ListBox::ListBox() { +} + +ListBox::~ListBox() { +} + +ListBox *ListBox::Allocate() { + return new ListBoxImpl(); } //---------------------------------------------------------------------- @@ -890,13 +1088,16 @@ const char *Platform::DefaultFont() { } int Platform::DefaultFontSize() { - return 8; + return wxNORMAL_FONT->GetPointSize(); } unsigned int Platform::DoubleClickTime() { return 500; // **** ::GetDoubleClickTime(); } +bool Platform::MouseButtonBounce() { + return FALSE; +} void Platform::DebugDisplay(const char *s) { wxLogDebug(stc2wx(s)); } @@ -998,6 +1199,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/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 12ad21dafe..9aeda729c7 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -67,26 +67,28 @@ 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 { public: - wxSTCCallTip(wxWindow* parent, CallTip* ct) - : wxSTCCallTipBase(parent, param2) + wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx) + : wxSTCCallTipBase(parent, param2), + m_ct(ct), m_swx(swx) { - m_ct = ct; } ~wxSTCCallTip() { - if (HasCapture()) ReleaseMouse(); } + bool AcceptsFocus() const { return FALSE; } + void OnPaint(wxPaintEvent& evt) { wxPaintDC dc(this); Surface* surfaceWindow = Surface::Allocate(); - surfaceWindow->Init(&dc); + surfaceWindow->Init(&dc, m_ct->wDraw.GetID()); m_ct->PaintCT(surfaceWindow); + surfaceWindow->Release(); delete surfaceWindow; } @@ -95,6 +97,13 @@ public: event.Skip(); } + void OnLeftDown(wxMouseEvent& event) { + wxPoint pt = event.GetPosition(); + Point p(pt.x, pt.y); + m_ct->MouseClick(p); + m_swx->CallTipClick(); + } + #if wxUSE_POPUPWIN && wxSTC_USE_POPUP virtual void DoSetSize(int x, int y, int width, int height, @@ -105,32 +114,18 @@ public: GetParent()->ClientToScreen(NULL, &y); wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags); } - - virtual bool Show( bool show = TRUE ) { - bool retval = wxSTCCallTipBase::Show(show); - if (show) - CaptureMouse(); - else - if (HasCapture()) ReleaseMouse(); - return retval; - } - - void OnLeftDown(wxMouseEvent& ) { - Show(FALSE); - } #endif private: - CallTip* m_ct; + CallTip* m_ct; + ScintillaWX* m_swx; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase) EVT_PAINT(wxSTCCallTip::OnPaint) EVT_SET_FOCUS(wxSTCCallTip::OnFocus) -#if wxUSE_POPUPWIN && wxSTC_USE_POPUP EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown) -#endif END_EVENT_TABLE() @@ -139,6 +134,7 @@ END_EVENT_TABLE() ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) { + capturedMouse = false; wMain = win; stc = win; wheelRotation = 0; @@ -220,15 +216,16 @@ void ScintillaWX::SetTicking(bool on) { void ScintillaWX::SetMouseCapture(bool on) { - if (on && !stc->HasCapture()) + if (on && !capturedMouse) stc->CaptureMouse(); - else if (!on && stc->HasCapture()) + else if (!on && capturedMouse && stc->HasCapture()) stc->ReleaseMouse(); + capturedMouse = on; } bool ScintillaWX::HaveMouseCapture() { - return stc->HasCapture(); + return capturedMouse; } @@ -387,8 +384,10 @@ bool ScintillaWX::CanPaste() { } void ScintillaWX::CreateCallTipWindow(PRectangle) { - ct.wCallTip = new wxSTCCallTip(stc, &ct); - ct.wDraw = ct.wCallTip; + if (! ct.wCallTip.Created() ) { + ct.wCallTip = new wxSTCCallTip(stc, &ct, this); + ct.wDraw = ct.wCallTip; + } } @@ -436,37 +435,37 @@ 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. + Point pt = LocationFromPosition(wParam); + char* defn = reinterpret_cast(lParam); AutoCompleteCancel(); - if (!ct.wCallTip.Created()) { - Point pt = LocationFromPosition(wParam); - pt.y += vs.lineHeight; - PRectangle rc = ct.CallTipStart(currentPos, pt, - reinterpret_cast(lParam), - vs.styles[STYLE_DEFAULT].fontName, - vs.styles[STYLE_DEFAULT].sizeZoomed, - IsUnicodeMode()); - // If the call-tip window would be out of the client - // space, adjust so it displays above the text. - PRectangle rcClient = GetClientRectangle(); - if (rc.bottom > rcClient.bottom) { + pt.y += vs.lineHeight; + PRectangle rc = ct.CallTipStart(currentPos, pt, + defn, + vs.styles[STYLE_DEFAULT].fontName, + vs.styles[STYLE_DEFAULT].sizeZoomed, + IsUnicodeMode(), + wMain); + // If the call-tip window would be out of the client + // space, adjust so it displays above the text. + PRectangle rcClient = GetClientRectangle(); + if (rc.bottom > rcClient.bottom) { #ifdef __WXGTK__ - int offset = int(vs.lineHeight * 1.25) + rc.Height(); + int offset = int(vs.lineHeight * 1.25) + rc.Height(); #else - int offset = vs.lineHeight + rc.Height(); + int offset = vs.lineHeight + rc.Height(); #endif - rc.top -= offset; - rc.bottom -= offset; - } - // Now display the window. - CreateCallTipWindow(rc); - ct.wCallTip.SetPositionRelative(rc, wMain); - ct.wCallTip.Show(); + rc.top -= offset; + rc.bottom -= offset; } - } + // Now display the window. + CreateCallTipWindow(rc); + ct.wCallTip.SetPositionRelative(rc, wMain); + ct.wCallTip.Show(); break; + } default: return ScintillaBase::WndProc(iMessage, wParam, lParam); @@ -483,22 +482,22 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) { paintState = painting; Surface* surfaceWindow = Surface::Allocate(); - surfaceWindow->Init(dc); - PRectangle rcPaint = PRectangleFromwxRect(rect); + surfaceWindow->Init(dc, wMain.GetID()); + 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 } @@ -775,16 +774,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); - Paint(surfaceWindow, rcPaint); - delete surfaceWindow; + surfaceWindow->Init(&dc, wMain.GetID()); -// stc->Refresh(FALSE); + dc.BeginDrawing(); + ClipChildren(dc, rcPaint); + Paint(surfaceWindow, rcPaint); + dc.EndDrawing(); + delete surfaceWindow; paintState = notPainting; } @@ -798,6 +799,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/src/stc/ScintillaWX.h b/src/stc/ScintillaWX.h index 04b2ac0333..4c6b35c6e3 100644 --- a/src/stc/ScintillaWX.h +++ b/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,8 +150,10 @@ public: bool GetHideSelection() { return hideSelection; } void DoScrollToLine(int line); void DoScrollToColumn(int column); + void ClipChildren(wxDC& dc, PRectangle rect); private: + bool capturedMouse; wxStyledTextCtrl* stc; #if wxUSE_DRAG_AND_DROP @@ -158,6 +161,9 @@ private: wxDragResult dragResult; #endif int wheelRotation; + + + friend class wxSTCCallTip; }; //---------------------------------------------------------------------- diff --git a/src/stc/StcVC.dsp b/src/stc/StcVC.dsp index a6c2c4ce95..7007794571 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 @@ -330,6 +342,10 @@ SOURCE=.\scintilla\src\LexOthers.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexPOV.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LexPascal.cxx # End Source File # Begin Source File @@ -446,6 +462,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/gen_iface.py b/src/stc/gen_iface.py index 6689380466..885357f398 100644 --- a/src/stc/gen_iface.py +++ b/src/stc/gen_iface.py @@ -42,6 +42,9 @@ cmdValues = [ (2300, 2349), (2176, 2180), (2390, 2393), (2395, 2396), + 2404, + (2413, 2416), + (2450, 2454), ] @@ -88,90 +91,114 @@ 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), - - 'GetStyleAt' : ( 0, 0, - '''int %s(int pos) { - return (unsigned char)SendMsg(%s, pos, 0);''', - 0), - - '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;''', - - ('Retrieve a buffer of cells.',)), - - - 'PositionFromPoint' : (0, - 'int %s(wxPoint pt);', - - '''int %s(wxPoint pt) { - return SendMsg(%s, pt.x, pt.y);''', - - 0), - - '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; - } - - 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);''', - - 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), + + '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;''', + + ('Retrieve a buffer of cells.',)), + + + 'PositionFromPoint' : + (0, + 'int %s(wxPoint pt);', + + '''int %s(wxPoint pt) { + return SendMsg(%s, pt.x, pt.y);''', + 0), + + '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; + } + + 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);''', + + 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);''', - - '''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);''', + '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) { + + 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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 +216,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);', - - '''void %s(int length, char* styleBytes) { - SendMsg(%s, length, (long)styleBytes);''', + 'SetStylingEx' : + ('SetStyleBytes', + 'void %s(int length, char* styleBytes);', - 0), + '''void %s(int length, char* styleBytes) { + SendMsg(%s, length, (long)styleBytes);''', + 0), 'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0), @@ -245,129 +273,162 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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);''', - - '''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), - - '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; - - return SendMsg(%s, doDraw, (long)&fr);''', - 0), - - - 'GetLine' : (0, - 'wxString %s(int line);', - - '''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);''', - - ('Retrieve the contents of a line.',)), + '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; + + 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; + + 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), + + + 'GetLine' : + (0, + 'wxString %s(int line);', + + '''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);''', + + ('Retrieve the contents of a line.',)), 'SetSel' : ('SetSelection', 0, 0, 0), - 'GetSelText' : ('GetSelectedText', - 'wxString %s();', - - '''wxString %s() { - int start; - int end; - - GetSelection(&start, &end); - int len = end - start; - if (!len) return wxEmptyString; - - 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);''', - - ('Retrieve the selected 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.',)), + + 'GetSelText' : + ('GetSelectedText', + 'wxString %s();', + + '''wxString %s() { + int start; + int end; + + GetSelection(&start, &end); + int len = end - start; + if (!len) return wxEmptyString; + + 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);''', + + ('Retrieve the selected 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,88 +437,104 @@ 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), - 'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0), - 'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0), - 'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0), - - - '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), - - '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), - - '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), - - - '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), - - '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), - - 'ReleaseDocument' : (0, - 'void %s(void* docPointer);', - '''void %s(void* docPointer) { - SendMsg(%s, 0, (long)docPointer);''', - 0), - 'SetCodePage' : (0, - 0, - '''void %s(int codePage) { + 'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0), + 'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0), + 'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0), + 'CallTipSetFore' : ('CallTipSetForeground', 0, 0, 0), + 'CallTipSetForeHlt' : ('CallTipSetForegroundHighlight', 0, 0, 0), + + 'SetHotspotActiveFore' : ('SetHotspotActiveForeground', 0, 0, 0), + 'SetHotspotActiveBack' : ('SetHotspotActiveBackground', 0, 0, 0), + + + '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), + + '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), + + '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), + + + '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), + + '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), + + '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 +542,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), @@ -474,6 +551,9 @@ methodOverrideMap = { 'GetFocus' : ('GetSTCFocus', 0, 0, 0), + 'LoadLexerLibrary' : (None, 0,0,0), + + # Remove all methods that are key commands since they can be # executed with CmdKeyExecute @@ -522,7 +602,16 @@ methodOverrideMap = { 'LineScrollDown' : (None, 0, 0, 0), 'LineScrollUp' : (None, 0, 0, 0), 'DeleteBackNotLine' : (None, 0, 0, 0), - + 'HomeWrap' : (None, 0, 0, 0), + 'HomeWrapExtend' : (None, 0, 0, 0), + 'LineEndWrap' : (None, 0, 0, 0), + 'LineEndWrapExtend' : (None, 0, 0, 0), + 'VCHomeWrap' : (None, 0, 0, 0), + 'VCHomeWrapExtend' : (None, 0, 0, 0), + 'ParaDown' : (None, 0, 0, 0), + 'ParaDownExtend' : (None, 0, 0, 0), + 'ParaUp' : (None, 0, 0, 0), + 'ParaUpExtend' : (None, 0, 0, 0), diff --git a/src/stc/makefile.b32 b/src/stc/makefile.b32 index 5a9843f863..345d659000 100644 --- a/src/stc/makefile.b32 +++ b/src/stc/makefile.b32 @@ -34,17 +34,21 @@ 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 \ LexOthers.obj \ + LexPOV.obj \ LexPascal.obj \ LexPerl.obj \ LexPython.obj \ @@ -60,17 +64,19 @@ OBJECTS = \ UniConversion.obj \ ViewStyle.obj \ WindowAccessor.obj \ + XPM.obj \ \ 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..25dd4ad0cd 100644 --- a/src/stc/makefile.g95 +++ b/src/stc/makefile.g95 @@ -22,17 +22,21 @@ 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) \ $(S)/LexOthers.$(OBJSUFF) \ + $(S)/LexPOV.$(OBJSUFF) \ $(S)/LexPascal.$(OBJSUFF) \ $(S)/LexPerl.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \ @@ -48,11 +52,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..4aa0e2c352 100644 --- a/src/stc/makefile.vc +++ b/src/stc/makefile.vc @@ -27,17 +27,21 @@ 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 \ $(D)\LexOthers.obj \ + $(D)\LexPOV.obj \ $(D)\LexPascal.obj \ $(D)\LexPerl.obj \ $(D)\LexPython.obj \ @@ -53,6 +57,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..76a2985a3b 100644 --- a/src/stc/makefile.wat +++ b/src/stc/makefile.wat @@ -31,17 +31,21 @@ 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 & LexOthers.obj & + LexPOV.obj & LexPascal.obj & LexPerl.obj & LexPython.obj & @@ -57,9 +61,10 @@ OBJECTS = & UniConversion.obj & ViewStyle.obj & WindowAccessor.obj & + XPM.obj & PlatWX.obj & ScintillaWX.obj & - stc.obj + stc.obj all: $(STCLIB) .SYMBOLIC @@ -67,17 +72,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/src/stc/scintilla/License.txt b/src/stc/scintilla/License.txt new file mode 100644 index 0000000000..cbe25b2fc2 --- /dev/null +++ b/src/stc/scintilla/License.txt @@ -0,0 +1,20 @@ +License for Scintilla and SciTE + +Copyright 1998-2003 by Neil Hodgson + +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/src/stc/scintilla/README.txt b/src/stc/scintilla/README.txt index 8538707cde..4f5b08f1cb 100644 --- a/src/stc/scintilla/README.txt +++ b/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.52 diff --git a/src/stc/scintilla/include/Accessor.h b/src/stc/scintilla/include/Accessor.h index 0b2c4baee2..3f59c07939 100644 --- a/src/stc/scintilla/include/Accessor.h +++ b/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/src/stc/scintilla/include/KeyWords.h b/src/stc/scintilla/include/KeyWords.h index df4e870c58..c51c88ef59 100644 --- a/src/stc/scintilla/include/KeyWords.h +++ b/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/src/stc/scintilla/include/Platform.h b/src/stc/scintilla/include/Platform.h index 1a8dfaa96e..7f5985c765 100644 --- a/src/stc/scintilla/include/Platform.h +++ b/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 @@ -109,6 +109,12 @@ public: return (right > other.left) && (left < other.right) && (bottom > other.top) && (top < other.bottom); } + void Move(int xDelta, int yDelta) { + left += xDelta; + top += yDelta; + right += xDelta; + bottom += yDelta; + } int Width() { return right - left; } int Height() { return bottom - top; } }; @@ -136,7 +142,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 +153,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 +227,9 @@ struct ColourPair { desired = desired_; allocated.Set(desired.AsLong()); } + void Copy() { + allocated.Set(desired.AsLong()); + } }; class Window; // Forward declaration for Palette @@ -271,9 +305,9 @@ public: virtual ~Surface() {}; static Surface *Allocate(); - virtual void Init()=0; - virtual void Init(SurfaceID sid)=0; - virtual void InitPixMap(int width, int height, Surface *surface_)=0; + virtual void Init(WindowID wid)=0; + virtual void Init(SurfaceID sid, WindowID wid)=0; + virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; virtual void Release()=0; virtual bool Initialised()=0; @@ -292,6 +326,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 +342,7 @@ public: virtual void FlushCachedState()=0; virtual void SetUnicodeMode(bool unicodeMode_)=0; + virtual void SetDBCSMode(int codePage)=0; }; /** @@ -329,8 +365,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(); @@ -341,7 +377,7 @@ public: void InvalidateAll(); void InvalidateRectangle(PRectangle rc); virtual void SetFont(Font &font); - enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow }; + enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; void SetCursor(Cursor curs); void SetTitle(const char *s); private: @@ -353,38 +389,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; }; /** @@ -426,6 +452,7 @@ public: static const char *DefaultFont(); static int DefaultFontSize(); static unsigned int DoubleClickTime(); + static bool MouseButtonBounce(); static void DebugDisplay(const char *s); static bool IsKeyDown(int key); static long SendScintilla( @@ -433,6 +460,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/src/stc/scintilla/include/PropSet.h b/src/stc/scintilla/include/PropSet.h index 59588c62ed..3f1b64f77f 100644 --- a/src/stc/scintilla/include/PropSet.h +++ b/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/src/stc/scintilla/include/SString.h b/src/stc/scintilla/include/SString.h index 3c7ccc33a5..01602df781 100644 --- a/src/stc/scintilla/include/SString.h +++ b/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/src/stc/scintilla/include/SciLexer.h b/src/stc/scintilla/include/SciLexer.h index a6066cd585..e1da492b27 100644 --- a/src/stc/scintilla/include/SciLexer.h +++ b/src/stc/scintilla/include/SciLexer.h @@ -48,6 +48,12 @@ #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_POV 39 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -273,6 +279,9 @@ #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_ERR_ELF 15 +#define SCE_ERR_IFC 16 #define SCE_BAT_DEFAULT 0 #define SCE_BAT_COMMENT 1 #define SCE_BAT_WORD 2 @@ -309,22 +318,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 +408,58 @@ #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 +#define SCE_CSS_DOUBLESTRING 13 +#define SCE_CSS_SINGLESTRING 14 +#define SCE_POV_DEFAULT 0 +#define SCE_POV_COMMENT 1 +#define SCE_POV_COMMENTLINE 2 +#define SCE_POV_COMMENTDOC 3 +#define SCE_POV_NUMBER 4 +#define SCE_POV_WORD 5 +#define SCE_POV_STRING 6 +#define SCE_POV_OPERATOR 7 +#define SCE_POV_IDENTIFIER 8 +#define SCE_POV_BRACE 9 +#define SCE_POV_WORD2 10 //--Autogenerated -- end of section automatically generated from Scintilla.iface #endif diff --git a/src/stc/scintilla/include/Scintilla.h b/src/stc/scintilla/include/Scintilla.h index 30fcf50fc4..c377d07cc2 100644 --- a/src/stc/scintilla/include/Scintilla.h +++ b/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 @@ -181,6 +184,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_CASE_LOWER 2 #define SCI_STYLESETCASE 2060 #define SCI_STYLESETCHARACTERSET 2066 +#define SCI_STYLESETHOTSPOT 2409 #define SCI_SETSELFORE 2067 #define SCI_SETSELBACK 2068 #define SCI_SETCARETFORE 2069 @@ -241,6 +245,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 @@ -278,6 +286,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCFIND_MATCHCASE 4 #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 +#define SCFIND_POSIX 0x00400000 #define SCI_FINDTEXT 2150 #define SCI_FORMATRANGE 2151 #define SCI_GETFIRSTVISIBLELINE 2152 @@ -333,11 +342,17 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_CALLTIPPOSSTART 2203 #define SCI_CALLTIPSETHLT 2204 #define SCI_CALLTIPSETBACK 2205 +#define SCI_CALLTIPSETFORE 2206 +#define SCI_CALLTIPSETFOREHLT 2207 #define SCI_VISIBLEFROMDOCLINE 2220 #define SCI_DOCLINEFROMVISIBLE 2221 #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 +365,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 +398,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 +448,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 @@ -426,6 +458,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_HOMEDISPLAYEXTEND 2346 #define SCI_LINEENDDISPLAY 2347 #define SCI_LINEENDDISPLAYEXTEND 2348 +#define SCI_HOMEWRAP 2349 +#define SCI_HOMEWRAPEXTEND 2450 +#define SCI_LINEENDWRAP 2451 +#define SCI_LINEENDWRAPEXTEND 2452 +#define SCI_VCHOMEWRAP 2453 +#define SCI_VCHOMEWRAPEXTEND 2454 #define SCI_MOVECARETINSIDEVIEW 2401 #define SCI_LINELENGTH 2350 #define SCI_BRACEHIGHLIGHT 2351 @@ -464,7 +502,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 +518,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 +526,15 @@ 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_SETHOTSPOTACTIVEFORE 2410 +#define SCI_SETHOTSPOTACTIVEBACK 2411 +#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412 +#define SCI_PARADOWN 2413 +#define SCI_PARADOWNEXTEND 2414 +#define SCI_PARAUP 2415 +#define SCI_PARAUPEXTEND 2416 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 @@ -495,6 +543,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETPROPERTY 4004 #define SCI_SETKEYWORDS 4005 #define SCI_SETLEXERLANGUAGE 4006 +#define SCI_LOADLEXERLIBRARY 4007 #define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_DELETETEXT 0x2 #define SC_MOD_CHANGESTYLE 0x4 @@ -548,6 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCN_DWELLSTART 2016 #define SCN_DWELLEND 2017 #define SCN_ZOOM 2018 +#define SCN_HOTSPOTCLICK 2019 +#define SCN_HOTSPOTDOUBLECLICK 2020 +#define SCN_CALLTIPCLICK 2021 //--Autogenerated -- end of section automatically generated from Scintilla.iface // These structures are defined to be exactly the same shape as the Win32 diff --git a/src/stc/scintilla/include/Scintilla.iface b/src/stc/scintilla/include/Scintilla.iface index d6383b103b..c5dacbdf04 100644 --- a/src/stc/scintilla/include/Scintilla.iface +++ b/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 @@ -405,6 +412,9 @@ set void StyleSetCase=2060(int style, int caseForce) # Set the character set of the font in a style. set void StyleSetCharacterSet=2066(int style, int characterSet) +# Set a style to be a hotspot or not. +set void StyleSetHotSpot=2409(int style, bool hotspot) + # Set the foreground colour of the selection and whether to use this setting. fun void SetSelFore=2067(bool useSetting, colour fore) @@ -578,6 +588,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,) @@ -681,6 +704,7 @@ val SCFIND_WHOLEWORD=2 val SCFIND_MATCHCASE=4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 +val SCFIND_POSIX=0x00400000 # Find some text in the document. fun position FindText=2150(int flags, findtext ft) @@ -688,7 +712,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. @@ -863,6 +887,12 @@ fun void CallTipSetHlt=2204(int start, int end) # Set the background colour for the call tip. set void CallTipSetBack=2205(colour back,) +# Set the foreground colour for the call tip. +set void CallTipSetFore=2206(colour fore,) + +# Set the foreground colour for the highlighted part of the call tip. +set void CallTipSetForeHlt=2207(colour fore,) + # Find the display line of a document line taking hidden lines into account. fun int VisibleFromDocLine=2220(int line,) @@ -873,6 +903,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 +944,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 +1030,38 @@ 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. +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 +1185,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(,) @@ -1141,6 +1218,19 @@ fun void LineEndDisplay=2347(,) # caret position. fun void LineEndDisplayExtend=2348(,) +# These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? +# except they behave differently when word-wrap is enabled: +# They go first to the start / end of the display line, like (Home|LineEnd)Display +# The difference is that, the cursor is already at the point, it goes on to the start +# or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend. + +fun void HomeWrap=2349(,) +fun void HomeWrapExtend=2450(,) +fun void LineEndWrap=2451(,) +fun void LineEndWrapExtend=2452(,) +fun void VCHomeWrap=2453(,) +fun void VCHomeWrapExtend=2454(,) + # Move the caret inside current view if it's not there already. fun void MoveCaretInsideView=2401(,) @@ -1251,7 +1341,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 +1381,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 +1420,27 @@ 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(,) + +# Set a fore colour for active hotspots. +set void SetHotspotActiveFore=2410(bool useSetting, colour fore) + +# Set a back colour for active hotspots. +set void SetHotspotActiveBack=2411(bool useSetting, colour back) + +# Enable / Disable underlining active hotspots. +set void SetHotspotActiveUnderline=2412(bool underline,) + +# Move caret between paragraphs (delimited by empty lines) +fun void ParaDown=2413(,) +fun void ParaDownExtend=2414(,) +fun void ParaUp=2415(,) +fun void ParaUpExtend=2416(,) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) @@ -1351,6 +1465,10 @@ set void SetKeyWords=4005(int keywordSet, string keyWords) # Set the lexing language of the document based on string name. set void SetLexerLanguage=4006(, string language) +# Load a lexer library (dll / so) +# NOT YET IMPLEMENTED +fun void LoadLexerLibrary=4007(, string path) + # Notifications # Type of modification and the action which caused the modification. # These are defined as a bit mask to make it easy to specify which notifications are wanted. @@ -1442,6 +1560,12 @@ 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 +val SCLEX_POV=39 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -1708,6 +1832,9 @@ 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 +val SCE_ERR_ELF=15 +val SCE_ERR_IFC=16 # Lexical states for SCLEX_BATCH lex Batch=SCLEX_BATCH SCE_BAT_ val SCE_BAT_DEFAULT=0 @@ -1754,24 +1881,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,7 +1986,67 @@ 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 +val SCE_CSS_DOUBLESTRING=13 +val SCE_CSS_SINGLESTRING=14 +# Lexical states for SCLEX_POV +lex POV=SCLEX_POV SCE_POV_ +val SCE_POV_DEFAULT=0 +val SCE_POV_COMMENT=1 +val SCE_POV_COMMENTLINE=2 +val SCE_POV_COMMENTDOC=3 +val SCE_POV_NUMBER=4 +val SCE_POV_WORD=5 +val SCE_POV_STRING=6 +val SCE_POV_OPERATOR=7 +val SCE_POV_IDENTIFIER=8 +val SCE_POV_BRACE=9 +val SCE_POV_WORD2=10 # Events evt void StyleNeeded=2000(int position) @@ -1874,6 +2068,9 @@ evt void URIDropped=2015(string text) evt void DwellStart=2016(int position) evt void DwellEnd=2017(int position) evt void Zoom=2018(void) +evt void HotSpotClick=2019(int modifiers, int position) +evt void HotSpotDoubleClick=2020(int modifiers, int position) +evt void CallTipClick=2021(int position) cat Deprecated diff --git a/src/stc/scintilla/include/ScintillaWidget.h b/src/stc/scintilla/include/ScintillaWidget.h index 203f357339..765fd8594d 100644 --- a/src/stc/scintilla/include/ScintillaWidget.h +++ b/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/src/stc/scintilla/include/WindowAccessor.h b/src/stc/scintilla/include/WindowAccessor.h index 6c16b150f2..4324605017 100644 --- a/src/stc/scintilla/include/WindowAccessor.h +++ b/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/src/stc/scintilla/src/AutoComplete.cxx b/src/stc/scintilla/src/AutoComplete.cxx index d971fa12a0..adbd24d038 100644 --- a/src/stc/scintilla/src/AutoComplete.cxx +++ b/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/src/stc/scintilla/src/AutoComplete.h b/src/stc/scintilla/src/AutoComplete.h index 622a5666ec..981fb44c06 100644 --- a/src/stc/scintilla/src/AutoComplete.h +++ b/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/src/stc/scintilla/src/CallTip.cxx b/src/stc/scintilla/src/CallTip.cxx index d67173b084..314f9bfa71 100644 --- a/src/stc/scintilla/src/CallTip.cxx +++ b/src/stc/scintilla/src/CallTip.cxx @@ -18,6 +18,9 @@ CallTip::CallTip() { inCallTipMode = false; posStartCallTip = 0; val = 0; + xUp = -100; + xDown = -100; + lineHeight = 1; startHighlight = 0; endHighlight = 0; @@ -35,6 +38,8 @@ CallTip::~CallTip() { val = 0; } +const int widthArrow = 14; + void CallTip::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(colourBG, want); pal.WantFind(colourUnSel, want); @@ -43,24 +48,98 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(colourLight, want); } -void CallTip::PaintCT(Surface *surfaceWindow) { - if (!val) - return ; +void CallTip::DrawChunk(Surface *surface, int &x, const char *s, + int posStart, int posEnd, int ytext, PRectangle rcClient, + bool highlight, bool draw) { + s += posStart; + int len = posEnd - posStart; + int maxEnd = 0; + int ends[10]; + for (int i=0;i 0) + ends[maxEnd++] = i; + ends[maxEnd++] = i+1; + } + } + ends[maxEnd++] = len; + int startSeg = 0; + int xEnd; + for (int seg = 0; seg startSeg) { + if (s[startSeg] <= '\002') { + xEnd = x + widthArrow; + offsetMain = xEnd; + if (draw) { + const int halfWidth = widthArrow / 2 - 3; + const int centreX = x + widthArrow / 2 - 1; + const int centreY = (rcClient.top + rcClient.bottom) / 2; + rcClient.left = x; + rcClient.right = xEnd; + surface->FillRectangle(rcClient, colourBG.allocated); + PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1); + surface->FillRectangle(rcClientInner, colourUnSel.allocated); + + if (s[startSeg] == '\001') { + // Up arrow + Point pts[] = { + Point(centreX - halfWidth, centreY + halfWidth / 2), + Point(centreX + halfWidth, centreY + halfWidth / 2), + Point(centreX, centreY - halfWidth + halfWidth / 2), + }; + surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), + colourBG.allocated, colourBG.allocated); + } else { + // Down arrow + Point pts[] = { + Point(centreX - halfWidth, centreY - halfWidth / 2), + Point(centreX + halfWidth, centreY - halfWidth / 2), + Point(centreX, centreY + halfWidth - halfWidth / 2), + }; + surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), + colourBG.allocated, colourBG.allocated); + } + } else { + if (s[startSeg] == '\001') { + xUp = x+1; + } else { + xDown = x+1; + } + } + } else { + xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg); + if (draw) { + rcClient.left = x; + rcClient.right = xEnd; + surface->DrawTextNoClip(rcClient, font, ytext, + s+startSeg, endSeg - startSeg, + highlight ? colourSel.allocated : colourUnSel.allocated, + colourBG.allocated); + } + } + x = xEnd; + startSeg = endSeg; + } + } +} + +int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { PRectangle rcClientPos = wCallTip.GetClientPosition(); PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, rcClientPos.bottom - rcClientPos.top); PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); - surfaceWindow->FillRectangle(rcClient, colourBG.allocated); // To make a nice small call tip window, it is only sized to fit most normal characters without accents - int lineHeight = surfaceWindow->Height(font); int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight int ytext = rcClient.top + ascent + 1; + rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; char *chunkVal = val; bool moreChunks = true; + int maxWidth = 0; while (moreChunks) { char *chunkEnd = strchr(chunkVal, '\n'); if (chunkEnd == NULL) { @@ -76,36 +155,38 @@ void CallTip::PaintCT(Surface *surfaceWindow) { int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset); thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset); thisEndHighlight -= chunkOffset; - int x = 5; - int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight); - rcClient.left = x; rcClient.top = ytext - ascent - 1; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal, thisStartHighlight, - colourUnSel.allocated, colourBG.allocated); - x = xEnd; - - xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight, - thisEndHighlight - thisStartHighlight); - rcClient.top = ytext; - rcClient.left = x; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight, - colourSel.allocated, colourBG.allocated); - x = xEnd; - - xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight, - chunkLength - thisEndHighlight); - rcClient.left = x; - rcClient.right = xEnd; - surfaceWindow->DrawTextNoClip(rcClient, font, ytext, - chunkVal + thisEndHighlight, chunkLength - thisEndHighlight, - colourUnSel.allocated, colourBG.allocated); + + int x = 5; + + DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, + ytext, rcClient, false, draw); + DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, + ytext, rcClient, true, draw); + DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, + ytext, rcClient, false, draw); + chunkVal = chunkEnd + 1; ytext += lineHeight; + rcClient.bottom += lineHeight; + maxWidth = Platform::Maximum(maxWidth, x); } + return maxWidth; +} + +void CallTip::PaintCT(Surface *surfaceWindow) { + if (!val) + return; + PRectangle rcClientPos = wCallTip.GetClientPosition(); + PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, + rcClientPos.bottom - rcClientPos.top); + PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); + + surfaceWindow->FillRectangle(rcClient, colourBG.allocated); + + offsetMain = 5; + PaintContents(surfaceWindow, true); + // Draw a raised border around the edges of the window surfaceWindow->MoveTo(0, rcClientSize.bottom - 1); surfaceWindow->PenColour(colourShade.allocated); @@ -116,20 +197,34 @@ void CallTip::PaintCT(Surface *surfaceWindow) { surfaceWindow->LineTo(0, rcClientSize.bottom - 1); } +void CallTip::MouseClick(Point pt) { + clickPlace = 0; + if (pt.y < lineHeight) { + if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) { + clickPlace = 1; + } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) { + clickPlace = 2; + } + } +} + PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, - const char *faceName, int size, bool unicodeMode_) { + const char *faceName, int size, + int codePage_, Window &wParent) { + clickPlace = 0; 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->Init(wParent.GetID()); + surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); + surfaceMeasure->SetDBCSMode(codePage); startHighlight = 0; endHighlight = 0; inCallTipMode = true; @@ -138,23 +233,22 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false); // Look for multiple lines in the text // Only support \n here - simply means container must avoid \r! - int width = 0; int numLines = 1; const char *newline; const char *look = val; + xUp = -100; + xDown = -100; + offsetMain = 5; + int width = PaintContents(surfaceMeasure, false) + 5; while ((newline = strchr(look, '\n')) != NULL) { - int thisWidth = surfaceMeasure->WidthText(font, look, newline - look); - width = Platform::Maximum(width, thisWidth); look = newline + 1; numLines++; } - int lastWidth = surfaceMeasure->WidthText(font, look, static_cast(strlen(look))); - width = Platform::Maximum(width, lastWidth) + 10; - int lineHeight = surfaceMeasure->Height(font); + lineHeight = surfaceMeasure->Height(font); // Extra line for border and an empty line at top and bottom int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2; delete surfaceMeasure; - return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height); + return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height); } void CallTip::CallTipCancel() { diff --git a/src/stc/scintilla/src/CallTip.h b/src/stc/scintilla/src/CallTip.h index 9f5025f63b..ffaedb0771 100644 --- a/src/stc/scintilla/src/CallTip.h +++ b/src/stc/scintilla/src/CallTip.h @@ -15,9 +15,17 @@ class CallTip { int endHighlight; char *val; Font font; + int xUp; + int xDown; + int lineHeight; + int offsetMain; // Private so CallTip objects can not be copied CallTip(const CallTip &) {} CallTip &operator=(const CallTip &) { return *this; } + void DrawChunk(Surface *surface, int &x, const char *s, + int posStart, int posEnd, int ytext, PRectangle rcClient, + bool highlight, bool draw); + int PaintContents(Surface *surfaceWindow, bool draw); public: Window wCallTip; @@ -29,22 +37,25 @@ public: ColourPair colourSel; ColourPair colourShade; ColourPair colourLight; - bool unicodeMode; - + int codePage; + int clickPlace; + 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); - + + void MouseClick(Point pt); + /// 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_, Window &wParent); + 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/src/stc/scintilla/src/CellBuffer.cxx b/src/stc/scintilla/src/CellBuffer.cxx index 420dee6ff7..8f292869d7 100644 --- a/src/stc/scintilla/src/CellBuffer.cxx +++ b/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/src/stc/scintilla/src/CellBuffer.h b/src/stc/scintilla/src/CellBuffer.h index 5cfcbfe1f0..2866d548cb 100644 --- a/src/stc/scintilla/src/CellBuffer.h +++ b/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/src/stc/scintilla/src/Document.cxx b/src/stc/scintilla/src/Document.cxx index 7458120442..20900bcf97 100644 --- a/src/stc/scintilla/src/Document.cxx +++ b/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++; - } - - - if (atLeadByte) { - // Position is between a lead byte and a trail byte - if (moveDir > 0) - return pos + 1; - else - return pos - 1; + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for(i=0;i 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); } @@ -718,6 +720,33 @@ void Document::ConvertLineEnds(int eolModeSet) { EndUndoAction(); } +int Document::ParaDown(int pos) { + int line = LineFromPosition(pos); + while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines + line++; + } + while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines + line++; + } + if (line < LinesTotal()) + return LineStart(line); + else // end of a document + return LineEnd(line-1); +} + +int Document::ParaUp(int pos) { + int line = LineFromPosition(pos); + line--; + while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines + line--; + } + while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines + line--; + } + line++; + return LineStart(line); +} + Document::charClassification Document::WordCharClass(unsigned char ch) { if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80)) return ccWord; @@ -745,7 +774,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 +827,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) { @@ -845,7 +874,7 @@ public: * Has not been tested with backwards DBCS searches yet. */ long Document::FindText(int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, bool regExp, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length) { if (regExp) { if (!pre) @@ -853,22 +882,16 @@ 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); endPos = MovePositionOutsideChar(endPos, 1, false); - const char *errmsg = pre->Compile(s, *length, caseSensitive); + const char *errmsg = pre->Compile(s, *length, caseSensitive, posix); if (errmsg) { return -1; } @@ -878,7 +901,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,36 +911,54 @@ 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 ((startPos != startOfLine) && (s[0] == '^')) - continue; // Can't match start of line if start position after start of line - startOfLine = startPos; - } - if (line == lineRangeEnd) { - if ((endPos != endOfLine) && (searchEnd == '$')) - continue; // Can't match end of line if end position before end of line - endOfLine = endPos; + if (increment == 1) { + if (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 ((endPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if end position before end of line + endOfLine = endPos; + } + } else { + if (line == lineRangeEnd) { + if ((endPos != startOfLine) && (s[0] == '^')) + continue; // Can't match start of line if end position after start of line + startOfLine = endPos; + } + if (line == lineRangeStart) { + if ((startPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if start position before end of line + endOfLine = startPos; + } } + DocumentIndexer di(this, endOfLine); int success = pre->Execute(di, startOfLine, endOfLine); if (success) { pos = pre->bopat[0]; lenRet = pre->eopat[0] - pre->bopat[0]; + if (increment == -1) { + // Check for the last match on this line. + int repetitions = 1000; // Break out of infinite loop + while (success && (pre->eopat[0] < endOfLine) && (repetitions--)) { + 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 +1076,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 +1111,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 +1136,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 +1251,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 +1266,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 +1312,47 @@ 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; +} + +int Document::ExtendStyleRange(int pos, int delta) { + int sStart = cb.StyleAt(pos); + if (delta < 0) { + while (pos > 0 && (cb.StyleAt(pos) == sStart)) + pos--; + pos++; + } else { + while (pos < (Length()) && (cb.StyleAt(pos) == sStart)) + pos++; } return pos; } diff --git a/src/stc/scintilla/src/Document.h b/src/stc/scintilla/src/Document.h index 82931207cf..bcdbe00ca5 100644 --- a/src/stc/scintilla/src/Document.h +++ b/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,8 +191,8 @@ 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, - bool caseSensitive, bool word, bool wordStart, bool regExp, int *length); + long FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length); long FindText(int iMessage, unsigned long wParam, long lParam); const char *SubstituteByPosition(const char *text, int *length); int LinesTotal(); @@ -220,9 +220,11 @@ public: bool IsWordPartSeparator(char ch); int WordPartLeft(int pos); int WordPartRight(int pos); + int ExtendStyleRange(int pos, int delta); + int ParaUp(int pos); + int ParaDown(int pos); private: - bool IsDBCS(int pos); charClassification WordCharClass(unsigned char ch); bool IsWordStartAt(int pos); bool IsWordEndAt(int pos); @@ -252,7 +254,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/src/stc/scintilla/src/DocumentAccessor.cxx b/src/stc/scintilla/src/DocumentAccessor.cxx index 595edf8ba2..b7902df35a 100644 --- a/src/stc/scintilla/src/DocumentAccessor.cxx +++ b/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/src/stc/scintilla/src/DocumentAccessor.h b/src/stc/scintilla/src/DocumentAccessor.h index dc591d13ec..f6523c94f9 100644 --- a/src/stc/scintilla/src/DocumentAccessor.h +++ b/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/src/stc/scintilla/src/Editor.cxx b/src/stc/scintilla/src/Editor.cxx index f2ba9f088b..44399a5fb0 100644 --- a/src/stc/scintilla/src/Editor.cxx +++ b/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(); @@ -358,7 +364,7 @@ Editor::Editor() { modEventMask = SC_MODEVENTMASKALL; pdoc = new Document(); - pdoc ->AddRef(); + pdoc->AddRef(); pdoc->AddWatcher(this, 0); recordingMacro = false; @@ -368,7 +374,10 @@ Editor::Editor() { wrapWidth = LineLayout::wrapWidthInfinite; docLineLastWrapped = -1; - llc.SetLevel(LineLayoutCache::llcDocument); + hsStart = -1; + hsEnd = -1; + + llc.SetLevel(LineLayoutCache::llcCaret); } Editor::~Editor() { @@ -414,7 +423,7 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) { void Editor::RefreshStyleData() { if (!stylesValid) { stylesValid = true; - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(this); if (surface) { vs.Refresh(*surface); RefreshColourPalette(palette, true); @@ -474,10 +483,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 +495,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 +526,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(this); + 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 +539,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 +549,6 @@ Point Editor::LocationFromPosition(int pos) { } pt.x += vs.fixedColumnWidth - xOffset; } - llc.Dispose(ll); return pt; } @@ -535,6 +566,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 +582,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(this); + 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 +627,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(this); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -604,18 +636,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 +659,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(this); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); int retVal = 0; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(lineDoc); @@ -638,17 +668,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 +849,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; } @@ -845,9 +901,9 @@ int Editor::MovePositionTo(int newPos, bool extend, bool ensureVisible) { } else { SetEmptySelection(newPos); } + ShowCaretAtCurrentPosition(); if (ensureVisible) EnsureCaretVisible(); - ShowCaretAtCurrentPosition(); NotifyMove(newPos); return 0; } @@ -877,7 +933,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 +946,9 @@ void Editor::ScrollTo(int line) { } else { Redraw(); } - SetVerticalScrollPos(); + if (moveThumb) { + SetVerticalScrollPos(); + } } } @@ -916,32 +974,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(this); + 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; } @@ -1092,9 +1149,9 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { } newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos()); if (newTopLine != topLine) { + Redraw(); SetTopLine(newTopLine); SetVerticalScrollPos(); - Redraw(); } } @@ -1166,7 +1223,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 +1258,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 +1314,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 +1330,17 @@ bool Editor::WrapLines() { wrapWidth = rcTextArea.Width(); // Ensure all of the document is styled. pdoc->EnsureStyledTo(pdoc->Length()); - AutoSurface surface(IsUnicodeMode()); + AutoSurface surface(this); 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 +1363,63 @@ bool Editor::WrapLines() { return wrapOccurred; } +void Editor::LinesJoin() { + if (!RangeContainsProtected(targetStart, targetEnd)) { + pdoc->BeginUndoAction(); + bool prevNonWS = true; + for (int pos = targetStart; pos < targetEnd; pos++) { + if (IsEOLChar(pdoc->CharAt(pos))) { + targetEnd -= pdoc->LenChar(pos); + pdoc->DelChar(pos); + if (prevNonWS) { + // Ensure at least one space separating previous lines + pdoc->InsertChar(pos, ' '); + } + } else { + prevNonWS = pdoc->CharAt(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(this); + 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) * strlen(eol) + + 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 +1492,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 +1506,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 +1576,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 +1584,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 +1639,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 +1661,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 +1675,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 +1720,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 +1751,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 +1765,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 +1777,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 +1818,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 +1841,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 +1855,71 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } } +ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground, + ColourAllocated background, bool inSelection, bool inHotspot, 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 (inHotspot) + return vsDraw.hotspotBackground.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 +1966,93 @@ 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); + } + 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) || + 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); + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, 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; + } } - for (int i = lineStart; i < lineEnd; i++) { + + 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) || + 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 +2062,27 @@ 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; + //hotspot foreground + if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) { + if (vsDraw.hotspotForegroundSet) + textFore = vsDraw.hotspotForeground.allocated; + } 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; } + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, 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 +2091,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 +2126,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 +2156,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 +2171,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 { @@ -1927,7 +2181,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } } } - if (vsDraw.styles[styleMain].underline) { + if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) { + PRectangle rcUL = rcSegment; + rcUL.top = rcUL.top + vsDraw.maxAscent + 1; + rcUL.bottom = rcUL.top + 1; + if (vsDraw.hotspotForegroundSet) + surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated); + else + surface->FillRectangle(rcUL, textFore); + } else if (vsDraw.styles[styleMain].underline) { PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; @@ -1964,31 +2226,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,47 +2239,48 @@ 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, wMain.GetID()); + // 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); - pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); + pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); PRectangle rcIG(0, 0, 1, vs.lineHeight); pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); @@ -2055,12 +2296,26 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (bufferedDraw) { if (!pixmapLine->Initialised()) { + PRectangle rcClient = GetClientRectangle(); pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(), - surfaceWindow); + surfaceWindow, wMain.GetID()); pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, - rcClient.Height(), surfaceWindow); + rcClient.Height(), surfaceWindow, wMain.GetID()); } } +} + +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 +2345,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 +2382,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface = pixmapLine; } surface->SetUnicodeMode(IsUnicodeMode()); + surface->SetDBCSMode(CodePage()); int visibleLine = topLine + screenLinePaintFirst; @@ -2140,7 +2404,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 +2417,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; } @@ -2170,6 +2433,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { ll->containsCaret = false; } + GetHotSpotRange(ll->hsStart, ll->hsEnd); + PRectangle rcLine = rcClient; rcLine.top = ypos; rcLine.bottom = ypos + vs.lineHeight; @@ -2177,7 +2442,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 +2452,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 +2551,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 +2565,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { visibleLine++; //gdk_flush(); } - llc.Dispose(ll); //if (durPaint < 0.00000001) // durPaint = 0.00000001; @@ -2307,10 +2613,10 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; - AutoSurface surface(pfr->hdc, IsUnicodeMode()); + AutoSurface surface(pfr->hdc, this); if (!surface) return 0; - AutoSurface surfaceMeasure(pfr->hdcTarget, IsUnicodeMode()); + AutoSurface surfaceMeasure(pfr->hdcTarget, this); if (!surfaceMeasure) { return 0; } @@ -2364,8 +2670,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 +2679,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 +2694,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 - while (line <= linePrintLast && ypos < pfr->rc.bottom) { - - // 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(); + int lineDoc = linePrintStart; + + int nPrintPos = pfr->chrg.cpMin; + int visibleLine = 0; + int widthPrint = pfr->rc.Width() - lineNumberWidth; + if (printWrapState == eWrapNone) + widthPrint = LineLayout::wrapWidthInfinite; + + while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { + + // 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(); + + // 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); + + 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; + } + } - // 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; - - PRectangle rcLine; - rcLine.left = pfr->rc.left + lineNumberWidth; - rcLine.top = ypos; - rcLine.right = pfr->rc.right; - rcLine.bottom = ypos + vsPrint.lineHeight; - - 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); + if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) { + visibleLine = -(ll.lines - 1); } + } - // Draw the line + 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(); - DrawLine(surface, vsPrint, line, line, xStart, rcLine, &ll); - - ypos += vsPrint.lineHeight; - line++; + 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(this); if (surface) { return surface->WidthText(vs.styles[style].font, text, strlen(text)); } else { @@ -2451,8 +2797,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 +2844,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 (currentPos < (pdoc->Length() - 1)) { - if ((pdoc->CharAt(currentPos) != '\r') && (pdoc->CharAt(currentPos) != '\n')) { + if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) { + if (currentPos < (pdoc->Length())) { + if (!IsEOLChar(pdoc->CharAt(currentPos))) { pdoc->DelChar(currentPos); } } @@ -2516,7 +2861,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 +2887,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,30 +2898,32 @@ 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 (!SelectionContainsProtected()) { + 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) { + pdoc->BeginUndoAction(); pdoc->DeleteChars(startPos, chars); + pdoc->EndUndoAction(); } } - 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 +2950,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 +2966,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 +2995,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 +3032,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 { @@ -2764,6 +3117,24 @@ void Editor::NotifyDoubleClick(Point, bool) { NotifyParent(scn); } +void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) { + SCNotification scn; + scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; + scn.position = position; + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0); + NotifyParent(scn); +} + +void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) { + SCNotification scn; + scn.nmhdr.code = SCN_HOTSPOTCLICK; + scn.position = position; + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0); + NotifyParent(scn); +} + void Editor::NotifyUpdateUI() { SCNotification scn; scn.nmhdr.code = SCN_UPDATEUI; @@ -2841,23 +3212,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(this); + 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 +3374,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: @@ -3013,8 +3384,12 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_SEARCHPREV: case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: + case SCI_PARADOWN: + case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: + case SCI_PARAUP: + case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: @@ -3031,6 +3406,10 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: + case SCI_HOMEWRAP: + case SCI_HOMEWRAPEXTEND: + case SCI_LINEENDWRAP: + case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: @@ -3047,6 +3426,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: + case SCI_VCHOMEWRAP: + case SCI_VCHOMEWRAPEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: case SCI_DELLINELEFT: @@ -3054,6 +3435,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 +3452,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 +3536,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 +3571,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 +3589,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(this); + 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 { @@ -3234,6 +3626,12 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_LINEDOWNEXTEND: CursorUpOrDown(1, true); break; + case SCI_PARADOWN: + MovePositionTo(pdoc->ParaDown(currentPos)); + break; + case SCI_PARADOWNEXTEND: + MovePositionTo(pdoc->ParaDown(currentPos), true); + break; case SCI_LINESCROLLDOWN: ScrollTo(topLine + 1); MoveCaretInsideView(false); @@ -3244,6 +3642,12 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_LINEUPEXTEND: CursorUpOrDown(-1, true); break; + case SCI_PARAUP: + MovePositionTo(pdoc->ParaUp(currentPos)); + break; + case SCI_PARAUPEXTEND: + MovePositionTo(pdoc->ParaUp(currentPos), true); + break; case SCI_LINESCROLLUP: ScrollTo(topLine - 1); MoveCaretInsideView(false); @@ -3304,6 +3708,38 @@ int Editor::KeyCommand(unsigned int iMessage) { MovePositionTo(pdoc->LineEndPosition(currentPos), true); SetLastXChosen(); break; + case SCI_HOMEWRAP: { + int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if (currentPos <= homePos) + homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos)); + MovePositionTo(homePos); + SetLastXChosen(); + } + break; + case SCI_HOMEWRAPEXTEND: { + int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if (currentPos <= homePos) + homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos)); + MovePositionTo(homePos, true); + SetLastXChosen(); + } + break; + case SCI_LINEENDWRAP: { + int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1); + if (currentPos >= endPos) + endPos = pdoc->LineEndPosition(currentPos); + MovePositionTo(endPos); + SetLastXChosen(); + } + break; + case SCI_LINEENDWRAPEXTEND: { + int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1); + if (currentPos >= endPos) + endPos = pdoc->LineEndPosition(currentPos); + MovePositionTo(endPos, true); + SetLastXChosen(); + } + break; case SCI_DOCUMENTSTART: MovePositionTo(0); SetLastXChosen(); @@ -3321,10 +3757,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 +3774,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; @@ -3376,6 +3812,26 @@ int Editor::KeyCommand(unsigned int iMessage) { MovePositionTo(pdoc->VCHomePosition(currentPos), true); SetLastXChosen(); break; + case SCI_VCHOMEWRAP: { + int homePos = pdoc->VCHomePosition(currentPos); + int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if ((viewLineStart < currentPos) && (viewLineStart > homePos)) + homePos = viewLineStart; + + MovePositionTo(homePos); + SetLastXChosen(); + } + break; + case SCI_VCHOMEWRAPEXTEND: { + int homePos = pdoc->VCHomePosition(currentPos); + int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1); + if ((viewLineStart < currentPos) && (viewLineStart > homePos)) + homePos = viewLineStart; + + MovePositionTo(homePos, true); + SetLastXChosen(); + } + break; case SCI_ZOOMIN: if (vs.zoomLevel < 20) { vs.zoomLevel++; @@ -3438,6 +3894,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 +3921,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,8 +4051,8 @@ 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, - ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. + uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range. TextToFind *ft = reinterpret_cast(lParam); @@ -3603,6 +4062,7 @@ long Editor::FindText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { ft->chrgText.cpMin = pos; @@ -3632,8 +4092,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. @@ -3646,6 +4106,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } else { pos = pdoc->FindText(searchAnchor, 0, txt, @@ -3653,6 +4114,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } @@ -3674,6 +4136,7 @@ long Editor::SearchInTarget(const char *text, int length) { (searchFlags & SCFIND_WHOLEWORD) != 0, (searchFlags & SCFIND_WORDSTART) != 0, (searchFlags & SCFIND_REGEXP) != 0, + (searchFlags & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { targetStart = pos; @@ -3943,7 +4406,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b SetEmptySelection(newPos); bool doubleClick = false; // Stop mouse button bounce changing selection type - if (curTime != lastClickTime) { + if (!Platform::MouseButtonBounce() || curTime != lastClickTime) { if (selectionType == selChar) { selectionType = selWord; doubleClick = true; @@ -3967,13 +4430,15 @@ 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); - if (doubleClick) + if (doubleClick) { NotifyDoubleClick(pt, shift); + if (PositionIsHotspot(newPos)) + NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt); + } } else { // Single click if (inSelMargin) { selType = selStream; @@ -4003,6 +4468,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b SetMouseCapture(true); selectionType = selLine; } else { + if (PositionIsHotspot(newPos)) { + NotifyHotSpotClicked(newPos, shift, ctrl, alt); + } if (!shift) { inDragDrop = PointInSelection(pt); } @@ -4029,6 +4497,53 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b ShowCaretAtCurrentPosition(); } +bool Editor::PositionIsHotspot(int position) { + return vs.styles[pdoc->StyleAt(position)].hotspot; +} + +bool Editor::PointIsHotspot(Point pt) { + int pos = PositionFromLocation(pt); + return PositionIsHotspot(pos); +} + +void Editor::SetHotSpotRange(Point *pt) { + if (pt) { + int pos = PositionFromLocation(*pt); + + // If we don't limit this to word characters then the + // range can encompass more than the run range and then + // the underline will not be drawn properly. + int hsStart_ = pdoc->ExtendStyleRange(pos, -1); + int hsEnd_ = pdoc->ExtendStyleRange(pos, 1); + + // Only invalidate the range if the hotspot range has changed... + if (hsStart_ != hsStart || hsEnd_ != hsEnd) { + if (hsStart != -1) { + InvalidateRange(hsStart, hsEnd); + } + hsStart = hsStart_; + hsEnd = hsEnd_; + InvalidateRange(hsStart, hsEnd); + } + } else { + if (hsStart != -1) { + int hsStart_ = hsStart; + int hsEnd_ = hsEnd; + hsStart = -1; + hsEnd = -1; + InvalidateRange(hsStart_, hsEnd_); + } else { + hsStart = -1; + hsEnd = -1; + } + } +} + +void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) { + hsStart_ = hsStart; + hsEnd_ = hsEnd; +} + void Editor::ButtonMove(Point pt) { if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { DwellEnd(true); @@ -4072,6 +4587,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) { @@ -4081,6 +4599,9 @@ void Editor::ButtonMove(Point pt) { } EnsureCaretVisible(false, false, true); + if (hsStart != -1 && !PositionIsHotspot(movePos)) + SetHotSpotRange(NULL); + } else { if (vs.fixedColumnWidth > 0) { // There is a margin if (PointInSelMargin(pt)) { @@ -4089,10 +4610,15 @@ void Editor::ButtonMove(Point pt) { } } // Display regular (drag) cursor over selection - if (PointInSelection(pt)) + if (PointInSelection(pt)) { DisplayCursor(Window::cursorArrow); - else + } else if (PointIsHotspot(pt)) { + DisplayCursor(Window::cursorHand); + SetHotSpotRange(&pt); + } else { DisplayCursor(Window::cursorText); + SetHotSpotRange(NULL); + } } } @@ -4104,6 +4630,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { DisplayCursor(Window::cursorReverseArrow); } else { DisplayCursor(Window::cursorText); + SetHotSpotRange(NULL); } xEndSelect = pt.x - vs.fixedColumnWidth + xOffset; ptMouseLast = pt; @@ -4117,7 +4644,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 +4696,8 @@ void Editor::Tick() { } } if ((dwellDelay < SC_TIME_FOREVER) && - (ticksToDwell > 0) && - (!HaveMouseCapture())) { + (ticksToDwell > 0) && + (!HaveMouseCapture())) { ticksToDwell -= timer.tickSize; if (ticksToDwell <= 0) { dwelling = true; @@ -4185,6 +4712,7 @@ void Editor::SetFocusState(bool focusState) { if (hasFocus) { ShowCaretAtCurrentPosition(); } else { + CancelModes(); DropCaret(); } } @@ -4329,6 +4857,13 @@ void Editor::SetDocPointer(Document *document) { pdoc = document; } pdoc->AddRef(); + + // Ensure all positions within document + currentPos = 0; + anchor = 0; + targetStart = 0; + targetEnd = 0; + // Reset the contraction state to fully shown. cs.Clear(); cs.InsertLines(0, pdoc->LinesTotal() - 1); @@ -4337,7 +4872,10 @@ void Editor::SetDocPointer(Document *document) { pdoc->AddWatcher(this, 0); Redraw(); - SetScrollBars(); + // Removed because of reentrance problems of GTK+ 2.x + // where changing a scroll bar position causes synchronous + // painting before lexer and styling state is set up. + //SetScrollBars(); } // Recursively expand a fold, making lines visible except where they have an unexpanded parent @@ -4407,7 +4945,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 +4982,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 +5006,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 +5019,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 +5136,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 +5170,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 +5206,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 +5321,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 +5410,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 +5517,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 +5530,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,8 +5629,16 @@ 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(wParam <= STYLE_MAX); PLATFORM_ASSERT(lParam); return TextWidth(wParam, CharPtrFromSPtr(lParam)); @@ -5061,7 +5646,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 +5670,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 +5770,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); @@ -5305,6 +5909,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); } break; + case SCI_STYLESETHOTSPOT: + if (wParam <= STYLE_MAX) { + vs.styles[wParam].hotspot = lParam != 0; + InvalidateStyleRedraw(); + } + break; case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); @@ -5412,10 +6022,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 +6080,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 @@ -5516,8 +6128,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: + case SCI_PARADOWN: + case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: + case SCI_PARAUP: + case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: @@ -5530,6 +6146,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: + case SCI_HOMEWRAP: + case SCI_HOMEWRAPEXTEND: + case SCI_LINEENDWRAP: + case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: @@ -5547,6 +6167,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: + case SCI_VCHOMEWRAP: + case SCI_VCHOMEWRAPEXTEND: case SCI_ZOOMIN: case SCI_ZOOMOUT: case SCI_DELWORDLEFT: @@ -5556,6 +6178,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: @@ -5629,12 +6252,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return reinterpret_cast(pdoc); case SCI_SETDOCPOINTER: + CancelModes(); SetDocPointer(reinterpret_cast(lParam)); return 0; case SCI_CREATEDOCUMENT: { Document *doc = new Document(); - doc->AddRef(); + if (doc) { + doc->AddRef(); + } return reinterpret_cast(doc); } @@ -5716,6 +6342,35 @@ 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; + + case SCI_SETHOTSPOTACTIVEFORE: + vs.hotspotForegroundSet = wParam != 0; + vs.hotspotForeground.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + + case SCI_SETHOTSPOTACTIVEBACK: + vs.hotspotBackgroundSet = wParam != 0; + vs.hotspotBackground.desired = ColourDesired(lParam); + InvalidateStyleRedraw(); + break; + + case SCI_SETHOTSPOTACTIVEUNDERLINE: + vs.hotspotUnderline = wParam != 0; + InvalidateStyleRedraw(); + break; + default: return DefWndProc(iMessage, wParam, lParam); } diff --git a/src/stc/scintilla/src/Editor.h b/src/stc/scintilla/src/Editor.h index 800630bbb0..2cc7930c47 100644 --- a/src/stc/scintilla/src/Editor.h +++ b/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 @@ -58,6 +58,10 @@ public: int *positions; char bracePreviousStyles[2]; + // Hotspot support + int hsStart; + int hsEnd; + // Wrapped line support int widthLine; int lines; @@ -131,38 +135,6 @@ public: } }; -/** - * A smart pointer class to ensure Surfaces are set up and deleted correctly. - */ -class AutoSurface { -private: - Surface *surf; -public: - AutoSurface(bool unicodeMode) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(); - surf->SetUnicodeMode(unicodeMode); - } - } - AutoSurface(SurfaceID sid, bool unicodeMode) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(sid); - surf->SetUnicodeMode(unicodeMode); - } - } - ~AutoSurface() { - delete surf; - } - Surface *operator->() const { - return surf; - } - operator Surface *() const { - return surf; - } -}; - /** */ class Editor : public DocWatcher { @@ -184,6 +156,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int printMagnification; int printColourMode; + int printWrapState; int cursorMode; int controlCharSymbol; @@ -196,11 +169,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; @@ -275,6 +252,10 @@ protected: // ScintillaBase subclass needs access to much of Editor int foldFlags; ContractionState cs; + // Hotspot support + int hsStart; + int hsEnd; + // Wrapping support enum { eWrapNone, eWrapWord } wrapState; int wrapWidth; @@ -321,12 +302,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 +321,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, bool inHotspot, 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); @@ -385,6 +376,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, bool shift); + void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); + void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyUpdateUI(); void NotifyPainted(); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); @@ -403,6 +396,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 +450,13 @@ 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); + bool PositionIsHotspot(int position); + bool PointIsHotspot(Point pt); + void SetHotSpotRange(Point *pt); + void GetHotSpotRange(int& hsStart, int& hsEnd); + + int CodePage() const; + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; public: @@ -465,6 +466,45 @@ public: virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); // Public so scintilla_set_id can use it. int ctrlID; + friend class AutoSurface; +}; + +/** + * A smart pointer class to ensure Surfaces are set up and deleted correctly. + */ +class AutoSurface { +private: + Surface *surf; +public: + AutoSurface(Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + AutoSurface(SurfaceID sid, Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(sid, ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + ~AutoSurface() { + delete surf; + } + Surface *operator->() const { + return surf; + } + operator Surface *() const { + return surf; + } }; #endif diff --git a/src/stc/scintilla/src/KeyMap.cxx b/src/stc/scintilla/src/KeyMap.cxx index c91e6c6ccc..12249e5f3c 100644 --- a/src/stc/scintilla/src/KeyMap.cxx +++ b/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); } @@ -66,9 +66,13 @@ const KeyToCommand KeyMap::MapDefault[] = { {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_ALT, SCI_PARADOWN}, + {SCK_DOWN, SCI_ASHIFT, SCI_PARADOWNEXTEND}, {SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, + {SCK_UP, SCI_ALT, SCI_PARAUP}, + {SCK_UP, SCI_ASHIFT, SCI_PARAUPEXTEND}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_CTRL, SCI_WORDLEFT}, @@ -109,7 +113,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 +131,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/src/stc/scintilla/src/KeyWords.cxx b/src/stc/scintilla/src/KeyWords.cxx index 8a03aa8ac4..73ecddf50d 100644 --- a/src/stc/scintilla/src/KeyWords.cxx +++ b/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); @@ -166,6 +171,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmLatex); LINK_LEXER(lmPascal); LINK_LEXER(lmPerl); + LINK_LEXER(lmPOV); LINK_LEXER(lmPython); LINK_LEXER(lmRuby); LINK_LEXER(lmSQL); diff --git a/src/stc/scintilla/src/LexAVE.cxx b/src/stc/scintilla/src/LexAVE.cxx index dfd15f02f1..900aea317c 100644 --- a/src/stc/scintilla/src/LexAVE.cxx +++ b/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]; + + // Do not leak onto next line + if (initStyle == SCE_AVE_STRINGEOL) { + initStyle = SCE_AVE_DEFAULT; + } - styler.StartAt(startPos); + StyleContext sc(startPos, length, initStyle, styler); - bool fold = styler.GetPropertyInt("fold") != 0; - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + 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); + } - 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); - 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; + // 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); } - 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; + } else if (sc.state == SCE_AVE_ENUM) { + if (!IsEnumChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); } - visibleChars = 0; - } - if (!isspace(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 (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 (state == SCE_AVE_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; + } else if (sc.state == SCE_AVE_COMMENT) { + if (sc.atLineEnd) { + sc.SetState(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 (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); } } - 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; + + // 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(); } } - 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; - } + } + sc.Complete(); +} - 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; - } +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; + char chNext = static_cast(tolower(styler[startPos])); + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + int styleNext = styler.StyleAt(startPos); + char s[10]; - if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0)) - { - chAttr = SCE_AVE_KEYWORD; + for (unsigned int i = startPos; i < lengthDoc; i++) { + 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 (keywords.InList(s)) - { - chAttr = SCE_AVE_WORD; - } + if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { + levelCurrent++; } - 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); + if ((strcmp(s, "end") == 0)) { + levelCurrent--; } } + } 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; + visibleChars = 0; + } + if (!isspacechar(ch)) { + visibleChars++; + } } - 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/src/stc/scintilla/src/LexAda.cxx b/src/stc/scintilla/src/LexAda.cxx index 0d8fb9d5dd..263f7da456 100644 --- a/src/stc/scintilla/src/LexAda.cxx +++ b/src/stc/scintilla/src/LexAda.cxx @@ -1,198 +1,520 @@ -// 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" + +/* + * Interface + */ + +static void ColouriseDocument( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler); + +static const char * const adaWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc); + +/* + * 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); -inline void classifyWordAda(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { +static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { + apostropheStartsAttribute = true; - static const unsigned KEWORD_LEN_MAX = 30; + sc.SetState(SCE_ADA_CHARACTER); - 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])); + // 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(); } - wordLower[i] = '\0'; - -// int levelChange = 0; - char chAttr = SCE_ADA_IDENTIFIER; - if (keywords.InList(wordLower)) { - chAttr = SCE_ADA_WORD; -// 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; + if (!sc.atLineEnd) { + sc.ForwardSetState(SCE_ADA_DEFAULT); + } else { + sc.ChangeState(stateEOL); } - styler.ColourTo(end, chAttr); - -// return levelChange; } +static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { + // Apostrophe meaning is not changed, but the parameter is present for uniformity -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); - } -} - - -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); - - 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; + + StyleContext sc(startPos, length, initStyle, styler); + + int lineCurrent = styler.GetLine(startPos); + bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; + + 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 (!isspacechar(ch)) - // visibleChars++; - if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; + // 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); + } + } + + sc.Complete(); +} + +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; + } - 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); + // 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; } - } else if (state == SCE_ADA_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_ADA_DEFAULT; + } + + 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; } - } 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; + } + + 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; } - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_ADA_STRINGEOL); - state = SCE_ADA_STRINGEOL; + canBeSpecial = true; + + } else if (ch == '#' && canBeSpecial) { + break; + + } else { + return false; } - } 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; + } + + 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 } - } 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); + } + + 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; } - 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); -// } + // if i == length, number was parsed successfully. + return i == length; +} + +static inline bool IsWordCharacter(int ch) { + return IsWordStartCharacter(ch) || isdigit(ch); } -LexerModule lmAda(SCLEX_ADA, ColouriseAdaDoc, "ada"); +static inline bool IsWordStartCharacter(int ch) { + return isalpha(ch) || ch == '_'; +} diff --git a/src/stc/scintilla/src/LexAsm.cxx b/src/stc/scintilla/src/LexAsm.cxx new file mode 100644 index 0000000000..1eecf9b31a --- /dev/null +++ b/src/stc/scintilla/src/LexAsm.cxx @@ -0,0 +1,142 @@ +// 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(); +} + +static const char * const asmWordListDesc[] = { + "CPU instructions", + "FPU instructions", + "Registers", + "Directives", + "Directive operands", + 0 +}; + +LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc); + diff --git a/src/stc/scintilla/src/LexBullant.cxx b/src/stc/scintilla/src/LexBullant.cxx index 1f76ffcf00..902f89c1e4 100644 --- a/src/stc/scintilla/src/LexBullant.cxx +++ b/src/stc/scintilla/src/LexBullant.cxx @@ -30,18 +30,6 @@ static int classifyWordBullant(unsigned int start, unsigned int end, WordList &k else { if (keywords.InList(s)) { chAttr = SCE_C_WORD; -/* if (strcmp(s, "end method") == 0 || - strcmp(s, "end case") == 0 || - strcmp(s, "end class") == 0 || - strcmp(s, "end debug") == 0 || - strcmp(s, "end test") == 0 || - strcmp(s, "end if") == 0 || - strcmp(s, "end lock") == 0 || - strcmp(s, "end transaction") == 0 || - strcmp(s, "end trap") == 0 || - strcmp(s, "end until") == 0 || - strcmp(s, "end while") == 0) - lev = -1;*/ if (strcmp(s, "end") == 0) lev = -1; else if (strcmp(s, "method") == 0 || @@ -80,7 +68,6 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int visibleChars = 0; - // int blockChange = 0; styler.StartSegment(startPos); int endFoundThisLine = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { @@ -230,4 +217,9 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle } } -LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant"); +static const char * const bullantWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc); diff --git a/src/stc/scintilla/src/LexCPP.cxx b/src/stc/scintilla/src/LexCPP.cxx index 39f458da73..661b968cd7 100644 --- a/src/stc/scintilla/src/LexCPP.cxx +++ b/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 == '_' || ch >= 161); // _ is not in fact correct CSS word-character +} + +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_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) { + if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\'')) + continue; + unsigned int i = sc.currentPos; + while (i && styler[i-1] == '\\') + i--; + if ((sc.currentPos - i) % 2 == 1) + continue; + sc.ForwardSetState(SCE_CSS_VALUE); + } + + 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_PSEUDOCLASS || 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_ID)) + sc.SetState(SCE_CSS_TAG); + + if (sc.Match('/', '*')) { + lastStateC = sc.state; + sc.SetState(SCE_CSS_COMMENT); + sc.Forward(); + } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) { + sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING)); + } else 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); +} + +static const char * const cssWordListDesc[] = { + "Keywords", + "Pseudo classes", + 0 +}; + +LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc); diff --git a/src/stc/scintilla/src/LexConf.cxx b/src/stc/scintilla/src/LexConf.cxx index c8441f41ec..c33cdb5ce6 100644 --- a/src/stc/scintilla/src/LexConf.cxx +++ b/src/stc/scintilla/src/LexConf.cxx @@ -175,4 +175,10 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k delete []buffer; } -LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf"); +static const char * const confWordListDesc[] = { + "Directives", + "Parameters", + 0 +}; + +LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc); diff --git a/src/stc/scintilla/src/LexCrontab.cxx b/src/stc/scintilla/src/LexCrontab.cxx index 37729cbfdd..d139bb4f14 100644 --- a/src/stc/scintilla/src/LexCrontab.cxx +++ b/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; @@ -208,4 +208,11 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi delete []buffer; } -LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab"); +static const char * const cronWordListDesc[] = { + "Section keywords and Forth words", + "nnCrontab keywords", + "Modifiers", + 0 +}; + +LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc); diff --git a/src/stc/scintilla/src/LexEiffel.cxx b/src/stc/scintilla/src/LexEiffel.cxx index a0bf26a5ea..974efd9a72 100644 --- a/src/stc/scintilla/src/LexEiffel.cxx +++ b/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; } @@ -226,5 +226,10 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent); -LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords); +static const char * const eiffelWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc); +LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc); diff --git a/src/stc/scintilla/src/LexFortran.cxx b/src/stc/scintilla/src/LexFortran.cxx new file mode 100644 index 0000000000..e2109a0ab5 --- /dev/null +++ b/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/src/stc/scintilla/src/LexHTML.cxx b/src/stc/scintilla/src/LexHTML.cxx index 545bbfd553..345b15edcb 100644 --- a/src/stc/scintilla/src/LexHTML.cxx +++ b/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/src/stc/scintilla/src/LexLisp.cxx b/src/stc/scintilla/src/LexLisp.cxx index cb150ff76d..9cd5433c89 100644 --- a/src/stc/scintilla/src/LexLisp.cxx +++ b/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) { @@ -192,4 +192,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc); +static const char * const lispWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc); diff --git a/src/stc/scintilla/src/LexLua.cxx b/src/stc/scintilla/src/LexLua.cxx index fc9607e25d..159bc1585d 100644 --- a/src/stc/scintilla/src/LexLua.cxx +++ b/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; @@ -266,4 +297,14 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc); +static const char * const luaWordListDesc[] = { + "Keywords", + "Basic functions", + "String & math functions", + "I/O & system facilities", + "XXX", + "XXX", + 0 +}; + +LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc); diff --git a/src/stc/scintilla/src/LexMatlab.cxx b/src/stc/scintilla/src/LexMatlab.cxx index f75d15c7ab..5f4dff3b8e 100644 --- a/src/stc/scintilla/src/LexMatlab.cxx +++ b/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. @@ -165,4 +165,9 @@ static void FoldMatlabDoc(unsigned int startPos, int length, int, } } -LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc); +static const char * const matlabWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc); diff --git a/src/stc/scintilla/src/LexOthers.cxx b/src/stc/scintilla/src/LexOthers.cxx index babb3a0d37..6d537c9b6c 100644 --- a/src/stc/scintilla/src/LexOthers.cxx +++ b/src/stc/scintilla/src/LexOthers.cxx @@ -20,6 +20,14 @@ #include "Scintilla.h" #include "SciLexer.h" +static bool Is0To9(char ch) { + return (ch >= '0') && (ch <= '9'); +} + +static bool Is1To9(char ch) { + return (ch >= '1') && (ch <= '9'); +} + static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); @@ -85,7 +93,7 @@ static void ColouriseBatchLine( while (offset < lengthLine) { if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset - 1, state); - if (isdigit(lineBuffer[offset + 1])) { + if (Is0To9(lineBuffer[offset + 1])) { styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); offset += 2; } else if (lineBuffer[offset + 1] == '%' && @@ -164,13 +172,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 +276,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 +303,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 @@ -337,12 +351,17 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[ } } +static bool strstart(char *haystack, char *needle) { + return strncmp(haystack, needle, strlen(needle)) == 0; +} + static void ColouriseErrorListLine( char *lineBuffer, unsigned int lengthLine, // unsigned int startLine, unsigned int endPos, Accessor &styler) { + const int unRecognized = 99; if (lineBuffer[0] == '>') { // Command or return status styler.ColourTo(endPos, SCE_ERR_CMD); @@ -359,10 +378,19 @@ 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 (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { + } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { + styler.ColourTo(endPos, SCE_ERR_PHP); + } else if ((strstart(lineBuffer, "Error ") || + strstart(lineBuffer, "Warning ")) && + strstr(lineBuffer, " at (") && + strstr(lineBuffer, ") : ") && + (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { + // Intel Fortran Compiler error/warning message + styler.ColourTo(endPos, SCE_ERR_IFC); + } else if (strstart(lineBuffer, "Error ")) { // Borland error message styler.ColourTo(endPos, SCE_ERR_BORLAND); - } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { + } else if (strstart(lineBuffer, "Warning ")) { // Borland warning message styler.ColourTo(endPos, SCE_ERR_BORLAND); } else if (strstr(lineBuffer, "at line " ) && @@ -374,54 +402,87 @@ static void ColouriseErrorListLine( } else if (strstr(lineBuffer, " at " ) && (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) && strstr(lineBuffer, " line ") && - (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine))) { + (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && + (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) { // perl error message styler.ColourTo(endPos, SCE_ERR_PERL); } else if ((memcmp(lineBuffer, " at ", 6) == 0) && strstr(lineBuffer, ":line ")) { // A .NET traceback styler.ColourTo(endPos, SCE_ERR_NET); + } else if (strstart(lineBuffer, "Line ") && + strstr(lineBuffer, ", file ")) { + // Essential Lahey Fortran error message + styler.ColourTo(endPos, SCE_ERR_ELF); } else { - // Look for ::message - // Look for (line)message - // Look for (line,pos)message + // Look for GCC ::message + // Look for Microsoft (line) :message + // Look for Microsoft (line,pos)message + // Look for CTags \tmessage int state = 0; for (unsigned int i = 0; i < lengthLine; i++) { - if ((state == 0) && (lineBuffer[i] == ':') && isdigit(lineBuffer[i + 1])) { - state = 1; - } else if ((state == 0) && (lineBuffer[i] == '(')) { - state = 10; - } else if ((state == 0) && (lineBuffer[i] == '\t')) { - state = 20; - } else if ((state == 1) && isdigit(lineBuffer[i])) { - state = 2; - } else if ((state == 2) && (lineBuffer[i] == ':')) { - state = 3; - break; - } else if ((state == 2) && !isdigit(lineBuffer[i])) { - state = 99; - } else if ((state == 10) && isdigit(lineBuffer[i])) { - state = 11; - } else if ((state == 11) && (lineBuffer[i] == ',')) { - state = 14; - } else if ((state == 11) && (lineBuffer[i] == ')')) { - state = 12; - } else if ((state == 12) && (lineBuffer[i] == ':')) { - state = 13; - } else if ((state == 14) && (lineBuffer[i] == ')')) { - state = 15; - break; - } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { - state = 99; - } else if ((state == 20) && (lineBuffer[i-1] == '\t') && - ((lineBuffer[i] == '/' && lineBuffer[i+1] == '^') || isdigit(lineBuffer[i]))) { - state = 24; - break; - } else if ((state == 20) && ((lineBuffer[i] == '/') && (lineBuffer[i+1] == '^'))) { - state = 21; + char ch = lineBuffer[i]; + char chNext = ' '; + if ((i+1) < lengthLine) + chNext = lineBuffer[i+1]; + if (state == 0) { + if (ch == ':') { + // May be GCC + if ((chNext != '\\') && (chNext != '/')) { + // This check is not completely accurate as may be on + // GTK+ with a file name that includes ':'. + state = 1; + } + } else if ((ch == '(') && Is1To9(chNext)) { + // May be Microsoft + // Check againt '0' often removes phone numbers + state = 10; + } else if (ch == '\t') { + // May be CTags + state = 20; + } + } else if (state == 1) { + state = Is1To9(ch) ? 2 : unRecognized; + } else if (state == 2) { + if (ch == ':') { + state = 3; // :9.*: is GCC + break; + } else if (!Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 10) { + state = Is0To9(ch) ? 11 : unRecognized; + } else if (state == 11) { + if (ch == ',') { + state = 14; + } else if (ch == ')') { + state = 12; + } else if ((ch != ' ') && !Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 12) { + if ((ch == ' ') && (chNext == ':')) + state = 13; + else + state = unRecognized; + } else if (state == 14) { + if (ch == ')') { + state = 15; + break; + } else if ((ch != ' ') && !Is0To9(ch)) { + state = unRecognized; + } + } else if (state == 20) { + if ((lineBuffer[i-1] == '\t') && + ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) { + state = 24; + break; + } else if ((ch == '/') && (lineBuffer[i+1] == '^')) { + state = 21; + } } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) { state = 22; - break; + break; } } if (state == 3) { @@ -429,7 +490,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); } @@ -553,12 +614,21 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, } } } - styler.ColourTo(lengthDoc, state); + styler.ColourTo(lengthDoc-1, state); } -LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch"); -LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff"); -LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props"); -LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile"); -LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist"); -LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex"); +static const char * const batchWordListDesc[] = { + "Keywords", + 0 +}; + +static const char * const emptyWordListDesc[] = { + 0 +}; + +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc); +LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", 0, emptyWordListDesc); +LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", 0, emptyWordListDesc); +LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); +LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc); diff --git a/src/stc/scintilla/src/LexPOV.cxx b/src/stc/scintilla/src/LexPOV.cxx new file mode 100644 index 0000000000..1e44450bbc --- /dev/null +++ b/src/stc/scintilla/src/LexPOV.cxx @@ -0,0 +1,222 @@ +// Scintilla source code edit control +/** @file LexPOV.cxx + ** Lexer for POV-Ray, based on lexer for C++. + **/ +// Copyright 2003 by Steven te Brinke +// 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" + +#define KEYWORD_BOXHEADER 1 +#define KEYWORD_FOLDCONTRACTED 2 + +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) || ch == '_'); +} + +static inline bool IsStateComment(const int state) { + return ((state == SCE_POV_COMMENT) || + (state == SCE_POV_COMMENTLINE) || + (state == SCE_POV_COMMENTDOC)); +} + +static inline bool IsStateString(const int state) { + return ((state == SCE_POV_STRING)); +} + +static void ColourisePOVDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + + // Do not leak onto next line + /*if (initStyle == SCE_POV_STRINGEOL) + initStyle = SCE_POV_DEFAULT;*/ + + StyleContext sc(startPos, length, initStyle, styler); + + bool caseSensitive = styler.GetPropertyInt("pov.case.sensitive", 1) != 0; + + for (; sc.More(); sc.Forward()) { + + /*if (sc.atLineStart && (sc.state == SCE_POV_STRING)) { + // Prevent SCE_POV_STRINGEOL from leaking back to previous line + sc.SetState(SCE_POV_STRING); + }*/ + + // Handle line continuation generically. + if (sc.ch == '\\') { + if (sc.chNext == '\n' || sc.chNext == '\r') { + sc.Forward(); + if (sc.ch == '\r' && sc.chNext == '\n') { + sc.Forward(); + } + continue; + } + } + + // Determine if the current state should terminate. + if (sc.state == SCE_POV_OPERATOR || sc.state == SCE_POV_BRACE) { + sc.SetState(SCE_POV_DEFAULT); + } else if (sc.state == SCE_POV_NUMBER) { + if (!IsADigit(sc.ch) || sc.ch != '.') { + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { + char s[100]; + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } + if (keywords.InList(s)) { + sc.ChangeState(SCE_POV_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_POV_WORD2); + } + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENT) { + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENTDOC) { + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_COMMENTLINE) { + if (sc.atLineEnd) { + sc.SetState(SCE_POV_DEFAULT); + } + } else if (sc.state == SCE_POV_STRING) { + if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_POV_DEFAULT); + } + } + + // Determine if a new state should be entered. + if (sc.state == SCE_POV_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_POV_NUMBER); + } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) { + sc.SetState(SCE_POV_IDENTIFIER); + } else if (sc.Match('/', '*')) { + sc.SetState(SCE_POV_COMMENT); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } else if (sc.Match('/', '/')) { + sc.SetState(SCE_POV_COMMENTLINE); + } else if (sc.ch == '\"') { + sc.SetState(SCE_POV_STRING); + //} else if (isoperator(static_cast(sc.ch))) { + } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') { + sc.SetState(SCE_POV_OPERATOR); + } else if (sc.ch == '{' || sc.ch == '}') { + sc.SetState(SCE_POV_BRACE); + } + } + + } + sc.Complete(); +} + +static bool IsStreamCommentStyle(int style) { + return style == SCE_POV_COMMENT || + style == SCE_POV_COMMENTDOC; +} + +static void FoldNoBoxPOVDoc(unsigned int startPos, int length, int initStyle, + Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 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); + int style = initStyle; + 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 (style == SCE_POV_BRACE) { + 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 void FoldPOVDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { + FoldNoBoxPOVDoc(startPos, length, initStyle, styler); +} + +static const char * const POVWordLists[] = { + "Primary keywords and identifiers", + "Secondary keywords and identifiers", + 0, + }; + +static void ColourisePOVDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + ColourisePOVDoc(startPos, length, initStyle, keywordlists, styler); +} + +LexerModule lmPOV(SCLEX_POV, ColourisePOVDocSensitive, "pov", FoldPOVDoc, POVWordLists); diff --git a/src/stc/scintilla/src/LexPascal.cxx b/src/stc/scintilla/src/LexPascal.cxx index 37e5e995fb..c3bea6773d 100644 --- a/src/stc/scintilla/src/LexPascal.cxx +++ b/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++; } @@ -339,4 +339,10 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc); +static const char * const pascalWordListDesc[] = { + "Keywords", + "Classwords", + 0 +}; + +LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc); diff --git a/src/stc/scintilla/src/LexPerl.cxx b/src/stc/scintilla/src/LexPerl.cxx index 1715009c9d..211c3b8751 100644 --- a/src/stc/scintilla/src/LexPerl.cxx +++ b/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", + "Keywords", 0 }; -LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", 0, perlWordListDesc); +LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc); diff --git a/src/stc/scintilla/src/LexPython.cxx b/src/stc/scintilla/src/LexPython.cxx index bfaa08f0e9..47974d1bce 100644 --- a/src/stc/scintilla/src/LexPython.cxx +++ b/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 @@ -409,9 +431,9 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse } static const char * const pythonWordListDesc[] = { - "Python keywords", + "Keywords", 0 }; -LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, +LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, pythonWordListDesc); diff --git a/src/stc/scintilla/src/LexRuby.cxx b/src/stc/scintilla/src/LexRuby.cxx index 35804e7107..43a874968d 100644 --- a/src/stc/scintilla/src/LexRuby.cxx +++ b/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,10 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle, } } } - -LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc); + +static const char * const rubyWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc); diff --git a/src/stc/scintilla/src/LexSQL.cxx b/src/stc/scintilla/src/LexSQL.cxx index 5af86d9f4a..0520c00ed6 100644 --- a/src/stc/scintilla/src/LexSQL.cxx +++ b/src/stc/scintilla/src/LexSQL.cxx @@ -155,4 +155,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, styler.ColourTo(lengthDoc - 1, state); } -LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql"); +static const char * const sqlWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc); diff --git a/src/stc/scintilla/src/LexVB.cxx b/src/stc/scintilla/src/LexVB.cxx index bd1248e044..72fdb9c3cf 100644 --- a/src/stc/scintilla/src/LexVB.cxx +++ b/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); @@ -116,7 +116,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, } else if (sc.ch == '#') { int n = 1; int chSeek = ' '; - while (chSeek == ' ' || chSeek == '\t') { + while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) { chSeek = sc.GetRelative(n); n++; } @@ -137,7 +137,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, sc.SetState(SCE_B_OPERATOR); } } - + if (sc.atLineEnd) { visibleChars = 0; } @@ -200,6 +200,11 @@ static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyl ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true); } -LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc); -LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc); +static const char * const vbWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc); +LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc); diff --git a/src/stc/scintilla/src/LineMarker.cxx b/src/stc/scintilla/src/LineMarker.cxx index 009ea4ea50..ec9c86f74f 100644 --- a/src/stc/scintilla/src/LineMarker.cxx +++ b/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/src/stc/scintilla/src/LineMarker.h b/src/stc/scintilla/src/LineMarker.h index 7897aa7759..ef5924f751 100644 --- a/src/stc/scintilla/src/LineMarker.h +++ b/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,35 @@ 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); + delete pxpm; + 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/src/stc/scintilla/src/PropSet.cxx b/src/stc/scintilla/src/PropSet.cxx index b527c385ce..18544aef23 100644 --- a/src/stc/scintilla/src/PropSet.cxx +++ b/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')) @@ -181,7 +185,8 @@ SString PropSet::GetExpanded(const char *key) { SString PropSet::Expand(const char *withVars) { char *base = StringDup(withVars); char *cpvar = strstr(base, "$("); - while (cpvar) { + int maxExpands = 1000; // Avoid infinite expansion of recursive definitions + while (cpvar && (maxExpands > 0)) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() @@ -197,6 +202,7 @@ SString PropSet::Expand(const char *withVars) { base = newbase; } cpvar = strstr(base, "$("); + maxExpands--; } SString sret = base; delete []base; @@ -257,7 +263,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); @@ -300,7 +306,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) { SString PropSet::GetNewExpand(const char *keybase, const char *filename) { char *base = StringDup(GetWild(keybase, filename).c_str()); char *cpvar = strstr(base, "$("); - while (cpvar) { + int maxExpands = 1000; // Avoid infinite expansion of recursive definitions + while (cpvar && (maxExpands > 0)) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() @@ -316,6 +323,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { base = newbase; } cpvar = strstr(base, "$("); + maxExpands--; } SString sret = base; delete []base; @@ -328,9 +336,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 +634,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 +677,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 +703,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/src/stc/scintilla/src/RESearch.cxx b/src/stc/scintilla/src/RESearch.cxx index f176bbf19e..656570a24b 100644 --- a/src/stc/scintilla/src/RESearch.cxx +++ b/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,23 @@ * Modification history: * * $Log$ - * Revision 1.5 2002/09/11 00:55:27 RD - * Update to Scintilla 1.48 + * Revision 1.6 2003/04/19 19:59:49 RD + * Updated Scintilla to 1.52 (on the trunk this time too) + * + * Revision 1.9 2003/03/21 10:36:08 nyamatongwe + * Detect patterns too long in regular expression search. + * + * Revision 1.8 2003/03/04 10:53:59 nyamatongwe + * Patch from Jakub to optionally implement more POSIX compatible regular + * expressions. \(..\) changes to (..) + * Fixes problem where find previous would not find earlier matches on same + * line. + * + * Revision 1.8 2003/03/03 20:12:56 vrana + * Added posix syntax. + * + * 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 +82,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 +122,7 @@ * void re_fail(msg, op) * char *msg; * char op; - * + * * Regular Expressions: * * [1] char matches itself, unless it is a special @@ -117,20 +132,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 +210,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 +221,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 +269,7 @@ const char bitarr[] = {1,2,4,8,16,32,64,'\200'}; #define badpat(x) (*nfa = END, x) - + RESearch::RESearch() { Init(); } @@ -332,10 +347,11 @@ const char escapeValue(char ch) { return 0; } -const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { +const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) { char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer.. */ char *sp=nfa; /* another one.. */ + char *mpMax = mp + MAXNFA - BITBLK - 10; int tagi = 0; /* tag stack index */ int tagc = 1; /* actual tag count */ @@ -343,7 +359,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; @@ -353,6 +369,8 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { const char *p=pat; /* pattern pointer */ for (int i=0; i mpMax) + return badpat("Pattern too long"); lp = mp; switch(*p) { @@ -383,7 +401,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; if (*++p == '^') { - mask = '\377'; + mask = '\377'; i++; p++; } else @@ -427,7 +445,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.. */ @@ -467,25 +485,6 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; switch(*++p) { - case '(': - if (tagc < MAXTAG) { - tagstk[++tagi] = tagc; - *mp++ = BOT; - *mp++ = static_cast(tagc++); - } - else - return badpat("Too many \\(\\) pairs"); - break; - case ')': - if (*sp == BOT) - return badpat("Null pattern inside \\(\\)"); - if (tagi > 0) { - *mp++ = static_cast(EOT); - *mp++ = static_cast(tagstk[tagi--]); - } - else - return badpat("Unmatched \\)"); - break; case '<': *mp++ = BOW; break; @@ -524,13 +523,49 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { *mp++ = escapeValue(*p); break; default: - *mp++ = CHR; - *mp++ = *p; + if (!posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast(tagc++); + } + else + return badpat("Too many \\(\\) pairs"); + } else if (!posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside \\(\\)"); + if (tagi > 0) { + *mp++ = static_cast(EOT); + *mp++ = static_cast(tagstk[tagi--]); + } + else + return badpat("Unmatched \\)"); + } else { + *mp++ = CHR; + *mp++ = *p; + } } break; default : /* an ordinary char */ - if (caseSensitive) { + if (posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast(tagc++); + } + else + return badpat("Too many () pairs"); + } else if (posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside ()"); + if (tagi > 0) { + *mp++ = static_cast(EOT); + *mp++ = static_cast(tagstk[tagi--]); + } + else + return badpat("Unmatched )"); + } else if (caseSensitive) { *mp++ = CHR; *mp++ = *p; } else { @@ -545,7 +580,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { sp = lp; } if (tagi > 0) - return badpat("Unmatched \\("); + return badpat((posix ? "Unmatched (" : "Unmatched \\(")); *mp = END; sta = OKP; return 0; @@ -555,7 +590,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 +615,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { bol = lp; failure = 0; - + Clear(); switch(*ap) { @@ -621,7 +656,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 +682,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 +693,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 +723,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 +831,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 +881,7 @@ int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) { pin = c - '0'; break; } - + default: *dst++ = c; continue; diff --git a/src/stc/scintilla/src/RESearch.h b/src/stc/scintilla/src/RESearch.h index 28238bfb7c..d676e0f318 100644 --- a/src/stc/scintilla/src/RESearch.h +++ b/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; }; @@ -32,7 +32,7 @@ public: bool GrabMatches(CharacterIndexer &ci); void ChSet(char c); void ChSetWithCase(char c, bool caseSensitive); - const char *Compile(const char *pat, int length, bool caseSensitive); + const char *Compile(const char *pat, int length, bool caseSensitive, bool posix); int Execute(CharacterIndexer &ci, int lp, int endp); void ModifyWord(char *s); int Substitute(CharacterIndexer &ci, char *src, char *dst); diff --git a/src/stc/scintilla/src/SVector.h b/src/stc/scintilla/src/SVector.h index c8edb513bc..9c3235d580 100644 --- a/src/stc/scintilla/src/SVector.h +++ b/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/src/stc/scintilla/src/ScintillaBase.cxx b/src/stc/scintilla/src/ScintillaBase.cxx index ab6e9a19b4..ea2e2d1d6d 100644 --- a/src/stc/scintilla/src/ScintillaBase.cxx +++ b/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,11 @@ void ScintillaBase::AutoCompleteCharacterDeleted() { } void ScintillaBase::AutoCompleteCompleted() { - int item = ac.lb.GetSelection(); + int item = ac.lb->GetSelection(); char selected[1000]; + selected[0] = '\0'; if (item != -1) { - ac.lb.GetValue(item, selected, sizeof(selected)); + ac.lb->GetValue(item, selected, sizeof(selected)); } ac.Cancel(); @@ -343,6 +345,36 @@ void ScintillaBase::AutoCompleteCompleted() { pdoc->EndUndoAction(); } +void ScintillaBase::CallTipShow(Point pt, const char *defn) { + AutoCompleteCancel(); + pt.y += vs.lineHeight; + PRectangle rc = ct.CallTipStart(currentPos, pt, + defn, + vs.styles[STYLE_DEFAULT].fontName, + vs.styles[STYLE_DEFAULT].sizeZoomed, + IsUnicodeMode(), + wMain); + // If the call-tip window would be out of the client + // space, adjust so it displays above the text. + PRectangle rcClient = GetClientRectangle(); + if (rc.bottom > rcClient.bottom) { + int offset = vs.lineHeight + rc.Height(); + rc.top -= offset; + rc.bottom -= offset; + } + // Now display the window. + CreateCallTipWindow(rc); + ct.wCallTip.SetPositionRelative(rc, wMain); + ct.wCallTip.Show(); +} + +void ScintillaBase::CallTipClick() { + SCNotification scn; + scn.nmhdr.code = SCN_CALLTIPCLICK; + scn.position = ct.clickPlace; + NotifyParent(scn); +} + void ScintillaBase::ContextMenu(Point pt) { if (displayPopupMenu) { bool writable = !WndProc(SCI_GETREADONLY, 0, 0); @@ -509,30 +541,24 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara case SCI_AUTOCGETDROPRESTOFWORD: return ac.dropRestOfWord; - case SCI_CALLTIPSHOW: { - AutoCompleteCancel(); - if (!ct.wCallTip.Created()) { - Point pt = LocationFromPosition(wParam); - pt.y += vs.lineHeight; - PRectangle rc = ct.CallTipStart(currentPos, pt, - reinterpret_cast(lParam), - vs.styles[STYLE_DEFAULT].fontName, - vs.styles[STYLE_DEFAULT].sizeZoomed, - IsUnicodeMode()); - // If the call-tip window would be out of the client - // space, adjust so it displays above the text. - PRectangle rcClient = GetClientRectangle(); - if (rc.bottom > rcClient.bottom) { - int offset = vs.lineHeight + rc.Height(); - rc.top -= offset; - rc.bottom -= offset; - } - // Now display the window. - CreateCallTipWindow(rc); - ct.wCallTip.SetPositionRelative(rc, wMain); - ct.wCallTip.Show(); - } - } + 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: + CallTipShow(LocationFromPosition(wParam), + reinterpret_cast(lParam)); break; case SCI_CALLTIPCANCEL: @@ -554,6 +580,16 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara InvalidateStyleRedraw(); break; + case SCI_CALLTIPSETFORE: + ct.colourUnSel = ColourDesired(wParam); + InvalidateStyleRedraw(); + break; + + case SCI_CALLTIPSETFOREHLT: + ct.colourSel = ColourDesired(wParam); + InvalidateStyleRedraw(); + break; + case SCI_USEPOPUP: displayPopupMenu = wParam != 0; break; diff --git a/src/stc/scintilla/src/ScintillaBase.h b/src/stc/scintilla/src/ScintillaBase.h index e68aeb6084..bf0b92d57d 100644 --- a/src/stc/scintilla/src/ScintillaBase.h +++ b/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); @@ -71,6 +71,8 @@ protected: void AutoCompleteMoveToCurrentWord(); static void AutoCompleteDoubleClick(void* p); + void CallTipClick(); + void CallTipShow(Point pt, const char *defn); virtual void CreateCallTipWindow(PRectangle rc) = 0; virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; diff --git a/src/stc/scintilla/src/Style.cxx b/src/stc/scintilla/src/Style.cxx index 2ee09f57d2..40a8dba6a4 100644 --- a/src/stc/scintilla/src/Style.cxx +++ b/src/stc/scintilla/src/Style.cxx @@ -16,13 +16,13 @@ Style::Style() { aliasOfDefaultFont = true; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); } Style::Style(const Style &source) { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, 0, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -34,6 +34,7 @@ Style::Style(const Style &source) { caseForce = source.caseForce; visible = source.visible; changeable = source.changeable; + hotspot = source.hotspot; } Style::~Style() { @@ -49,7 +50,7 @@ Style &Style::operator=(const Style &source) { return * this; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, SC_CHARSET_DEFAULT, - false, false, false, false, caseMixed, true, true); + false, false, false, false, caseMixed, true, true, false); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -66,9 +67,9 @@ 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 visible_, bool changeable_) { + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, + bool visible_, bool changeable_, bool hotspot_) { fore.desired = fore_; back.desired = back_; characterSet = characterSet_; @@ -81,6 +82,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, caseForce = caseForce_; visible = visible_; changeable = changeable_; + hotspot = hotspot_; if (aliasOfDefaultFont) font.SetID(0); else @@ -100,8 +102,9 @@ void Style::ClearTo(const Style &source) { source.eolFilled, source.underline, source.caseForce, - source.visible, - source.changeable); + source.visible, + source.changeable, + source.hotspot); } bool Style::EquivalentFontTo(const Style *other) const { diff --git a/src/stc/scintilla/src/Style.h b/src/stc/scintilla/src/Style.h index 63259b1a93..2f1e575860 100644 --- a/src/stc/scintilla/src/Style.h +++ b/src/stc/scintilla/src/Style.h @@ -26,6 +26,7 @@ public: ecaseForced caseForce; bool visible; bool changeable; + bool hotspot; Font font; int sizeZoomed; @@ -43,13 +44,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 visible_, bool changeable_); + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, + bool visible_, bool changeable_, bool hotspot_); 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/src/stc/scintilla/src/StyleContext.cxx b/src/stc/scintilla/src/StyleContext.cxx index bdae28196f..64fc7a048e 100644 --- a/src/stc/scintilla/src/StyleContext.cxx +++ b/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/src/stc/scintilla/src/StyleContext.h b/src/stc/scintilla/src/StyleContext.h index 4c9352916d..f2f8305c94 100644 --- a/src/stc/scintilla/src/StyleContext.h +++ b/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 + ((ch >= 0x100) ? 1 : 0)); } 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/src/stc/scintilla/src/ViewStyle.cxx b/src/stc/scintilla/src/ViewStyle.cxx index 12e1406aa4..eb8e54f2f8 100644 --- a/src/stc/scintilla/src/ViewStyle.cxx +++ b/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,18 @@ 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; + + hotspotForegroundSet = source.hotspotForegroundSet; + hotspotForeground.desired = source.hotspotForeground.desired; + hotspotBackgroundSet = source.hotspotBackgroundSet; + hotspotBackground.desired = source.hotspotBackground.desired; + hotspotUnderline = source.hotspotUnderline; + whitespaceForegroundSet = source.whitespaceForegroundSet; whitespaceForeground.desired = source.whitespaceForeground.desired; whitespaceBackgroundSet = source.whitespaceBackgroundSet; @@ -124,6 +137,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 +157,13 @@ void ViewStyle::Init() { edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0); edgeState = EDGE_NONE; caretWidth = 1; + someStylesProtected = false; + + hotspotForegroundSet = false; + hotspotForeground.desired = ColourDesired(0, 0, 0xff); + hotspotBackgroundSet = false; + hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff); + hotspotUnderline = true; leftMarginWidth = 1; rightMarginWidth = 1; @@ -148,9 +174,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 +202,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); @@ -191,6 +218,8 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { pal.WantFind(caretcolour, want); pal.WantFind(caretLineBackground, want); pal.WantFind(edgecolour, want); + pal.WantFind(hotspotForeground, want); + pal.WantFind(hotspotBackground, want); } void ViewStyle::Refresh(Surface &surface) { @@ -199,6 +228,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 +237,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,11 +258,11 @@ 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, - false, false, false, false, Style::caseMixed, true, true); + false, false, false, false, Style::caseMixed, true, true, false); } void ViewStyle::ClearStyles() { @@ -245,3 +278,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/src/stc/scintilla/src/ViewStyle.h b/src/stc/scintilla/src/ViewStyle.h index 887170eaac..ff38efef2e 100644 --- a/src/stc/scintilla/src/ViewStyle.h +++ b/src/stc/scintilla/src/ViewStyle.h @@ -59,6 +59,15 @@ public: ColourPair whitespaceBackground; ColourPair selbar; ColourPair selbarlight; + bool foldmarginColourSet; + ColourPair foldmarginColour; + bool foldmarginHighlightColourSet; + ColourPair foldmarginHighlightColour; + bool hotspotForegroundSet; + ColourPair hotspotForeground; + bool hotspotBackgroundSet; + ColourPair hotspotBackground; + bool hotspotUnderline; /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin enum { margins=3 }; int leftMarginWidth; ///< Spacing margin on left of text @@ -78,7 +87,8 @@ public: ColourPair edgecolour; int edgeState; int caretWidth; - + bool someStylesProtected; + ViewStyle(); ViewStyle(const ViewStyle &source); ~ViewStyle(); @@ -88,6 +98,7 @@ public: void ResetDefaultStyle(); void ClearStyles(); void SetStyleFontName(int styleIndex, const char *name); + bool ProtectionActive() const; }; #endif diff --git a/src/stc/scintilla/src/WindowAccessor.cxx b/src/stc/scintilla/src/WindowAccessor.cxx index ce42534e7b..d70ddf5c34 100644 --- a/src/stc/scintilla/src/WindowAccessor.cxx +++ b/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/src/stc/scintilla/src/XPM.cxx b/src/stc/scintilla/src/XPM.cxx new file mode 100644 index 0000000000..c4e4f888ef --- /dev/null +++ b/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/src/stc/scintilla/src/XPM.h b/src/stc/scintilla/src/XPM.h new file mode 100644 index 0000000000..948e557a92 --- /dev/null +++ b/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/src/stc/stc.cpp b/src/stc/stc.cpp index 17cf6ee406..c4a9d0c4e1 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -20,7 +20,10 @@ #include "wx/stc/stc.h" #include "ScintillaWX.h" +#include #include +#include +#include //---------------------------------------------------------------------- @@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG ) DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER ) DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP ) DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK ) + BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) @@ -201,7 +208,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 +223,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 +250,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 +300,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 +328,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 +406,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 +462,21 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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); @@ -555,6 +577,11 @@ void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet) { SendMsg(2066, style, characterSet); } +// Set a style to be a hotspot or not. +void wxStyledTextCtrl::StyleSetHotSpot(int style, bool hotspot) { + SendMsg(2409, style, hotspot); +} + // Set the foreground colour of the selection and whether to use this setting. void wxStyledTextCtrl::SetSelForeground(bool useSetting, const wxColour& fore) { SendMsg(2067, useSetting, wxColourAsLong(fore)); @@ -572,12 +599,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 +614,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 +845,37 @@ 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 img = bmp.ConvertToImage(); + img.SaveFile(strm, wxBITMAP_TYPE_XPM); + size_t len = strm.GetSize(); + char* buff = new char[len+1]; + strm.CopyTo(buff, len); + buff[len] = 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 +1016,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; - - 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); -} - -// Retrieve the line at the top of the display. + 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; + + return SendMsg(2151, doDraw, (long)&fr); +} + +// 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 +1113,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 +1231,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 +1291,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 +1303,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. @@ -1299,6 +1357,16 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& back) { SendMsg(2205, wxColourAsLong(back), 0); } +// Set the foreground colour for the call tip. +void wxStyledTextCtrl::CallTipSetForeground(const wxColour& fore) { + SendMsg(2206, wxColourAsLong(fore), 0); +} + +// Set the foreground colour for the highlighted part of the call tip. +void wxStyledTextCtrl::CallTipSetForegroundHighlight(const wxColour& fore) { + SendMsg(2207, wxColourAsLong(fore), 0); +} + // Find the display line of a document line taking hidden lines into account. int wxStyledTextCtrl::VisibleFromDocLine(int line) { return SendMsg(2220, line, 0); @@ -1366,7 +1434,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 +1540,61 @@ 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. +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 +1654,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 +1747,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 +1862,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 +1879,31 @@ 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); +} + +// Set a fore colour for active hotspots. +void wxStyledTextCtrl::SetHotspotActiveForeground(bool useSetting, const wxColour& fore) { + SendMsg(2410, useSetting, wxColourAsLong(fore)); +} + +// Set a back colour for active hotspots. +void wxStyledTextCtrl::SetHotspotActiveBackground(bool useSetting, const wxColour& back) { + SendMsg(2411, useSetting, wxColourAsLong(back)); +} + +// Enable / Disable underlining active hotspots. +void wxStyledTextCtrl::SetHotspotActiveUnderline(bool underline) { + SendMsg(2412, underline, 0); +} + // Start notifying the container of all key presses and commands. void wxStyledTextCtrl::StartRecord() { SendMsg(3001, 0, 0); @@ -1928,9 +2081,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) { @@ -2196,6 +2347,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetEventType(wxEVT_STC_ZOOM); break; + case SCN_HOTSPOTCLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK); + break; + + case SCN_HOTSPOTDOUBLECLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK); + break; + + case SCN_CALLTIPCLICK: + evt.SetEventType(wxEVT_STC_CALLTIP_CLICK); + break; + default: return; } diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 0ab9afdc5e..6643474798 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -20,7 +20,10 @@ #include "wx/stc/stc.h" #include "ScintillaWX.h" +#include #include +#include +#include //---------------------------------------------------------------------- @@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG ) DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER ) DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP ) DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK ) +DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK ) + BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) @@ -306,9 +313,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) { @@ -574,6 +579,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) { evt.SetEventType(wxEVT_STC_ZOOM); break; + case SCN_HOTSPOTCLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK); + break; + + case SCN_HOTSPOTDOUBLECLICK: + evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK); + break; + + case SCN_CALLTIPCLICK: + evt.SetEventType(wxEVT_STC_CALLTIP_CLICK); + break; + default: return; } diff --git a/src/stc/stc.h.in b/src/stc/stc.h.in index 7a54289b2c..baeaf0d437 100644 --- a/src/stc/stc.h.in +++ b/src/stc/stc.h.in @@ -225,11 +225,11 @@ private: void NotifyChange(); void NotifyParent(SCNotification* scn); - -private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxStyledTextCtrl) +protected: + ScintillaWX* m_swx; wxStopWatch m_stopWatch; wxScrollBar* m_vScrollBar; @@ -348,6 +348,8 @@ private: #endif }; + + #ifndef SWIG BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650) @@ -373,6 +375,9 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER, 1670) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP, 1671) DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM, 1672) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK, 1673) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK, 1674) + DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK, 1675) END_DECLARE_EVENT_TYPES() #else enum { @@ -399,6 +404,9 @@ END_DECLARE_EVENT_TYPES() wxEVT_STC_DRAG_OVER, wxEVT_STC_DO_DROP, wxEVT_STC_ZOOM, + wxEVT_STC_HOTSPOT_CLICK, + wxEVT_STC_HOTSPOT_DCLICK, + wxEVT_STC_CALLTIP_CLICK }; #endif @@ -430,6 +438,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&); #define EVT_STC_DRAG_OVER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_DO_DROP(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), #define EVT_STC_ZOOM(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), +#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ), + #endif //---------------------------------------------------------------------- -- 2.45.2