// 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
#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.
#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
#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
#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.
#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
#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
#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
// 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
// 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
// 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
//----------------------------------------------------------------------
// 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);
// 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);
// 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);
// 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);
// 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.
// 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);
// 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.
// 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();
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);
// 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();
void NotifyChange();
void NotifyParent(SCNotification* scn);
-
-private:
DECLARE_EVENT_TABLE()
DECLARE_CLASS(wxStyledTextCtrl)
+protected:
+
ScintillaWX* m_swx;
wxStopWatch m_stopWatch;
wxScrollBar* m_vScrollBar;
#endif
};
+
+
#ifndef SWIG
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650)
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 {
wxEVT_STC_DRAG_OVER,
wxEVT_STC_DO_DROP,
wxEVT_STC_ZOOM,
+ wxEVT_STC_HOTSPOT_CLICK,
+ wxEVT_STC_HOTSPOT_DCLICK,
+ wxEVT_STC_CALLTIP_CLICK
};
#endif
#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
//----------------------------------------------------------------------
};
//----------------------------------------------------------------------
+// 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
{
void OnAbout(wxCommandEvent& event);
private:
- wxStyledTextCtrl* ed;
+ MySTC* ed;
DECLARE_EVENT_TABLE()
};
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;
//----------------------------------------
// 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
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();
}
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 \
UniConversion.o \
ViewStyle.o \
WindowAccessor.o \
+ XPM.o \
+
DEPFILES=$(OBJECTS:.o=.d)
#include <wx/wx.h>
#include <wx/encconv.h>
-
+#include <wx/listctrl.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
+#include <wx/imaglist.h>
#include "Platform.h"
#include "PlatWX.h"
false,
stc2wx(faceName),
encoding);
-#ifdef __WXMAC__
- ((wxFont*)id)->SetNoAntiAliasing( true ) ;
-#endif
}
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_);
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();
// 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;
((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));
}
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...
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];
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; i<str.Length(); i++) {
+ int w, h;
+ hdc->GetTextExtent(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) {
}
+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;
#endif
}
+void SurfaceImpl::SetDBCSMode(int codePage) {
+ // dbcsMode = codePage == SC_CP_DBCS;
+}
+
+
Surface *Surface::Allocate() {
return new SurfaceImpl;
}
}
void Window::Destroy() {
- if (id)
+ if (id) {
+ Show(FALSE);
GETWIN(id)->Destroy();
+ }
id = 0;
}
}
PRectangle Window::GetPosition() {
+ if (! id) return PRectangle();
wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
return PRectangleFromwxRect(rc);
}
}
PRectangle Window::GetClientPosition() {
+ if (! id) return PRectangle();
wxSize sz = GETWIN(id)->GetClientSize();
return PRectangle(0, 0, sz.x, sz.y);
}
case cursorReverseArrow:
cursorId = wxCURSOR_RIGHT_ARROW;
break;
+ case cursorHand:
+ cursorId = wxCURSOR_HAND;
default:
cursorId = wxCURSOR_ARROW;
break;
// 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 <wx/popupwin.h>
-#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();
}
//----------------------------------------------------------------------
}
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));
}
return false;
}
+int Platform::DBCSCharLength(int codePage, const char *s) {
+ return 0;
+}
+
+int Platform::DBCSCharMaxLength() {
+ return 0;
+}
//----------------------------------------------------------------------
#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;
}
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,
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()
ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
+ capturedMouse = false;
wMain = win;
stc = win;
wheelRotation = 0;
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;
}
}
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;
+ }
}
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<char *>(lParam);
AutoCompleteCancel();
- if (!ct.wCallTip.Created()) {
- Point pt = LocationFromPosition(wParam);
- pt.y += vs.lineHeight;
- PRectangle rc = ct.CallTipStart(currentPos, pt,
- reinterpret_cast<char *>(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);
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
}
// 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;
}
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
+}
//----------------------------------------------------------------------
#include "Platform.h"
#include "Scintilla.h"
+#include "XPM.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "PropSet.h"
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
wxDragResult dragResult;
#endif
int wheelRotation;
+
+
+ friend class wxSTCCallTip;
};
//----------------------------------------------------------------------
# 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
# 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
# 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
# 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
(2176, 2180),
(2390, 2393),
(2395, 2396),
+ 2404,
+ (2413, 2416),
+ (2450, 2454),
]
'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),
'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),
'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),
'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."));
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),
'GetFocus' : ('GetSTCFocus', 0, 0, 0),
+ 'LoadLexerLibrary' : (None, 0,0,0),
+
+
# Remove all methods that are key commands since they can be
# executed with CmdKeyExecute
'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),
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 \
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:
$(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) \
$(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
$(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 \
$(D)\UniConversion.obj \
$(D)\ViewStyle.obj \
$(D)\WindowAccessor.obj \
+ $(D)\XPM.obj \
\
$(D)\PlatWX.obj \
$(D)\ScintillaWX.obj \
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 &
UniConversion.obj &
ViewStyle.obj &
WindowAccessor.obj &
+ XPM.obj &
PlatWX.obj &
ScintillaWX.obj &
- stc.obj
+ stc.obj
all: $(STCLIB) .SYMBOLIC
*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)
--- /dev/null
+License for Scintilla and SciTE
+
+Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+
+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
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
char buf[bufferSize+1];
int startPos;
int endPos;
- int codePage;
+ int codePage;
virtual bool InternalIsLeadByte(char ch)=0;
virtual void Fill(int position)=0;
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;
}
}
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
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; }
** 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 <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PLATFORM_H
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; }
};
}
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 {
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;
}
desired = desired_;
allocated.Set(desired.AsLong());
}
+ void Copy() {
+ allocated.Set(desired.AsLong());
+ }
};
class Window; // Forward declaration for Palette
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;
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;
virtual void FlushCachedState()=0;
virtual void SetUnicodeMode(bool unicodeMode_)=0;
+ virtual void SetDBCSMode(int codePage)=0;
};
/**
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();
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:
*/
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;
};
/**
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(
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);
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; }
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');
};
return append(sOther, static_cast<lenpos_t>(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);
*/
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);
}
#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
#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
#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
#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
/** @file Scintilla.h
** Interface to the edit control.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// 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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
# 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,)
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
# 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
# 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)
# 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,)
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)
# 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.
# 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,)
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.
# 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.
# 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(,)
# 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(,)
# 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(,)
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.
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(,)
# 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(,)
# 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.
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.
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
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
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)
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
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"
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();
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();
/** @file AutoComplete.cxx
** Defines the auto completion list box.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#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;
bool AutoComplete::IsFillUpChar(char ch) {
return ch && strchr(fillUpChars, ch);
}
-
+
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
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) {
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);
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
if (location == -1 && autoHide)
Cancel();
else
- lb.Select(location);
+ lb->Select(location);
}
/** @file AutoComplete.h
** Defines the auto completion list box.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef AUTOCOMPLETE_H
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?
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_);
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);
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
+ xUp = -100;
+ xDown = -100;
+ lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
val = 0;
}
+const int widthArrow = 14;
+
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(colourBG, want);
pal.WantFind(colourUnSel, 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<len;i++) {
+ if (s[i] <= '\002') {
+ if (i > 0)
+ ends[maxEnd++] = i;
+ ends[maxEnd++] = i+1;
+ }
+ }
+ ends[maxEnd++] = len;
+ int startSeg = 0;
+ int xEnd;
+ for (int seg = 0; seg<maxEnd; seg++) {
+ int endSeg = ends[seg];
+ if (endSeg > 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) {
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);
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;
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<int>(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() {
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;
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);
}
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<char>((curVal & ~mask) | style));
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);
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
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
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<unsigned char>(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<unsigned char>(cb.CharAt(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<Platform::DBCSCharMaxLength(); i++) {
+ mbstr[i] = cb.CharAt(pos+i);
+ }
+ mbstr[i] = '\0';
+ return Platform::DBCSCharLength(dbcsCodePage, mbstr);
} else {
return 1;
}
// 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--;
- 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<Platform::DBCSCharMaxLength();i++) {
+ mbstr[i] = cb.CharAt(startLine+i);
+ }
+ mbstr[i] = '\0';
+
+ int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ if (startLine + mbsize == pos) {
+ return pos;
+ } else if (startLine + mbsize > pos) {
+ if (moveDir > 0) {
+ return startLine + mbsize;
+ } else {
+ return startLine;
+ }
+ }
+ startLine += mbsize;
}
}
}
sWithStyle[i*2] = s[i];
sWithStyle[i*2 + 1] = 0;
}
- changed = InsertStyledString(position*2, sWithStyle,
+ changed = InsertStyledString(position*2, sWithStyle,
static_cast<int>(insertLength*2));
delete []sWithStyle;
}
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);
}
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;
}
/**
- * 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.
}
/**
- * 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) {
* 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)
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;
}
// 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);
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;
}
}
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<char>(MakeUpperCase(ch)));
}
} else {
- if (isupper(ch)) {
+ if (IsUpperCase(ch)) {
ChangeChar(pos, static_cast<char>(MakeLowerCase(ch)));
}
}
}
} else {
for (ch = 0; ch < 256; ch++) {
- if (ch >= 0x80 || isalnum(ch) || ch == '_')
+ if (ch >= 0x80 || isalnum(ch) || ch == '_')
charClass[ch] = ccWord;
}
}
return false;
} else {
enteredCount++;
+ style &= stylingMask;
int prevEndStyled = endStyled;
if (cb.SetStyleFor(endStyled, length, style, stylingMask)) {
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
}
bool Document::IsWordPartSeparator(char ch) {
- return ispunct(ch) && (WordCharClass(ch) == ccWord);
+ return (WordCharClass(ch) == ccWord) && IsPunctuation(ch);
}
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;
}
}
}
++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;
}
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
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_) {
};
}
bool Overlaps(Range other) const {
- return
+ return
Contains(other.start) ||
Contains(other.end) ||
other.Contains(start) ||
}
};
-private:
+private:
int refCount;
CellBuffer cb;
enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
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();
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);
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_),
*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
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();
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();
/** @file Editor.cxx
** Main code for the edit control.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "Platform.h"
+#ifndef PLAT_QT
#define INCLUDE_DEPRECATED_FEATURES
+#endif
#include "Scintilla.h"
#include "ContractionState.h"
#include "CellBuffer.h"
#include "KeyMap.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
positions(0),
widthLine(wrapWidthInfinite),
lines(1) {
- Resize(maxLineLength_);
+ Resize(maxLineLength_);
}
LineLayout::~LineLayout() {
int *newLineStarts = new int[newMaxLines];
if (!newLineStarts)
return;
- for (int i=0; i<newMaxLines; i++) {
+ for (int i = 0; i < newMaxLines; i++) {
if (i < lenLineStarts)
newLineStarts[i] = lineStarts[i];
else
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight) {
+ char bracesMatchStyle, int xHighlight) {
if (rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
}
}
if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) ||
- (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
+ (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
xHighlightGuide = xHighlight;
}
}
size = (size / 16 + 1) * 16;
}
if (size > 0) {
- cache = new LineLayout *[size];
+ cache = new LineLayout * [size];
}
- for (int i=0; i<size; i++)
+ for (int i = 0; i < size; i++)
cache[i] = 0;
}
if (lengthForLevel > size) {
Deallocate();
} else if (lengthForLevel < length) {
- for (int i=lengthForLevel; i<length; i++) {
+ for (int i = lengthForLevel; i < length; i++) {
delete cache[i];
cache[i] = 0;
}
}
void LineLayoutCache::Deallocate() {
- for (int i=0; i<length; i++)
+ for (int i = 0; i < length; i++)
delete cache[i];
delete []cache;
cache = 0;
void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
if (cache && !allInvalidated) {
- for (int i=0; i<length; i++) {
+ for (int i = 0; i < length; i++) {
if (cache[i]) {
cache[i]->Invalidate(validity_);
}
}
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);
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;
}
printMagnification = 0;
printColourMode = SC_PRINT_NORMAL;
+ printWrapState = eWrapWord;
cursorMode = SC_CURSORNORMAL;
controlCharSymbol = 0; /* Draw the control characters */
mouseDownCaptures = true;
bufferedDraw = true;
+ twoPhaseDraw = true;
lastClickTime = 0;
dwellDelay = SC_TIME_FOREVER;
xCaretMargin = 50;
horizontalScrollBarVisible = true;
scrollWidth = 2000;
+ verticalScrollBarVisible = true;
endAtLastLine = true;
pixmapLine = Surface::Allocate();
modEventMask = SC_MODEVENTMASKALL;
pdoc = new Document();
- pdoc ->AddRef();
+ pdoc->AddRef();
pdoc->AddWatcher(this, 0);
recordingMacro = false;
wrapWidth = LineLayout::wrapWidthInfinite;
docLineLastWrapped = -1;
- llc.SetLevel(LineLayoutCache::llcDocument);
+ hsStart = -1;
+ hsEnd = -1;
+
+ llc.SetLevel(LineLayoutCache::llcCaret);
}
Editor::~Editor() {
void Editor::RefreshStyleData() {
if (!stylesValid) {
stylesValid = true;
- AutoSurface surface(IsUnicodeMode());
+ AutoSurface surface(this);
if (surface) {
vs.Refresh(*surface);
RefreshColourPalette(palette, true);
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];
}
}
+// 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();
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;
if (posInLine > ll->maxLineLength) {
pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
}
- for (int subLine=0; subLine<ll->lines; 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)) {
}
pt.x += vs.fixedColumnWidth - xOffset;
}
- llc.Dispose(ll);
return pt;
}
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;
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;
}
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);
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;
}
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);
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;
}
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;
}
} else {
SetEmptySelection(newPos);
}
+ ShowCaretAtCurrentPosition();
if (ensureVisible)
EnsureCaretVisible();
- ShowCaretAtCurrentPosition();
NotifyMove(newPos);
return 0;
}
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
} else {
Redraw();
}
- SetVerticalScrollPos();
+ if (moveThumb) {
+ SetVerticalScrollPos();
+ }
}
}
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; subLine<ll->lines; 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;
}
}
newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
if (newTopLine != topLine) {
+ Redraw();
SetTopLine(newTopLine);
SetVerticalScrollPos();
- Redraw();
}
}
}
} 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
}
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();
}
if (wrapState == eWrapNone) {
if (wrapWidth != LineLayout::wrapWidthInfinite) {
wrapWidth = LineLayout::wrapWidthInfinite;
- for (int lineDoc=0; lineDoc<pdoc->LinesTotal(); lineDoc++) {
+ for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
cs.SetHeight(lineDoc, 1);
}
wrapOccurred = true;
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;
}
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;
// 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) {
// 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;
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
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) {
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());
}
/**
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++;
}
}
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<char>(styleByte & styleMask));
- allSame = allSame &&
- (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+ if (vstyle.viewEOL || (!IsEOLChar(chDoc != '\r'))) {
+ allSame = allSame &&
+ (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+ allSame = allSame &&
+ (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
else
allSame = allSame &&
- (ll->chars[numCharsInLine] == chDoc);
+ (ll->chars[numCharsInLine] == chDoc);
numCharsInLine++;
}
}
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<char>(styleByte & styleMask);
ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
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:
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
- ll->positions + startseg + 1);
+ ll->positions + startseg + 1);
}
lastSegItalics = false;
} else { // Regular character
} 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
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;
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;
}
}
}
}
+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) {
}
}
+ 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))) {
// 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;
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;
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<char>(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++) {
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);
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 {
}
}
}
- 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;
}
// 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) {
}
}
-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);
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);
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)) {
surface = pixmapLine;
}
surface->SetUnicodeMode(IsUnicodeMode());
+ surface->SetDBCSMode(CodePage());
int visibleLine = topLine + screenLinePaintFirst;
//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);
// 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;
}
ll->containsCaret = false;
}
+ GetHotSpotRange(ll->hsStart, ll->hsEnd);
+
PRectangle rcLine = rcClient;
rcLine.top = ypos;
rcLine.bottom = ypos + vs.lineHeight;
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
- highlightGuideColumn * vs.spaceWidth);
+ highlightGuideColumn * vs.spaceWidth);
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
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
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);
visibleLine++;
//gdk_flush();
}
- llc.Dispose(ll);
//if (durPaint < 0.00000001)
// durPaint = 0.00000001;
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;
}
// 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;
}
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);
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 {
}
// Empty method is overridden on GTK+ to show / hide scrollbars
-void Editor::ReconfigureScrollBars() {
-}
+void Editor::ReconfigureScrollBars() {}
void Editor::SetScrollBars() {
RefreshStyleData();
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);
}
}
if (treatAsDBCS) {
NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
- static_cast<unsigned char>(s[1]));
+ static_cast<unsigned char>(s[1]));
} else {
int byte = static_cast<unsigned char>(s[0]);
if ((byte < 0xC0) || (1 == len)) {
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.
}
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();
- }
}
}
}
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;
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()) {
}
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();
}
}
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 {
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;
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);
}
case SCI_REPLACESEL:
case SCI_ADDTEXT:
case SCI_INSERTTEXT:
+ case SCI_APPENDTEXT:
case SCI_CLEARALL:
case SCI_SELECTALL:
case SCI_GOTOLINE:
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:
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:
case SCI_FORMFEED:
case SCI_VCHOME:
case SCI_VCHOMEEXTEND:
+ case SCI_VCHOMEWRAP:
+ case SCI_VCHOMEWRAPEXTEND:
case SCI_DELWORDLEFT:
case SCI_DELWORDRIGHT:
case SCI_DELLINELEFT:
case SCI_LINECUT:
case SCI_LINEDELETE:
case SCI_LINETRANSPOSE:
+ case SCI_LINEDUPLICATE:
case SCI_LOWERCASE:
case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
case SCI_NEWLINE:
default:
// printf("Filtered out %ld of macro recording\n", iMessage);
- return;
+ return ;
}
// Send notification
}
}
+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() {
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.
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; subLine<ll->lines; 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 {
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);
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);
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();
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);
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;
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++;
case SCI_LINETRANSPOSE:
LineTranspose();
break;
+ case SCI_LINEDUPLICATE:
+ LineDuplicate();
+ break;
case SCI_LOWERCASE:
ChangeCaseOfSelection(false);
break;
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;
}
* @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<TextToFind *>(lParam);
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = pos;
* @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.
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
}
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
+ (searchFlags & SCFIND_POSIX) != 0,
&lengthFound);
if (pos != -1) {
targetStart = pos;
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;
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;
SetMouseCapture(true);
selectionType = selLine;
} else {
+ if (PositionIsHotspot(newPos)) {
+ NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+ }
if (!shift) {
inDragDrop = PointInSelection(pt);
}
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);
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) {
}
EnsureCaretVisible(false, false, true);
+ if (hsStart != -1 && !PositionIsHotspot(movePos))
+ SetHotSpotRange(NULL);
+
} else {
if (vs.fixedColumnWidth > 0) { // There is a margin
if (PointInSelMargin(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);
+ }
}
}
DisplayCursor(Window::cursorReverseArrow);
} else {
DisplayCursor(Window::cursorText);
+ SetHotSpotRange(NULL);
}
xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
ptMouseLast = pt;
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);
}
}
if ((dwellDelay < SC_TIME_FOREVER) &&
- (ticksToDwell > 0) &&
- (!HaveMouseCapture())) {
+ (ticksToDwell > 0) &&
+ (!HaveMouseCapture())) {
ticksToDwell -= timer.tickSize;
if (ticksToDwell <= 0) {
dwelling = true;
if (hasFocus) {
ShowCaretAtCurrentPosition();
} else {
+ CancelModes();
DropCaret();
}
}
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);
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
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();
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;
}
switch (iMessage) {
- case SCI_GETTEXT:
- {
+ case SCI_GETTEXT: {
if (lParam == 0)
return 0;
if (wParam == 0)
return iChar;
}
- case SCI_SETTEXT:
- {
+ case SCI_SETTEXT: {
if (lParam == 0)
return 0;
pdoc->DeleteChars(0, pdoc->Length());
// 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<int>(wParam) < 0) ||
(static_cast<int>(wParam) > pdoc->LineFromPosition(pdoc->Length())))
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);
case SCI_SETXOFFSET:
xOffset = wParam;
+ SetHorizontalScrollPos();
Redraw();
break;
case SCI_GETXOFFSET:
return xOffset;
+ case SCI_CHOOSECARETX:
+ SetLastXChosen();
+ break;
+
case SCI_SCROLLCARET:
EnsureCaretVisible();
break;
return 0;
}
+ case SCI_APPENDTEXT:
+ pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam);
+ return 0;
+
case SCI_CLEARALL:
ClearAll();
return 0;
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<short>(wParam) >= pdoc->Length())
return 0;
pdoc->SetStyleFor(wParam, static_cast<char>(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));
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;
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));
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();
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();
}
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);
InvalidateStyleRedraw();
}
break;
+ case SCI_STYLESETHOTSPOT:
+ if (wParam <= STYLE_MAX) {
+ vs.styles[wParam].hotspot = lParam != 0;
+ InvalidateStyleRedraw();
+ }
+ break;
case SCI_STYLERESETDEFAULT:
vs.ResetDefaultStyle();
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;
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
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:
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:
case SCI_FORMFEED:
case SCI_VCHOME:
case SCI_VCHOMEEXTEND:
+ case SCI_VCHOMEWRAP:
+ case SCI_VCHOMEWRAPEXTEND:
case SCI_ZOOMIN:
case SCI_ZOOMOUT:
case SCI_DELWORDLEFT:
case SCI_LINECUT:
case SCI_LINEDELETE:
case SCI_LINETRANSPOSE:
+ case SCI_LINEDUPLICATE:
case SCI_LOWERCASE:
case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
return reinterpret_cast<sptr_t>(pdoc);
case SCI_SETDOCPOINTER:
+ CancelModes();
SetDocPointer(reinterpret_cast<Document *>(lParam));
return 0;
case SCI_CREATEDOCUMENT: {
Document *doc = new Document();
- doc->AddRef();
+ if (doc) {
+ doc->AddRef();
+ }
return reinterpret_cast<sptr_t>(doc);
}
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);
}
/** @file Editor.h
** Defines the main editor class.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
int *positions;
char bracePreviousStyles[2];
+ // Hotspot support
+ int hsStart;
+ int hsEnd;
+
// Wrapped line support
int widthLine;
int lines;
}
};
-/**
- * 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 {
int printMagnification;
int printColourMode;
+ int printWrapState;
int cursorMode;
int controlCharSymbol;
/** 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;
int foldFlags;
ContractionState cs;
+ // Hotspot support
+ int hsStart;
+ int hsEnd;
+
// Wrapping support
enum { eWrapNone, eWrapWord } wrapState;
int wrapWidth;
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);
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);
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);
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);
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:
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
// Scintilla source code edit control
-/** @file KeyMap.cxx
+/** @file KeyMap.cxx
** Defines a mapping between keystrokes and commands.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
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);
}
{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},
{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},
{'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},
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;
return wordListDescriptions[index];
}
}
-
+
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
//++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);
LINK_LEXER(lmLatex);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPOV);
LINK_LEXER(lmPython);
LINK_LEXER(lmRuby);
LINK_LEXER(lmSQL);
// SciTE - Scintilla based Text Editor
/** @file LexAVE.cxx
** Lexer for Avenue.
+ **
+ ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <stdio.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
#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<char>(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<char>(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<char>(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<char>(tolower(chNext));
+ chNext = static_cast<char>(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<char>(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);
+
-// SciTE - Scintilla based Text Editor
-// LexAda.cxx - lexer for Ada95
-// by Tahir Karaca <tahir@bigfoot.de>
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
// The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
#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<char>(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<char>(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<char>(sc.ch);
+ sc.Forward();
+ }
+
+ // Special case: exponent with sign
+ if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+ (sc.ch == '+' || sc.ch == '-')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward ();
+
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ number += static_cast<char>(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<char>(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 == '_';
+}
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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);
+
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 ||
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++) {
}
}
-LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant");
+static const char * const bullantWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
#include "Scintilla.h"
#include "SciLexer.h"
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
static bool IsOKBeforeRE(const int ch) {
return (ch == '(') || (ch == '=') || (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) {
}
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];
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);
} 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);
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);
// 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);
}
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;
}
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;
}
if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
if (ch == '#') {
- unsigned int j=i+1;
- while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ unsigned int j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
j++;
}
if (styler.Match(j, "region") || styler.Match(j, "if")) {
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
+static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ int foldFlags = styler.GetPropertyInt("fold.flags") ;
+ bool foldBox = ((foldFlags & SC_FOLDFLAG_BOX) == SC_FOLDFLAG_BOX);
+
+ if (foldBox) {
+ FoldBoxCppDoc(startPos, length, initStyle, keywordlists, styler);
+ } else {
+ FoldNoBoxCppDoc(startPos, length, initStyle, styler);
+ }
+}
+
static const char * const cppWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- 0,
-};
-
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc, cppWordLists);
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Fold header keywords",
+ 0,
+ };
+
+static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmTCL(SCLEX_TCL, ColouriseCppDocSensitive, "tcl", FoldCppDoc, cppWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCSS.cxx
+ ** Lexer for Cascade Style Sheets
+ ** Written by Jakub Vrána
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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);
delete []buffer;
}
-LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf");
+static const char * const confWordListDesc[] = {
+ "Directives",
+ "Parameters",
+ 0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
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;
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);
ch == '{' || ch == '}' || ch == '~' ||
ch == '[' || ch == ']' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' ||
- ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
+ ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
ch == '!' || ch == '@' || ch == '?';
}
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;
}
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);
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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<unsigned int>(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<char>(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<char>(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);
/** @file LexHTML.cxx
** Lexer for HTML.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
}
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<char>(tolower(ch));
+ if ((ch != '<') && (ch != '/')) {
+ s[i++] = caseSensitive ? ch : static_cast<char>(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] == '!') {
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 ||
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
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;
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;
}
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;
scriptLanguage = eScriptVBS;
styler.ColourTo(i, SCE_H_ASP);
// fold whole script
- levelCurrent++;
+ if (foldHTMLPreprocessor)
+ levelCurrent++;
// should be better
ch = styler.SafeGetCharAt(i);
continue;
state = SCE_H_SGML_COMMAND; // wait for a pending command
}
// fold whole tag (-- when closing the tag)
-
- levelCurrent++;
+ if (foldHTMLPreprocessor)
+ levelCurrent++;
continue;
}
inScriptType = eHtml;
scriptLanguage = eScriptNone;
// unfold all scripting languages
- levelCurrent--;
+ if (foldHTMLPreprocessor)
+ levelCurrent--;
continue;
}
/////////////////////////////////////
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;
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
+ if (!tagDontFold){
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
}
tagClosing = false;
} else if (ch == '/' && chNext == '>') {
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);
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);
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)) {
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;
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++;
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;
}
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;
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 == '\"') {
}
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;
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;
}
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) {
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);
// Handle some PHP script
if (sc.state == SCE_HPHP_WORD) {
- if (!IsAWordStart(sc.ch)) {
+ if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_COMMENTLINE) {
sc.ForwardSetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_VARIABLE) {
- if (!IsAWordStart(sc.ch)) {
+ if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_OPERATOR) {
}
}
if (sc.state == SCE_HPHP_DEFAULT) {
- if (IsAWordStart(sc.ch)) {
+ if (IsPhpWordStart(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_WORD);
} else if (sc.ch == '#') {
sc.SetState(SCE_HPHP_COMMENTLINE);
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<char>(sc.chNext))) {
sc.SetState(SCE_HPHP_VARIABLE);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_OPERATOR);
if (isLispwordstart(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_IDENTIFIER;
- }
+ }
else if (ch == ';') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_COMMENT;
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
}
-
+
else if (ch == '\"') {
state = SCE_LISP_STRING;
}
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) {
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);
#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 == '_');
}
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
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);
// 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') {
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))) {
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<char>(sc.ch))) {
+ } else if (isLuaOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_LUA_OPERATOR);
}
}
sc.Complete();
}
-
static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
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);
/** @file LexMatlab.cxx
** Lexer for Matlab.
** Written by José Fonseca
- **/
+ **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
}
}
-LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc);
+static const char * const matlabWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
#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'));
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] == '%' &&
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);
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
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
}
}
+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);
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 " ) &&
} 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 <filename>:<line>:message
- // Look for <filename>(line)message
- // Look for <filename>(line,pos)message
+ // Look for GCC <filename>:<line>:message
+ // Look for Microsoft <filename>(line) :message
+ // Look for Microsoft <filename>(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) {
} 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);
}
}
}
}
- 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);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPOV.cxx
+ ** Lexer for POV-Ray, based on lexer for C++.
+ **/
+// Copyright 2003 by Steven te Brinke <steven.t.b@zonnet.nl>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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);
}
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;
WordList& keywords = *keywordlists[0];
WordList& classwords = *keywordlists[1];
-
+
char s[100];
getRange(start, end, styler, s, sizeof(s));
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')) {
levelPrev = levelCurrent;
visibleChars = 0;
}
-
+
if (!isspacechar(ch))
visibleChars++;
}
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);
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);
// Scintilla source code edit control
/** @file LexPython.cxx
** Lexer for Python.
- **/
+ **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
}
/* 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);
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
} else if (whingeLevel == 4) {
chFlags = (spaceFlags & wsTab) ? chBad : chGood;
}
+ sc.SetState(sc.state);
styler.SetFlags(chFlags, static_cast<char>(sc.state));
}
(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);
break;
}
+ bool needEOLCheck = false;
+
// Check for a state end
if (sc.state == SCE_P_OPERATOR) {
kwLast = kwOther;
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 == '\\') {
sc.Forward();
sc.Forward();
sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
}
} else if (sc.state == SCE_P_TRIPLEDOUBLE) {
if (sc.ch == '\\') {
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))) {
} 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();
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
}
static const char * const pythonWordListDesc[] = {
- "Python keywords",
+ "Keywords",
0
};
-LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
+LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
pythonWordListDesc);
} 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);
}
}
}
-
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc);
+
+static const char * const rubyWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
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);
}
static inline bool IsADateCharacter(const int ch) {
- return (ch < 0x80) &&
+ return (ch < 0x80) &&
(isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
}
styler.StartAt(startPos);
int visibleChars = 0;
-
+
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
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') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
-
+
if (sc.state == SCE_B_DEFAULT) {
if (sc.ch == '\'') {
sc.SetState(SCE_B_COMMENT);
} else if (sc.ch == '#') {
int n = 1;
int chSeek = ' ';
- while (chSeek == ' ' || chSeek == '\t') {
+ while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
chSeek = sc.GetRelative(n);
n++;
}
sc.SetState(SCE_B_OPERATOR);
}
}
-
+
if (sc.atLineEnd) {
visibleChars = 0;
}
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);
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <string.h>
+
#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;
}
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++;
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<char>(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) {
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
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);
};
/** @file PropSet.cxx
** A Java style properties file module.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Maintain a dictionary of properties
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+//#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
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) {
lenVal = static_cast<int>(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<unsigned int>(lenKey)) &&
+ if ((hash == p->hash) &&
+ ((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
(0 == strncmp(p->key, key, lenKey)))) {
// Replace current value
delete [](p->val);
p->val = StringDup(val, lenVal);
- return ;
+ return;
}
}
// Not found
}
void PropSet::Set(const char *keyVal) {
- while (isspace(*keyVal))
+ while (IsASpace(*keyVal))
keyVal++;
const char *endVal = keyVal;
while (*endVal && (*endVal != '\n'))
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 $()
base = newbase;
}
cpvar = strstr(base, "$(");
+ maxExpands--;
}
SString sret = base;
delete []base;
if (keyfile == NULL)
keyfile = orgkeyfile;
- for (; ; ) {
+ for (;;) {
char *del = strchr(keyfile, ';');
if (del == NULL)
del = keyfile + strlen(keyfile);
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 $()
base = newbase;
}
cpvar = strstr(base, "$(");
+ maxExpands--;
}
SString sret = base;
delete []base;
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;
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--;
}
}
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, ' ');
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;
* 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
* 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
*
* 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.
*
* void re_fail(msg, op)
* char *msg;
* char op;
- *
+ *
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
*
* [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:
*
* 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.
*
* 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
*
const char bitarr[] = {1,2,4,8,16,32,64,'\200'};
#define badpat(x) (*nfa = END, x)
-
+
RESearch::RESearch() {
Init();
}
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 */
int n;
char mask; /* xor mask -CCL/NCL */
int c1, c2;
-
+
if (!pat || !length)
if (sta)
return 0;
const char *p=pat; /* pattern pointer */
for (int i=0; i<length; i++, p++) {
+ if (mp > mpMax)
+ return badpat("Pattern too long");
lp = mp;
switch(*p) {
i++;
if (*++p == '^') {
- mask = '\377';
+ mask = '\377';
i++;
p++;
} else
for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
*mp++ = static_cast<char>(mask ^ bittab[n]);
-
+
break;
case '*': /* match 0 or more.. */
i++;
switch(*++p) {
- case '(':
- if (tagc < MAXTAG) {
- tagstk[++tagi] = tagc;
- *mp++ = BOT;
- *mp++ = static_cast<char>(tagc++);
- }
- else
- return badpat("Too many \\(\\) pairs");
- break;
- case ')':
- if (*sp == BOT)
- return badpat("Null pattern inside \\(\\)");
- if (tagi > 0) {
- *mp++ = static_cast<char>(EOT);
- *mp++ = static_cast<char>(tagstk[tagi--]);
- }
- else
- return badpat("Unmatched \\)");
- break;
case '<':
*mp++ = BOW;
break;
*mp++ = escapeValue(*p);
break;
default:
- *mp++ = CHR;
- *mp++ = *p;
+ if (!posix && *p == '(') {
+ if (tagc < MAXTAG) {
+ tagstk[++tagi] = tagc;
+ *mp++ = BOT;
+ *mp++ = static_cast<char>(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<char>(EOT);
+ *mp++ = static_cast<char>(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<char>(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<char>(EOT);
+ *mp++ = static_cast<char>(tagstk[tagi--]);
+ }
+ else
+ return badpat("Unmatched )");
+ } else if (caseSensitive) {
*mp++ = CHR;
*mp++ = *p;
} else {
sp = lp;
}
if (tagi > 0)
- return badpat("Unmatched \\(");
+ return badpat((posix ? "Unmatched (" : "Unmatched \\("));
*mp = END;
sta = OKP;
return 0;
* RESearch::Execute:
* execute nfa to find a match.
*
- * special cases: (nfa[0])
+ * special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
bol = lp;
failure = 0;
-
+
Clear();
switch(*ap) {
return 1;
}
-/*
+/*
* PMatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
*
* 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).
*
*/
* 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
};
#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;
* 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;
pin = c - '0';
break;
}
-
+
default:
*dst++ = c;
continue;
* 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;
};
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);
*/
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) {
delete []v;
v = newv;
}
-
+
public:
SVector() {
allocFailure = false;
/** @file ScintillaBase.cxx
** An enhanced subclass of Editor with calltips, autocomplete and context menu.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
return;
}
}
- ac.Start(wMain, idAutoComplete, currentPos, lenEntered);
+ ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
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;
}
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.
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();
}
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();
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);
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<char *>(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<const char *>(lParam));
+ break;
+
+ case SCI_CLEARREGISTEREDIMAGES:
+ ac.lb->ClearRegisteredImages();
+ break;
+
+ case SCI_AUTOCSETTYPESEPARATOR:
+ ac.SetTypesep(static_cast<char>(wParam));
+ break;
+
+ case SCI_AUTOCGETTYPESEPARATOR:
+ return ac.GetTypesep();
+
+ case SCI_CALLTIPSHOW:
+ CallTipShow(LocationFromPosition(wParam),
+ reinterpret_cast<const char *>(lParam));
break;
case SCI_CALLTIPCANCEL:
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;
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);
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;
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;
caseForce = source.caseForce;
visible = source.visible;
changeable = source.changeable;
+ hotspot = source.hotspot;
}
Style::~Style() {
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;
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_;
caseForce = caseForce_;
visible = visible_;
changeable = changeable_;
+ hotspot = hotspot_;
if (aliasOfDefaultFont)
font.SetID(0);
else
source.eolFilled,
source.underline,
source.caseForce,
- source.visible,
- source.changeable);
+ source.visible,
+ source.changeable,
+ source.hotspot);
}
bool Style::EquivalentFontTo(const Style *other) const {
ecaseForced caseForce;
bool visible;
bool changeable;
+ bool hotspot;
Font font;
int sizeZoomed;
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
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);
}
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);
}
/** @file StyleContext.cxx
** Lexer infrastructure.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// 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<unsigned char>(styler.SafeGetCharAt(pos+1));
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(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;
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<unsigned char>(styler.SafeGetCharAt(pos));
if (styler.IsLeadByte(static_cast<char>(ch))) {
pos++;
ch = ch << 8;
ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
}
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
- }
- atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+ GetNextChar(pos);
}
void Complete() {
styler.ColourTo(currentPos - 1, state);
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<unsigned char>(styler.SafeGetCharAt(currentPos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(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 = ' ';
atLineEnd = true;
}
}
+ void Forward(int nb) {
+ for (int i = 0; i < nb; i++) {
+ Forward();
+ }
+ }
void ChangeState(int state_) {
state = state_;
}
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) {
/** @file ViewStyle.cxx
** Store information on how the document is to be viewed.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include "Scintilla.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
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;
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;
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;
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;
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);
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) {
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]);
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
+ if (styles[i].IsProtected()) {
+ someStylesProtected = true;
+ }
}
lineHeight = maxAscent + maxDescent;
}
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() {
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
styles[styleIndex].fontName = fontNames.Save(name);
}
+
+bool ViewStyle::ProtectionActive() const {
+ return someStylesProtected;
+}
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
ColourPair edgecolour;
int edgeState;
int caretWidth;
-
+ bool someStylesProtected;
+
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void ResetDefaultStyle();
void ClearStyles();
void SetStyleFontName(int styleIndex, const char *name);
+ bool ProtectionActive() const;
};
#endif
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
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);
}
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) {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) {
- Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
+ Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
styleBuf);
validLen = 0;
}
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;
}
ch = (*this)[++pos];
}
-
+
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.h>
+#include <stdlib.h>
+
+#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;i<nColours;i++) {
+ if (codes[i] == ch) {
+ return colours[i].allocated;
+ }
+ }
+ return colours[0].allocated;
+#endif
+}
+
+void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
+ if ((code != codeTransparent) && (startX != x)) {
+ PRectangle rc(startX, y, x, y+1);
+ surface->FillRectangle(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<const char * const *>(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<strings; i++) {
+ allocation += MeasureLength(linesForm[i]) + 1;
+ }
+ data = new char[allocation];
+ char *nextBit = data;
+ for (int j=0; j<strings; j++) {
+ lines[j] = nextBit;
+ size_t len = MeasureLength(linesForm[j]);
+ memcpy(nextBit, linesForm[j], len);
+ nextBit += len;
+ *nextBit++ = '\0';
+ }
+
+ for (int code=0;code<256; code++) {
+ colourCodeTable[code] = 0;
+ }
+
+ for (int c=0; c<nColours; c++) {
+ const char *colourDef = linesForm[c+1];
+ codes[c] = colourDef[0];
+ colourDef += 4;
+ if (*colourDef == '#') {
+ colours[c].desired.Set(colourDef);
+ } else {
+ colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
+ codeTransparent = codes[c];
+ }
+ colourCodeTable[static_cast<unsigned char>(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;i<nColours;i++) {
+ pal.WantFind(colours[i], want);
+ }
+}
+
+void XPM::CopyDesiredColours() {
+ if (!data || !codes || !colours || !lines) {
+ return;
+ }
+ for (int i=0;i<nColours;i++) {
+ colours[i].Copy();
+ }
+}
+
+void XPM::Draw(Surface *surface, PRectangle &rc) {
+ if (!data || !codes || !colours || !lines) {
+ return;
+ }
+ // Centre the pixmap
+ int startY = rc.top + (rc.Height() - height) / 2;
+ int startX = rc.left + (rc.Width() - width) / 2;
+ for (int y=0;y<height;y++) {
+ int prevCode = 0;
+ int xStartRun = 0;
+ for (int x=0; x<width; x++) {
+ int code = lines[y+nColours+1][x];
+ if (code != prevCode) {
+ FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
+ xStartRun = x;
+ prevCode = code;
+ }
+ }
+ FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
+ }
+}
+
+const char **XPM::LinesFormFromTextForm(const char *textForm) {
+ // Build the lines form out of the text form
+ const char **linesForm = 0;
+ int countQuotes = 0;
+ int strings=1;
+ for (int j=0; countQuotes < (2*strings); j++) {
+ if (textForm[j] == '\"') {
+ if (countQuotes == 0) {
+ const char *line0 = textForm + j + 1;
+ // Skip width
+ line0 = NextField(line0);
+ // Add 1 line for each pixel of height
+ strings += atoi(line0);
+ line0 = NextField(line0);
+ // Add 1 line for each colour
+ strings += atoi(line0);
+ linesForm = new const char *[strings];
+ }
+ if (linesForm && ((countQuotes & 1) == 0)) {
+ linesForm[countQuotes / 2] = textForm + j + 1;
+ }
+ countQuotes++;
+ }
+ }
+ return linesForm;
+}
+
+// In future, may want to minimize search time by sorting and using a binary search.
+
+XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
+}
+
+XPMSet::~XPMSet() {
+ Clear();
+}
+
+void XPMSet::Clear() {
+ for (int i=0;i<maximum;i++) {
+ delete set[i];
+ }
+ delete []set;
+ set = 0;
+ len = 0;
+ maximum = 0;
+ height = -1;
+ width = -1;
+}
+
+void XPMSet::Add(int id, const char *textForm) {
+ // Invalidate cached dimensions
+ height = -1;
+ width = -1;
+
+ // Replace if this id already present
+ for (int i=0;i<maximum;i++) {
+ if (set[i]->GetId() == 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; i<maximum; i++) {
+ setNew[i] = set[i];
+ }
+ delete []set;
+ set = setNew;
+ }
+ set[maximum] = pxpm;
+ maximum++;
+ }
+}
+
+XPM *XPMSet::Get(int id) {
+ for (int i=0;i<maximum;i++) {
+ if (set[i]->GetId() == id) {
+ return set[i];
+ }
+ }
+ return 0;
+}
+
+int XPMSet::GetHeight() {
+ if (height < 0) {
+ for (int i=0; i<maximum; i++) {
+ if (height < set[i]->GetHeight()) {
+ height = set[i]->GetHeight();
+ }
+ }
+ }
+ return (height > 0) ? height : 0;
+}
+
+int XPMSet::GetWidth() {
+ if (width < 0) {
+ for (int i=0; i<maximum; i++) {
+ if (width < set[i]->GetWidth()) {
+ width = set[i]->GetWidth();
+ }
+ }
+ }
+ return (width > 0) ? width : 0;
+}
--- /dev/null
+// 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 <neilh@scintilla.org>
+// 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
#include "wx/stc/stc.h"
#include "ScintillaWX.h"
+#include <wx/wx.h>
#include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
//----------------------------------------------------------------------
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)
// 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.
// 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.
// 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?
// 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
// 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.
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.
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);
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));
// 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.
// 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.
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);
// 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.
// 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.
// 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.
// 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.
// 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.
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);
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);
}
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);
// 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.
// 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.
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) {
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);
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) {
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;
}
#include "wx/stc/stc.h"
#include "ScintillaWX.h"
+#include <wx/wx.h>
#include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
//----------------------------------------------------------------------
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)
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) {
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;
}
void NotifyChange();
void NotifyParent(SCNotification* scn);
-
-private:
DECLARE_EVENT_TABLE()
DECLARE_CLASS(wxStyledTextCtrl)
+protected:
+
ScintillaWX* m_swx;
wxStopWatch m_stopWatch;
wxScrollBar* m_vScrollBar;
#endif
};
+
+
#ifndef SWIG
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650)
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 {
wxEVT_STC_DRAG_OVER,
wxEVT_STC_DO_DROP,
wxEVT_STC_ZOOM,
+ wxEVT_STC_HOTSPOT_CLICK,
+ wxEVT_STC_HOTSPOT_DCLICK,
+ wxEVT_STC_CALLTIP_CLICK
};
#endif
#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
//----------------------------------------------------------------------
// 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
#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.
#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
#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
#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.
#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
#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
#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
// 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
// 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
// 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
//----------------------------------------------------------------------
// 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);
// 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);
// 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);
// 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);
// 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.
// 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);
// 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.
// 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();
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);
// 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();
void NotifyChange();
void NotifyParent(SCNotification* scn);
-
-private:
DECLARE_EVENT_TABLE()
DECLARE_CLASS(wxStyledTextCtrl)
+protected:
+
ScintillaWX* m_swx;
wxStopWatch m_stopWatch;
wxScrollBar* m_vScrollBar;
#endif
};
+
+
#ifndef SWIG
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650)
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 {
wxEVT_STC_DRAG_OVER,
wxEVT_STC_DO_DROP,
wxEVT_STC_ZOOM,
+ wxEVT_STC_HOTSPOT_CLICK,
+ wxEVT_STC_HOTSPOT_DCLICK,
+ wxEVT_STC_CALLTIP_CLICK
};
#endif
#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
//----------------------------------------------------------------------
};
//----------------------------------------------------------------------
+// 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
{
void OnAbout(wxCommandEvent& event);
private:
- wxStyledTextCtrl* ed;
+ MySTC* ed;
DECLARE_EVENT_TABLE()
};
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;
//----------------------------------------
// 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
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();
}
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 \
UniConversion.o \
ViewStyle.o \
WindowAccessor.o \
+ XPM.o \
+
DEPFILES=$(OBJECTS:.o=.d)
#include <wx/wx.h>
#include <wx/encconv.h>
-
+#include <wx/listctrl.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
+#include <wx/imaglist.h>
#include "Platform.h"
#include "PlatWX.h"
false,
stc2wx(faceName),
encoding);
-#ifdef __WXMAC__
- ((wxFont*)id)->SetNoAntiAliasing( true ) ;
-#endif
}
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_);
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();
// 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;
((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));
}
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...
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];
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; i<str.Length(); i++) {
+ int w, h;
+ hdc->GetTextExtent(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) {
}
+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;
#endif
}
+void SurfaceImpl::SetDBCSMode(int codePage) {
+ // dbcsMode = codePage == SC_CP_DBCS;
+}
+
+
Surface *Surface::Allocate() {
return new SurfaceImpl;
}
}
void Window::Destroy() {
- if (id)
+ if (id) {
+ Show(FALSE);
GETWIN(id)->Destroy();
+ }
id = 0;
}
}
PRectangle Window::GetPosition() {
+ if (! id) return PRectangle();
wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
return PRectangleFromwxRect(rc);
}
}
PRectangle Window::GetClientPosition() {
+ if (! id) return PRectangle();
wxSize sz = GETWIN(id)->GetClientSize();
return PRectangle(0, 0, sz.x, sz.y);
}
case cursorReverseArrow:
cursorId = wxCURSOR_RIGHT_ARROW;
break;
+ case cursorHand:
+ cursorId = wxCURSOR_HAND;
default:
cursorId = wxCURSOR_ARROW;
break;
// 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 <wx/popupwin.h>
-#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();
}
//----------------------------------------------------------------------
}
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));
}
return false;
}
+int Platform::DBCSCharLength(int codePage, const char *s) {
+ return 0;
+}
+
+int Platform::DBCSCharMaxLength() {
+ return 0;
+}
//----------------------------------------------------------------------
#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;
}
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,
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()
ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
+ capturedMouse = false;
wMain = win;
stc = win;
wheelRotation = 0;
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;
}
}
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;
+ }
}
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<char *>(lParam);
AutoCompleteCancel();
- if (!ct.wCallTip.Created()) {
- Point pt = LocationFromPosition(wParam);
- pt.y += vs.lineHeight;
- PRectangle rc = ct.CallTipStart(currentPos, pt,
- reinterpret_cast<char *>(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);
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
}
// 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;
}
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
+}
//----------------------------------------------------------------------
#include "Platform.h"
#include "Scintilla.h"
+#include "XPM.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "PropSet.h"
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
wxDragResult dragResult;
#endif
int wheelRotation;
+
+
+ friend class wxSTCCallTip;
};
//----------------------------------------------------------------------
# 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
# 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
# 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
# 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
(2176, 2180),
(2390, 2393),
(2395, 2396),
+ 2404,
+ (2413, 2416),
+ (2450, 2454),
]
'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),
'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),
'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),
'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."));
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),
'GetFocus' : ('GetSTCFocus', 0, 0, 0),
+ 'LoadLexerLibrary' : (None, 0,0,0),
+
+
# Remove all methods that are key commands since they can be
# executed with CmdKeyExecute
'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),
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 \
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:
$(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) \
$(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
$(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 \
$(D)\UniConversion.obj \
$(D)\ViewStyle.obj \
$(D)\WindowAccessor.obj \
+ $(D)\XPM.obj \
\
$(D)\PlatWX.obj \
$(D)\ScintillaWX.obj \
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 &
UniConversion.obj &
ViewStyle.obj &
WindowAccessor.obj &
+ XPM.obj &
PlatWX.obj &
ScintillaWX.obj &
- stc.obj
+ stc.obj
all: $(STCLIB) .SYMBOLIC
*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)
--- /dev/null
+License for Scintilla and SciTE
+
+Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+
+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
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
char buf[bufferSize+1];
int startPos;
int endPos;
- int codePage;
+ int codePage;
virtual bool InternalIsLeadByte(char ch)=0;
virtual void Fill(int position)=0;
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;
}
}
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
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; }
** 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 <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PLATFORM_H
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; }
};
}
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 {
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;
}
desired = desired_;
allocated.Set(desired.AsLong());
}
+ void Copy() {
+ allocated.Set(desired.AsLong());
+ }
};
class Window; // Forward declaration for Palette
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;
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;
virtual void FlushCachedState()=0;
virtual void SetUnicodeMode(bool unicodeMode_)=0;
+ virtual void SetDBCSMode(int codePage)=0;
};
/**
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();
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:
*/
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;
};
/**
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(
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);
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; }
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');
};
return append(sOther, static_cast<lenpos_t>(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);
*/
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);
}
#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
#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
#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
#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
/** @file Scintilla.h
** Interface to the edit control.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// 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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
# 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,)
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
# 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
# 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)
# 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,)
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)
# 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.
# 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,)
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.
# 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.
# 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(,)
# 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(,)
# 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(,)
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.
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(,)
# 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(,)
# 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.
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.
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
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
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)
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
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"
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();
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();
/** @file AutoComplete.cxx
** Defines the auto completion list box.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#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;
bool AutoComplete::IsFillUpChar(char ch) {
return ch && strchr(fillUpChars, ch);
}
-
+
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
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) {
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);
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
if (location == -1 && autoHide)
Cancel();
else
- lb.Select(location);
+ lb->Select(location);
}
/** @file AutoComplete.h
** Defines the auto completion list box.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef AUTOCOMPLETE_H
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?
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_);
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);
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
+ xUp = -100;
+ xDown = -100;
+ lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
val = 0;
}
+const int widthArrow = 14;
+
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(colourBG, want);
pal.WantFind(colourUnSel, 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<len;i++) {
+ if (s[i] <= '\002') {
+ if (i > 0)
+ ends[maxEnd++] = i;
+ ends[maxEnd++] = i+1;
+ }
+ }
+ ends[maxEnd++] = len;
+ int startSeg = 0;
+ int xEnd;
+ for (int seg = 0; seg<maxEnd; seg++) {
+ int endSeg = ends[seg];
+ if (endSeg > 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) {
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);
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;
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<int>(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() {
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;
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);
}
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<char>((curVal & ~mask) | style));
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);
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
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
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<unsigned char>(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<unsigned char>(cb.CharAt(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<Platform::DBCSCharMaxLength(); i++) {
+ mbstr[i] = cb.CharAt(pos+i);
+ }
+ mbstr[i] = '\0';
+ return Platform::DBCSCharLength(dbcsCodePage, mbstr);
} else {
return 1;
}
// 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--;
- 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<Platform::DBCSCharMaxLength();i++) {
+ mbstr[i] = cb.CharAt(startLine+i);
+ }
+ mbstr[i] = '\0';
+
+ int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ if (startLine + mbsize == pos) {
+ return pos;
+ } else if (startLine + mbsize > pos) {
+ if (moveDir > 0) {
+ return startLine + mbsize;
+ } else {
+ return startLine;
+ }
+ }
+ startLine += mbsize;
}
}
}
sWithStyle[i*2] = s[i];
sWithStyle[i*2 + 1] = 0;
}
- changed = InsertStyledString(position*2, sWithStyle,
+ changed = InsertStyledString(position*2, sWithStyle,
static_cast<int>(insertLength*2));
delete []sWithStyle;
}
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);
}
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;
}
/**
- * 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.
}
/**
- * 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) {
* 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)
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;
}
// 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);
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;
}
}
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<char>(MakeUpperCase(ch)));
}
} else {
- if (isupper(ch)) {
+ if (IsUpperCase(ch)) {
ChangeChar(pos, static_cast<char>(MakeLowerCase(ch)));
}
}
}
} else {
for (ch = 0; ch < 256; ch++) {
- if (ch >= 0x80 || isalnum(ch) || ch == '_')
+ if (ch >= 0x80 || isalnum(ch) || ch == '_')
charClass[ch] = ccWord;
}
}
return false;
} else {
enteredCount++;
+ style &= stylingMask;
int prevEndStyled = endStyled;
if (cb.SetStyleFor(endStyled, length, style, stylingMask)) {
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
}
bool Document::IsWordPartSeparator(char ch) {
- return ispunct(ch) && (WordCharClass(ch) == ccWord);
+ return (WordCharClass(ch) == ccWord) && IsPunctuation(ch);
}
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;
}
}
}
++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;
}
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
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_) {
};
}
bool Overlaps(Range other) const {
- return
+ return
Contains(other.start) ||
Contains(other.end) ||
other.Contains(start) ||
}
};
-private:
+private:
int refCount;
CellBuffer cb;
enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
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();
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);
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_),
*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
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();
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();
/** @file Editor.cxx
** Main code for the edit control.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "Platform.h"
+#ifndef PLAT_QT
#define INCLUDE_DEPRECATED_FEATURES
+#endif
#include "Scintilla.h"
#include "ContractionState.h"
#include "CellBuffer.h"
#include "KeyMap.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
positions(0),
widthLine(wrapWidthInfinite),
lines(1) {
- Resize(maxLineLength_);
+ Resize(maxLineLength_);
}
LineLayout::~LineLayout() {
int *newLineStarts = new int[newMaxLines];
if (!newLineStarts)
return;
- for (int i=0; i<newMaxLines; i++) {
+ for (int i = 0; i < newMaxLines; i++) {
if (i < lenLineStarts)
newLineStarts[i] = lineStarts[i];
else
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight) {
+ char bracesMatchStyle, int xHighlight) {
if (rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
}
}
if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) ||
- (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
+ (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
xHighlightGuide = xHighlight;
}
}
size = (size / 16 + 1) * 16;
}
if (size > 0) {
- cache = new LineLayout *[size];
+ cache = new LineLayout * [size];
}
- for (int i=0; i<size; i++)
+ for (int i = 0; i < size; i++)
cache[i] = 0;
}
if (lengthForLevel > size) {
Deallocate();
} else if (lengthForLevel < length) {
- for (int i=lengthForLevel; i<length; i++) {
+ for (int i = lengthForLevel; i < length; i++) {
delete cache[i];
cache[i] = 0;
}
}
void LineLayoutCache::Deallocate() {
- for (int i=0; i<length; i++)
+ for (int i = 0; i < length; i++)
delete cache[i];
delete []cache;
cache = 0;
void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
if (cache && !allInvalidated) {
- for (int i=0; i<length; i++) {
+ for (int i = 0; i < length; i++) {
if (cache[i]) {
cache[i]->Invalidate(validity_);
}
}
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);
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;
}
printMagnification = 0;
printColourMode = SC_PRINT_NORMAL;
+ printWrapState = eWrapWord;
cursorMode = SC_CURSORNORMAL;
controlCharSymbol = 0; /* Draw the control characters */
mouseDownCaptures = true;
bufferedDraw = true;
+ twoPhaseDraw = true;
lastClickTime = 0;
dwellDelay = SC_TIME_FOREVER;
xCaretMargin = 50;
horizontalScrollBarVisible = true;
scrollWidth = 2000;
+ verticalScrollBarVisible = true;
endAtLastLine = true;
pixmapLine = Surface::Allocate();
modEventMask = SC_MODEVENTMASKALL;
pdoc = new Document();
- pdoc ->AddRef();
+ pdoc->AddRef();
pdoc->AddWatcher(this, 0);
recordingMacro = false;
wrapWidth = LineLayout::wrapWidthInfinite;
docLineLastWrapped = -1;
- llc.SetLevel(LineLayoutCache::llcDocument);
+ hsStart = -1;
+ hsEnd = -1;
+
+ llc.SetLevel(LineLayoutCache::llcCaret);
}
Editor::~Editor() {
void Editor::RefreshStyleData() {
if (!stylesValid) {
stylesValid = true;
- AutoSurface surface(IsUnicodeMode());
+ AutoSurface surface(this);
if (surface) {
vs.Refresh(*surface);
RefreshColourPalette(palette, true);
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];
}
}
+// 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();
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;
if (posInLine > ll->maxLineLength) {
pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
}
- for (int subLine=0; subLine<ll->lines; 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)) {
}
pt.x += vs.fixedColumnWidth - xOffset;
}
- llc.Dispose(ll);
return pt;
}
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;
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;
}
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);
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;
}
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);
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;
}
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;
}
} else {
SetEmptySelection(newPos);
}
+ ShowCaretAtCurrentPosition();
if (ensureVisible)
EnsureCaretVisible();
- ShowCaretAtCurrentPosition();
NotifyMove(newPos);
return 0;
}
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
} else {
Redraw();
}
- SetVerticalScrollPos();
+ if (moveThumb) {
+ SetVerticalScrollPos();
+ }
}
}
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; subLine<ll->lines; 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;
}
}
newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
if (newTopLine != topLine) {
+ Redraw();
SetTopLine(newTopLine);
SetVerticalScrollPos();
- Redraw();
}
}
}
} 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
}
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();
}
if (wrapState == eWrapNone) {
if (wrapWidth != LineLayout::wrapWidthInfinite) {
wrapWidth = LineLayout::wrapWidthInfinite;
- for (int lineDoc=0; lineDoc<pdoc->LinesTotal(); lineDoc++) {
+ for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
cs.SetHeight(lineDoc, 1);
}
wrapOccurred = true;
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;
}
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;
// 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) {
// 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;
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
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) {
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());
}
/**
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++;
}
}
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<char>(styleByte & styleMask));
- allSame = allSame &&
- (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+ if (vstyle.viewEOL || (!IsEOLChar(chDoc != '\r'))) {
+ allSame = allSame &&
+ (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+ allSame = allSame &&
+ (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
else
allSame = allSame &&
- (ll->chars[numCharsInLine] == chDoc);
+ (ll->chars[numCharsInLine] == chDoc);
numCharsInLine++;
}
}
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<char>(styleByte & styleMask);
ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
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:
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
- ll->positions + startseg + 1);
+ ll->positions + startseg + 1);
}
lastSegItalics = false;
} else { // Regular character
} 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
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;
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;
}
}
}
}
+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) {
}
}
+ 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))) {
// 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;
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;
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<char>(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++) {
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);
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 {
}
}
}
- 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;
}
// 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) {
}
}
-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);
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);
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)) {
surface = pixmapLine;
}
surface->SetUnicodeMode(IsUnicodeMode());
+ surface->SetDBCSMode(CodePage());
int visibleLine = topLine + screenLinePaintFirst;
//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);
// 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;
}
ll->containsCaret = false;
}
+ GetHotSpotRange(ll->hsStart, ll->hsEnd);
+
PRectangle rcLine = rcClient;
rcLine.top = ypos;
rcLine.bottom = ypos + vs.lineHeight;
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
- highlightGuideColumn * vs.spaceWidth);
+ highlightGuideColumn * vs.spaceWidth);
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
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
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);
visibleLine++;
//gdk_flush();
}
- llc.Dispose(ll);
//if (durPaint < 0.00000001)
// durPaint = 0.00000001;
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;
}
// 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;
}
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);
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 {
}
// Empty method is overridden on GTK+ to show / hide scrollbars
-void Editor::ReconfigureScrollBars() {
-}
+void Editor::ReconfigureScrollBars() {}
void Editor::SetScrollBars() {
RefreshStyleData();
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);
}
}
if (treatAsDBCS) {
NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
- static_cast<unsigned char>(s[1]));
+ static_cast<unsigned char>(s[1]));
} else {
int byte = static_cast<unsigned char>(s[0]);
if ((byte < 0xC0) || (1 == len)) {
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.
}
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();
- }
}
}
}
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;
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()) {
}
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();
}
}
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 {
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;
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);
}
case SCI_REPLACESEL:
case SCI_ADDTEXT:
case SCI_INSERTTEXT:
+ case SCI_APPENDTEXT:
case SCI_CLEARALL:
case SCI_SELECTALL:
case SCI_GOTOLINE:
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:
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:
case SCI_FORMFEED:
case SCI_VCHOME:
case SCI_VCHOMEEXTEND:
+ case SCI_VCHOMEWRAP:
+ case SCI_VCHOMEWRAPEXTEND:
case SCI_DELWORDLEFT:
case SCI_DELWORDRIGHT:
case SCI_DELLINELEFT:
case SCI_LINECUT:
case SCI_LINEDELETE:
case SCI_LINETRANSPOSE:
+ case SCI_LINEDUPLICATE:
case SCI_LOWERCASE:
case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
case SCI_NEWLINE:
default:
// printf("Filtered out %ld of macro recording\n", iMessage);
- return;
+ return ;
}
// Send notification
}
}
+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() {
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.
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; subLine<ll->lines; 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 {
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);
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);
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();
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);
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;
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++;
case SCI_LINETRANSPOSE:
LineTranspose();
break;
+ case SCI_LINEDUPLICATE:
+ LineDuplicate();
+ break;
case SCI_LOWERCASE:
ChangeCaseOfSelection(false);
break;
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;
}
* @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<TextToFind *>(lParam);
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = pos;
* @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.
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
&lengthFound);
}
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
+ (searchFlags & SCFIND_POSIX) != 0,
&lengthFound);
if (pos != -1) {
targetStart = pos;
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;
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;
SetMouseCapture(true);
selectionType = selLine;
} else {
+ if (PositionIsHotspot(newPos)) {
+ NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+ }
if (!shift) {
inDragDrop = PointInSelection(pt);
}
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);
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) {
}
EnsureCaretVisible(false, false, true);
+ if (hsStart != -1 && !PositionIsHotspot(movePos))
+ SetHotSpotRange(NULL);
+
} else {
if (vs.fixedColumnWidth > 0) { // There is a margin
if (PointInSelMargin(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);
+ }
}
}
DisplayCursor(Window::cursorReverseArrow);
} else {
DisplayCursor(Window::cursorText);
+ SetHotSpotRange(NULL);
}
xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
ptMouseLast = pt;
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);
}
}
if ((dwellDelay < SC_TIME_FOREVER) &&
- (ticksToDwell > 0) &&
- (!HaveMouseCapture())) {
+ (ticksToDwell > 0) &&
+ (!HaveMouseCapture())) {
ticksToDwell -= timer.tickSize;
if (ticksToDwell <= 0) {
dwelling = true;
if (hasFocus) {
ShowCaretAtCurrentPosition();
} else {
+ CancelModes();
DropCaret();
}
}
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);
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
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();
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;
}
switch (iMessage) {
- case SCI_GETTEXT:
- {
+ case SCI_GETTEXT: {
if (lParam == 0)
return 0;
if (wParam == 0)
return iChar;
}
- case SCI_SETTEXT:
- {
+ case SCI_SETTEXT: {
if (lParam == 0)
return 0;
pdoc->DeleteChars(0, pdoc->Length());
// 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<int>(wParam) < 0) ||
(static_cast<int>(wParam) > pdoc->LineFromPosition(pdoc->Length())))
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);
case SCI_SETXOFFSET:
xOffset = wParam;
+ SetHorizontalScrollPos();
Redraw();
break;
case SCI_GETXOFFSET:
return xOffset;
+ case SCI_CHOOSECARETX:
+ SetLastXChosen();
+ break;
+
case SCI_SCROLLCARET:
EnsureCaretVisible();
break;
return 0;
}
+ case SCI_APPENDTEXT:
+ pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam);
+ return 0;
+
case SCI_CLEARALL:
ClearAll();
return 0;
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<short>(wParam) >= pdoc->Length())
return 0;
pdoc->SetStyleFor(wParam, static_cast<char>(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));
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;
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));
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();
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();
}
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);
InvalidateStyleRedraw();
}
break;
+ case SCI_STYLESETHOTSPOT:
+ if (wParam <= STYLE_MAX) {
+ vs.styles[wParam].hotspot = lParam != 0;
+ InvalidateStyleRedraw();
+ }
+ break;
case SCI_STYLERESETDEFAULT:
vs.ResetDefaultStyle();
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;
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
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:
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:
case SCI_FORMFEED:
case SCI_VCHOME:
case SCI_VCHOMEEXTEND:
+ case SCI_VCHOMEWRAP:
+ case SCI_VCHOMEWRAPEXTEND:
case SCI_ZOOMIN:
case SCI_ZOOMOUT:
case SCI_DELWORDLEFT:
case SCI_LINECUT:
case SCI_LINEDELETE:
case SCI_LINETRANSPOSE:
+ case SCI_LINEDUPLICATE:
case SCI_LOWERCASE:
case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
return reinterpret_cast<sptr_t>(pdoc);
case SCI_SETDOCPOINTER:
+ CancelModes();
SetDocPointer(reinterpret_cast<Document *>(lParam));
return 0;
case SCI_CREATEDOCUMENT: {
Document *doc = new Document();
- doc->AddRef();
+ if (doc) {
+ doc->AddRef();
+ }
return reinterpret_cast<sptr_t>(doc);
}
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);
}
/** @file Editor.h
** Defines the main editor class.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
int *positions;
char bracePreviousStyles[2];
+ // Hotspot support
+ int hsStart;
+ int hsEnd;
+
// Wrapped line support
int widthLine;
int lines;
}
};
-/**
- * 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 {
int printMagnification;
int printColourMode;
+ int printWrapState;
int cursorMode;
int controlCharSymbol;
/** 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;
int foldFlags;
ContractionState cs;
+ // Hotspot support
+ int hsStart;
+ int hsEnd;
+
// Wrapping support
enum { eWrapNone, eWrapWord } wrapState;
int wrapWidth;
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);
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);
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);
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);
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:
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
// Scintilla source code edit control
-/** @file KeyMap.cxx
+/** @file KeyMap.cxx
** Defines a mapping between keystrokes and commands.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
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);
}
{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},
{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},
{'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},
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;
return wordListDescriptions[index];
}
}
-
+
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
//++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);
LINK_LEXER(lmLatex);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPOV);
LINK_LEXER(lmPython);
LINK_LEXER(lmRuby);
LINK_LEXER(lmSQL);
// SciTE - Scintilla based Text Editor
/** @file LexAVE.cxx
** Lexer for Avenue.
+ **
+ ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <stdio.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
#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<char>(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<char>(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<char>(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<char>(tolower(chNext));
+ chNext = static_cast<char>(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<char>(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);
+
-// SciTE - Scintilla based Text Editor
-// LexAda.cxx - lexer for Ada95
-// by Tahir Karaca <tahir@bigfoot.de>
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
// The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
#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<char>(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<char>(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<char>(sc.ch);
+ sc.Forward();
+ }
+
+ // Special case: exponent with sign
+ if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+ (sc.ch == '+' || sc.ch == '-')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward ();
+
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ number += static_cast<char>(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<char>(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 == '_';
+}
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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);
+
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 ||
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++) {
}
}
-LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant");
+static const char * const bullantWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
#include "Scintilla.h"
#include "SciLexer.h"
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
static bool IsOKBeforeRE(const int ch) {
return (ch == '(') || (ch == '=') || (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) {
}
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];
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);
} 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);
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);
// 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);
}
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;
}
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;
}
if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
if (ch == '#') {
- unsigned int j=i+1;
- while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ unsigned int j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
j++;
}
if (styler.Match(j, "region") || styler.Match(j, "if")) {
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
+static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ int foldFlags = styler.GetPropertyInt("fold.flags") ;
+ bool foldBox = ((foldFlags & SC_FOLDFLAG_BOX) == SC_FOLDFLAG_BOX);
+
+ if (foldBox) {
+ FoldBoxCppDoc(startPos, length, initStyle, keywordlists, styler);
+ } else {
+ FoldNoBoxCppDoc(startPos, length, initStyle, styler);
+ }
+}
+
static const char * const cppWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- 0,
-};
-
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc, cppWordLists);
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Fold header keywords",
+ 0,
+ };
+
+static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmTCL(SCLEX_TCL, ColouriseCppDocSensitive, "tcl", FoldCppDoc, cppWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCSS.cxx
+ ** Lexer for Cascade Style Sheets
+ ** Written by Jakub Vrána
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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);
delete []buffer;
}
-LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf");
+static const char * const confWordListDesc[] = {
+ "Directives",
+ "Parameters",
+ 0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
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;
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);
ch == '{' || ch == '}' || ch == '~' ||
ch == '[' || ch == ']' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' ||
- ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
+ ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
ch == '!' || ch == '@' || ch == '?';
}
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;
}
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);
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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<unsigned int>(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<char>(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<char>(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);
/** @file LexHTML.cxx
** Lexer for HTML.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
}
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<char>(tolower(ch));
+ if ((ch != '<') && (ch != '/')) {
+ s[i++] = caseSensitive ? ch : static_cast<char>(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] == '!') {
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 ||
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
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;
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;
}
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;
scriptLanguage = eScriptVBS;
styler.ColourTo(i, SCE_H_ASP);
// fold whole script
- levelCurrent++;
+ if (foldHTMLPreprocessor)
+ levelCurrent++;
// should be better
ch = styler.SafeGetCharAt(i);
continue;
state = SCE_H_SGML_COMMAND; // wait for a pending command
}
// fold whole tag (-- when closing the tag)
-
- levelCurrent++;
+ if (foldHTMLPreprocessor)
+ levelCurrent++;
continue;
}
inScriptType = eHtml;
scriptLanguage = eScriptNone;
// unfold all scripting languages
- levelCurrent--;
+ if (foldHTMLPreprocessor)
+ levelCurrent--;
continue;
}
/////////////////////////////////////
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;
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
+ if (!tagDontFold){
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
}
tagClosing = false;
} else if (ch == '/' && chNext == '>') {
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);
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);
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)) {
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;
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++;
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;
}
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;
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 == '\"') {
}
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;
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;
}
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) {
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);
// Handle some PHP script
if (sc.state == SCE_HPHP_WORD) {
- if (!IsAWordStart(sc.ch)) {
+ if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_COMMENTLINE) {
sc.ForwardSetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_VARIABLE) {
- if (!IsAWordStart(sc.ch)) {
+ if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_DEFAULT);
}
} else if (sc.state == SCE_HPHP_OPERATOR) {
}
}
if (sc.state == SCE_HPHP_DEFAULT) {
- if (IsAWordStart(sc.ch)) {
+ if (IsPhpWordStart(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_WORD);
} else if (sc.ch == '#') {
sc.SetState(SCE_HPHP_COMMENTLINE);
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<char>(sc.chNext))) {
sc.SetState(SCE_HPHP_VARIABLE);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HPHP_OPERATOR);
if (isLispwordstart(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_IDENTIFIER;
- }
+ }
else if (ch == ';') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_COMMENT;
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
}
-
+
else if (ch == '\"') {
state = SCE_LISP_STRING;
}
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) {
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);
#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 == '_');
}
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
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);
// 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') {
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))) {
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<char>(sc.ch))) {
+ } else if (isLuaOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_LUA_OPERATOR);
}
}
sc.Complete();
}
-
static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
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);
/** @file LexMatlab.cxx
** Lexer for Matlab.
** Written by José Fonseca
- **/
+ **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
}
}
-LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc);
+static const char * const matlabWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
#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'));
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] == '%' &&
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);
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
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
}
}
+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);
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 " ) &&
} 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 <filename>:<line>:message
- // Look for <filename>(line)message
- // Look for <filename>(line,pos)message
+ // Look for GCC <filename>:<line>:message
+ // Look for Microsoft <filename>(line) :message
+ // Look for Microsoft <filename>(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) {
} 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);
}
}
}
}
- 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);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPOV.cxx
+ ** Lexer for POV-Ray, based on lexer for C++.
+ **/
+// Copyright 2003 by Steven te Brinke <steven.t.b@zonnet.nl>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#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<char>(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);
}
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;
WordList& keywords = *keywordlists[0];
WordList& classwords = *keywordlists[1];
-
+
char s[100];
getRange(start, end, styler, s, sizeof(s));
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')) {
levelPrev = levelCurrent;
visibleChars = 0;
}
-
+
if (!isspacechar(ch))
visibleChars++;
}
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);
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);
// Scintilla source code edit control
/** @file LexPython.cxx
** Lexer for Python.
- **/
+ **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
}
/* 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);
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
} else if (whingeLevel == 4) {
chFlags = (spaceFlags & wsTab) ? chBad : chGood;
}
+ sc.SetState(sc.state);
styler.SetFlags(chFlags, static_cast<char>(sc.state));
}
(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);
break;
}
+ bool needEOLCheck = false;
+
// Check for a state end
if (sc.state == SCE_P_OPERATOR) {
kwLast = kwOther;
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 == '\\') {
sc.Forward();
sc.Forward();
sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
}
} else if (sc.state == SCE_P_TRIPLEDOUBLE) {
if (sc.ch == '\\') {
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))) {
} 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();
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
}
static const char * const pythonWordListDesc[] = {
- "Python keywords",
+ "Keywords",
0
};
-LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
+LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
pythonWordListDesc);
} 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);
}
}
}
-
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc);
+
+static const char * const rubyWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
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);
}
static inline bool IsADateCharacter(const int ch) {
- return (ch < 0x80) &&
+ return (ch < 0x80) &&
(isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
}
styler.StartAt(startPos);
int visibleChars = 0;
-
+
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
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') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
-
+
if (sc.state == SCE_B_DEFAULT) {
if (sc.ch == '\'') {
sc.SetState(SCE_B_COMMENT);
} else if (sc.ch == '#') {
int n = 1;
int chSeek = ' ';
- while (chSeek == ' ' || chSeek == '\t') {
+ while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
chSeek = sc.GetRelative(n);
n++;
}
sc.SetState(SCE_B_OPERATOR);
}
}
-
+
if (sc.atLineEnd) {
visibleChars = 0;
}
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);
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <string.h>
+
#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;
}
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++;
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<char>(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) {
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
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);
};
/** @file PropSet.cxx
** A Java style properties file module.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Maintain a dictionary of properties
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+//#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
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) {
lenVal = static_cast<int>(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<unsigned int>(lenKey)) &&
+ if ((hash == p->hash) &&
+ ((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
(0 == strncmp(p->key, key, lenKey)))) {
// Replace current value
delete [](p->val);
p->val = StringDup(val, lenVal);
- return ;
+ return;
}
}
// Not found
}
void PropSet::Set(const char *keyVal) {
- while (isspace(*keyVal))
+ while (IsASpace(*keyVal))
keyVal++;
const char *endVal = keyVal;
while (*endVal && (*endVal != '\n'))
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 $()
base = newbase;
}
cpvar = strstr(base, "$(");
+ maxExpands--;
}
SString sret = base;
delete []base;
if (keyfile == NULL)
keyfile = orgkeyfile;
- for (; ; ) {
+ for (;;) {
char *del = strchr(keyfile, ';');
if (del == NULL)
del = keyfile + strlen(keyfile);
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 $()
base = newbase;
}
cpvar = strstr(base, "$(");
+ maxExpands--;
}
SString sret = base;
delete []base;
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;
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--;
}
}
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, ' ');
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;
* 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
* 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
*
* 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.
*
* void re_fail(msg, op)
* char *msg;
* char op;
- *
+ *
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
*
* [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:
*
* 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.
*
* 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
*
const char bitarr[] = {1,2,4,8,16,32,64,'\200'};
#define badpat(x) (*nfa = END, x)
-
+
RESearch::RESearch() {
Init();
}
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 */
int n;
char mask; /* xor mask -CCL/NCL */
int c1, c2;
-
+
if (!pat || !length)
if (sta)
return 0;
const char *p=pat; /* pattern pointer */
for (int i=0; i<length; i++, p++) {
+ if (mp > mpMax)
+ return badpat("Pattern too long");
lp = mp;
switch(*p) {
i++;
if (*++p == '^') {
- mask = '\377';
+ mask = '\377';
i++;
p++;
} else
for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
*mp++ = static_cast<char>(mask ^ bittab[n]);
-
+
break;
case '*': /* match 0 or more.. */
i++;
switch(*++p) {
- case '(':
- if (tagc < MAXTAG) {
- tagstk[++tagi] = tagc;
- *mp++ = BOT;
- *mp++ = static_cast<char>(tagc++);
- }
- else
- return badpat("Too many \\(\\) pairs");
- break;
- case ')':
- if (*sp == BOT)
- return badpat("Null pattern inside \\(\\)");
- if (tagi > 0) {
- *mp++ = static_cast<char>(EOT);
- *mp++ = static_cast<char>(tagstk[tagi--]);
- }
- else
- return badpat("Unmatched \\)");
- break;
case '<':
*mp++ = BOW;
break;
*mp++ = escapeValue(*p);
break;
default:
- *mp++ = CHR;
- *mp++ = *p;
+ if (!posix && *p == '(') {
+ if (tagc < MAXTAG) {
+ tagstk[++tagi] = tagc;
+ *mp++ = BOT;
+ *mp++ = static_cast<char>(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<char>(EOT);
+ *mp++ = static_cast<char>(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<char>(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<char>(EOT);
+ *mp++ = static_cast<char>(tagstk[tagi--]);
+ }
+ else
+ return badpat("Unmatched )");
+ } else if (caseSensitive) {
*mp++ = CHR;
*mp++ = *p;
} else {
sp = lp;
}
if (tagi > 0)
- return badpat("Unmatched \\(");
+ return badpat((posix ? "Unmatched (" : "Unmatched \\("));
*mp = END;
sta = OKP;
return 0;
* RESearch::Execute:
* execute nfa to find a match.
*
- * special cases: (nfa[0])
+ * special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
bol = lp;
failure = 0;
-
+
Clear();
switch(*ap) {
return 1;
}
-/*
+/*
* PMatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
*
* 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).
*
*/
* 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
};
#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;
* 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;
pin = c - '0';
break;
}
-
+
default:
*dst++ = c;
continue;
* 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;
};
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);
*/
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) {
delete []v;
v = newv;
}
-
+
public:
SVector() {
allocFailure = false;
/** @file ScintillaBase.cxx
** An enhanced subclass of Editor with calltips, autocomplete and context menu.
**/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
return;
}
}
- ac.Start(wMain, idAutoComplete, currentPos, lenEntered);
+ ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
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;
}
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.
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();
}
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();
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);
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<char *>(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<const char *>(lParam));
+ break;
+
+ case SCI_CLEARREGISTEREDIMAGES:
+ ac.lb->ClearRegisteredImages();
+ break;
+
+ case SCI_AUTOCSETTYPESEPARATOR:
+ ac.SetTypesep(static_cast<char>(wParam));
+ break;
+
+ case SCI_AUTOCGETTYPESEPARATOR:
+ return ac.GetTypesep();
+
+ case SCI_CALLTIPSHOW:
+ CallTipShow(LocationFromPosition(wParam),
+ reinterpret_cast<const char *>(lParam));
break;
case SCI_CALLTIPCANCEL:
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;
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);
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;
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;
caseForce = source.caseForce;
visible = source.visible;
changeable = source.changeable;
+ hotspot = source.hotspot;
}
Style::~Style() {
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;
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_;
caseForce = caseForce_;
visible = visible_;
changeable = changeable_;
+ hotspot = hotspot_;
if (aliasOfDefaultFont)
font.SetID(0);
else
source.eolFilled,
source.underline,
source.caseForce,
- source.visible,
- source.changeable);
+ source.visible,
+ source.changeable,
+ source.hotspot);
}
bool Style::EquivalentFontTo(const Style *other) const {
ecaseForced caseForce;
bool visible;
bool changeable;
+ bool hotspot;
Font font;
int sizeZoomed;
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
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);
}
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);
}
/** @file StyleContext.cxx
** Lexer infrastructure.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// 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<unsigned char>(styler.SafeGetCharAt(pos+1));
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(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;
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<unsigned char>(styler.SafeGetCharAt(pos));
if (styler.IsLeadByte(static_cast<char>(ch))) {
pos++;
ch = ch << 8;
ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
}
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
- }
- atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+ GetNextChar(pos);
}
void Complete() {
styler.ColourTo(currentPos - 1, state);
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<unsigned char>(styler.SafeGetCharAt(currentPos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(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 = ' ';
atLineEnd = true;
}
}
+ void Forward(int nb) {
+ for (int i = 0; i < nb; i++) {
+ Forward();
+ }
+ }
void ChangeState(int state_) {
state = state_;
}
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) {
/** @file ViewStyle.cxx
** Store information on how the document is to be viewed.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include "Scintilla.h"
#include "Indicator.h"
+#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
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;
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;
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;
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;
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);
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) {
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]);
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
+ if (styles[i].IsProtected()) {
+ someStylesProtected = true;
+ }
}
lineHeight = maxAscent + maxDescent;
}
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() {
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
styles[styleIndex].fontName = fontNames.Save(name);
}
+
+bool ViewStyle::ProtectionActive() const {
+ return someStylesProtected;
+}
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
ColourPair edgecolour;
int edgeState;
int caretWidth;
-
+ bool someStylesProtected;
+
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void ResetDefaultStyle();
void ClearStyles();
void SetStyleFontName(int styleIndex, const char *name);
+ bool ProtectionActive() const;
};
#endif
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
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);
}
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) {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) {
- Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
+ Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
styleBuf);
validLen = 0;
}
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;
}
ch = (*this)[++pos];
}
-
+
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
--- /dev/null
+// 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 <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.h>
+#include <stdlib.h>
+
+#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;i<nColours;i++) {
+ if (codes[i] == ch) {
+ return colours[i].allocated;
+ }
+ }
+ return colours[0].allocated;
+#endif
+}
+
+void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
+ if ((code != codeTransparent) && (startX != x)) {
+ PRectangle rc(startX, y, x, y+1);
+ surface->FillRectangle(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<const char * const *>(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<strings; i++) {
+ allocation += MeasureLength(linesForm[i]) + 1;
+ }
+ data = new char[allocation];
+ char *nextBit = data;
+ for (int j=0; j<strings; j++) {
+ lines[j] = nextBit;
+ size_t len = MeasureLength(linesForm[j]);
+ memcpy(nextBit, linesForm[j], len);
+ nextBit += len;
+ *nextBit++ = '\0';
+ }
+
+ for (int code=0;code<256; code++) {
+ colourCodeTable[code] = 0;
+ }
+
+ for (int c=0; c<nColours; c++) {
+ const char *colourDef = linesForm[c+1];
+ codes[c] = colourDef[0];
+ colourDef += 4;
+ if (*colourDef == '#') {
+ colours[c].desired.Set(colourDef);
+ } else {
+ colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
+ codeTransparent = codes[c];
+ }
+ colourCodeTable[static_cast<unsigned char>(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;i<nColours;i++) {
+ pal.WantFind(colours[i], want);
+ }
+}
+
+void XPM::CopyDesiredColours() {
+ if (!data || !codes || !colours || !lines) {
+ return;
+ }
+ for (int i=0;i<nColours;i++) {
+ colours[i].Copy();
+ }
+}
+
+void XPM::Draw(Surface *surface, PRectangle &rc) {
+ if (!data || !codes || !colours || !lines) {
+ return;
+ }
+ // Centre the pixmap
+ int startY = rc.top + (rc.Height() - height) / 2;
+ int startX = rc.left + (rc.Width() - width) / 2;
+ for (int y=0;y<height;y++) {
+ int prevCode = 0;
+ int xStartRun = 0;
+ for (int x=0; x<width; x++) {
+ int code = lines[y+nColours+1][x];
+ if (code != prevCode) {
+ FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
+ xStartRun = x;
+ prevCode = code;
+ }
+ }
+ FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
+ }
+}
+
+const char **XPM::LinesFormFromTextForm(const char *textForm) {
+ // Build the lines form out of the text form
+ const char **linesForm = 0;
+ int countQuotes = 0;
+ int strings=1;
+ for (int j=0; countQuotes < (2*strings); j++) {
+ if (textForm[j] == '\"') {
+ if (countQuotes == 0) {
+ const char *line0 = textForm + j + 1;
+ // Skip width
+ line0 = NextField(line0);
+ // Add 1 line for each pixel of height
+ strings += atoi(line0);
+ line0 = NextField(line0);
+ // Add 1 line for each colour
+ strings += atoi(line0);
+ linesForm = new const char *[strings];
+ }
+ if (linesForm && ((countQuotes & 1) == 0)) {
+ linesForm[countQuotes / 2] = textForm + j + 1;
+ }
+ countQuotes++;
+ }
+ }
+ return linesForm;
+}
+
+// In future, may want to minimize search time by sorting and using a binary search.
+
+XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
+}
+
+XPMSet::~XPMSet() {
+ Clear();
+}
+
+void XPMSet::Clear() {
+ for (int i=0;i<maximum;i++) {
+ delete set[i];
+ }
+ delete []set;
+ set = 0;
+ len = 0;
+ maximum = 0;
+ height = -1;
+ width = -1;
+}
+
+void XPMSet::Add(int id, const char *textForm) {
+ // Invalidate cached dimensions
+ height = -1;
+ width = -1;
+
+ // Replace if this id already present
+ for (int i=0;i<maximum;i++) {
+ if (set[i]->GetId() == 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; i<maximum; i++) {
+ setNew[i] = set[i];
+ }
+ delete []set;
+ set = setNew;
+ }
+ set[maximum] = pxpm;
+ maximum++;
+ }
+}
+
+XPM *XPMSet::Get(int id) {
+ for (int i=0;i<maximum;i++) {
+ if (set[i]->GetId() == id) {
+ return set[i];
+ }
+ }
+ return 0;
+}
+
+int XPMSet::GetHeight() {
+ if (height < 0) {
+ for (int i=0; i<maximum; i++) {
+ if (height < set[i]->GetHeight()) {
+ height = set[i]->GetHeight();
+ }
+ }
+ }
+ return (height > 0) ? height : 0;
+}
+
+int XPMSet::GetWidth() {
+ if (width < 0) {
+ for (int i=0; i<maximum; i++) {
+ if (width < set[i]->GetWidth()) {
+ width = set[i]->GetWidth();
+ }
+ }
+ }
+ return (width > 0) ? width : 0;
+}
--- /dev/null
+// 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 <neilh@scintilla.org>
+// 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
#include "wx/stc/stc.h"
#include "ScintillaWX.h"
+#include <wx/wx.h>
#include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
//----------------------------------------------------------------------
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)
// 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.
// 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.
// 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?
// 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
// 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.
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.
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);
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));
// 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.
// 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.
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);
// 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.
// 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.
// 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.
// 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.
// 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.
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);
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);
}
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);
// 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.
// 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.
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) {
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);
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) {
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;
}
#include "wx/stc/stc.h"
#include "ScintillaWX.h"
+#include <wx/wx.h>
#include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
//----------------------------------------------------------------------
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)
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) {
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;
}
void NotifyChange();
void NotifyParent(SCNotification* scn);
-
-private:
DECLARE_EVENT_TABLE()
DECLARE_CLASS(wxStyledTextCtrl)
+protected:
+
ScintillaWX* m_swx;
wxStopWatch m_stopWatch;
wxScrollBar* m_vScrollBar;
#endif
};
+
+
#ifndef SWIG
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE, 1650)
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 {
wxEVT_STC_DRAG_OVER,
wxEVT_STC_DO_DROP,
wxEVT_STC_ZOOM,
+ wxEVT_STC_HOTSPOT_CLICK,
+ wxEVT_STC_HOTSPOT_DCLICK,
+ wxEVT_STC_CALLTIP_CLICK
};
#endif
#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
//----------------------------------------------------------------------