Some wxStyledTextCtrl bugfixes

Merged in new Scintilla sources

Added new methods to wxStyledTextCtrl to match new Scintilla capabilities.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7302 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2000-04-28 06:37:53 +00:00
parent 21aff0fe10
commit efecda0bf7
94 changed files with 2690 additions and 1056 deletions

View File

@@ -130,7 +130,9 @@ enum {
wxSTC_CMD_LINEDELETE, wxSTC_CMD_LINEDELETE,
wxSTC_CMD_LINETRANSPOSE, wxSTC_CMD_LINETRANSPOSE,
wxSTC_CMD_LOWERCASE, wxSTC_CMD_LOWERCASE,
wxSTC_CMD_UPPERCASE wxSTC_CMD_UPPERCASE,
wxSTC_CMD_LINESCROLLDOWN,
wxSTC_CMD_LINESCROLLUP
}; };
@@ -253,7 +255,11 @@ public:
int GetLineStartPos(int line); int GetLineStartPos(int line);
int GetLineLengthAtPos(int pos); int GetLineLengthAtPos(int pos);
int GetLineLength(int line); int GetLineLength(int line);
wxString GetCurrentLineText(); #ifdef SWIG
wxString GetCurrentLineText(int* OUTPUT);
#else
wxString GetCurrentLineText(int* linePos);
#endif
int GetCurrentLine(); int GetCurrentLine();
int PositionFromPoint(wxPoint pt); int PositionFromPoint(wxPoint pt);
int LineFromPoint(wxPoint pt); int LineFromPoint(wxPoint pt);
@@ -274,7 +280,10 @@ public:
void EnsureCaretVisible(); void EnsureCaretVisible();
void SetCaretPolicy(int policy, int slop=0); void SetCaretPolicy(int policy, int slop=0);
int GetSelectionType(); int GetSelectionType();
int GetLinesOnScreen();
bool IsSelectionRectangle();
void SetUseHorizontalScrollBar(bool use);
bool GetUseHorizontalScrollBar();
// Searching // Searching
@@ -303,6 +312,8 @@ public:
void StartStyling(int pos, int mask); void StartStyling(int pos, int mask);
void SetStyleFor(int length, int style); void SetStyleFor(int length, int style);
void SetStyleBytes(int length, char* styleBytes); void SetStyleBytes(int length, char* styleBytes);
void SetLineState(int line, int value);
int GetLineState(int line);
// Style Definition // Style Definition
@@ -348,8 +359,15 @@ public:
// Other settings // Other settings
void SetBufferedDraw(bool isBuffered); void SetBufferedDraw(bool isBuffered);
void SetTabWidth(int numChars); void SetTabWidth(int numChars);
void SetIndent(int numChars);
void SetUseTabs(bool usetabs);
void SetLineIndentation(int line, int indentation);
int GetLineIndentation(int line);
int GetLineIndentationPos(int line);
void SetWordChars(const wxString& wordChars); void SetWordChars(const wxString& wordChars);
void SetUsePop(bool usepopup);
// Brace highlighting // Brace highlighting
void BraceHighlight(int pos1, int pos2); void BraceHighlight(int pos1, int pos2);
@@ -387,7 +405,9 @@ public:
int AutoCompPosAtStart(); int AutoCompPosAtStart();
void AutoCompComplete(); void AutoCompComplete();
void AutoCompStopChars(const wxString& stopChars); void AutoCompStopChars(const wxString& stopChars);
void AutoCompSetSeparator(char separator);
char AutoCompGetSeparator();
void AutoCompSelect(const wxString& stringtoselect);
// Call tips // Call tips
void CallTipShow(int pos, const wxString& text); void CallTipShow(int pos, const wxString& text);

View File

@@ -23,7 +23,16 @@ HEADER_SUBDIR=stc
HEADERS=stc.h HEADERS=stc.h
OBJECTS=PlatWX.o ScintillaWX.o stc.o \ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Accessor.o \ DocumentAccessor.o \
LexCPP.o \
LexHTML.o \
LexOthers.o \
LexPerl.o \
LexPython.o \
LexSQL.o \
LexVB.o \
UniConversion.o \
WindowAccessor.o \
AutoComplete.o \ AutoComplete.o \
CallTip.o \ CallTip.o \
CellBuffer.o \ CellBuffer.o \
@@ -33,18 +42,12 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Indicator.o \ Indicator.o \
KeyMap.o \ KeyMap.o \
KeyWords.o \ KeyWords.o \
LexCPP.o \
LexHTML.o \
LexOthers.o \
LexPerl.o \
LexPython.o \
LexSQL.o \
LexVB.o \
LineMarker.o \ LineMarker.o \
PropSet.o \ PropSet.o \
ScintillaBase.o \ ScintillaBase.o \
Style.o \ Style.o \
ViewStyle.o ViewStyle.o \
APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include

View File

@@ -196,6 +196,12 @@ int Surface::LogPixelsY() {
return hdc->GetPPI().y; return hdc->GetPPI().y;
} }
int Surface::DeviceHeightFont(int points) {
return points * LogPixelsY() / 72;
}
void Surface::MoveTo(int x_, int y_) { void Surface::MoveTo(int x_, int y_) {
x = x_; x = x_;
y = y_; y = y_;

View File

@@ -195,9 +195,8 @@ void ScintillaWX::NotifyParent(SCNotification scn) {
void ScintillaWX::Copy() { void ScintillaWX::Copy() {
if (currentPos != anchor) { if (currentPos != anchor) {
char* text = CopySelectionRange(); char* text = CopySelectionRange();
textDO.SetText(text);
wxTheClipboard->Open(); wxTheClipboard->Open();
wxTheClipboard->SetData(&textDO); wxTheClipboard->SetData(new wxTextDataObject(text));
wxTheClipboard->Close(); wxTheClipboard->Close();
} }
} }

View File

@@ -139,7 +139,6 @@ private:
bool capturedMouse; bool capturedMouse;
wxStyledTextCtrl* stc; wxStyledTextCtrl* stc;
wxTextDataObject textDO;
wxSTCDropTarget* dropTarget; wxSTCDropTarget* dropTarget;
wxDragResult dragResult; wxDragResult dragResult;
}; };

View File

@@ -25,17 +25,13 @@ OBJECTS = \
AutoComplete.obj \ AutoComplete.obj \
CallTip.obj \ CallTip.obj \
CellBuffer.obj \ CellBuffer.obj \
ContractionState.obj\ ContractionState.obj \
Document.obj \ Document.obj \
DocumentAccessor.obj \
Editor.obj \ Editor.obj \
Indicator.obj \ Indicator.obj \
KeyMap.obj \ KeyMap.obj \
KeyWords.obj \ KeyWords.obj \
LineMarker.obj \
PropSet.obj \
ScintillaBase.obj \
Style.obj \
ViewStyle.obj \
LexCPP.obj \ LexCPP.obj \
LexHTML.obj \ LexHTML.obj \
LexOthers.obj \ LexOthers.obj \
@@ -43,11 +39,19 @@ OBJECTS = \
LexPython.obj \ LexPython.obj \
LexSQL.obj \ LexSQL.obj \
LexVB.obj \ LexVB.obj \
LineMarker.obj \
PropSet.obj \
ScintillaBase.obj \
Style.obj \
UniConversion.obj \
ViewStyle.obj \
WindowAccessor.obj \
\ \
PlatWX.obj \ PlatWX.obj \
ScintillaWX.obj \ ScintillaWX.obj \
stc.obj \ stc.obj \
!include $(WXDIR)\src\makelib.b32 !include $(WXDIR)\src\makelib.b32
CFG = stc.cfg CFG = stc.cfg

View File

@@ -32,6 +32,9 @@ OBJECTS = \
$(S)/LexPython.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \
$(S)/LexSQL.$(OBJSUFF) \ $(S)/LexSQL.$(OBJSUFF) \
$(S)/LexVB.$(OBJSUFF) \ $(S)/LexVB.$(OBJSUFF) \
$(S)/DocumentAccessor.$(OBJSUFF)\
$(S)/UniConversion.$(OBJSUFF) \
$(S)/WindowAccessor.$(OBJSUFF) \
PlatWX.$(OBJSUFF) \ PlatWX.$(OBJSUFF) \
ScintillaWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \
stc.$(OBJSUFF) stc.$(OBJSUFF)

View File

@@ -15,21 +15,16 @@ NOPCH=1
!include $(WXDIR)\src\makevc.env !include $(WXDIR)\src\makevc.env
OBJECTS = \ OBJECTS = \
$(D)\Accessor.obj \
$(D)\AutoComplete.obj \ $(D)\AutoComplete.obj \
$(D)\CallTip.obj \ $(D)\CallTip.obj \
$(D)\CellBuffer.obj \ $(D)\CellBuffer.obj \
$(D)\ContractionState.obj\ $(D)\ContractionState.obj\
$(D)\Document.obj \ $(D)\Document.obj \
$(D)\DocumentAccessor.obj\
$(D)\Editor.obj \ $(D)\Editor.obj \
$(D)\Indicator.obj \ $(D)\Indicator.obj \
$(D)\KeyMap.obj \ $(D)\KeyMap.obj \
$(D)\KeyWords.obj \ $(D)\KeyWords.obj \
$(D)\LineMarker.obj \
$(D)\PropSet.obj \
$(D)\ScintillaBase.obj \
$(D)\Style.obj \
$(D)\ViewStyle.obj \
$(D)\LexCPP.obj \ $(D)\LexCPP.obj \
$(D)\LexHTML.obj \ $(D)\LexHTML.obj \
$(D)\LexOthers.obj \ $(D)\LexOthers.obj \
@@ -37,6 +32,13 @@ OBJECTS = \
$(D)\LexPython.obj \ $(D)\LexPython.obj \
$(D)\LexSQL.obj \ $(D)\LexSQL.obj \
$(D)\LexVB.obj \ $(D)\LexVB.obj \
$(D)\LineMarker.obj \
$(D)\PropSet.obj \
$(D)\ScintillaBase.obj \
$(D)\Style.obj \
$(D)\UniConversion.obj \
$(D)\ViewStyle.obj \
$(D)\WindowAccessor.obj \
\ \
$(D)\PlatWX.obj \ $(D)\PlatWX.obj \
$(D)\ScintillaWX.obj \ $(D)\ScintillaWX.obj \

View File

@@ -5,29 +5,28 @@
enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
class Accessor;
typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
// Interface to data in a Scintilla
class Accessor { class Accessor {
protected: protected:
// bufferSize is a trade off between time taken to copy the characters and SendMessage overhead enum {extremePosition=0x7FFFFFFF};
// bufferSize is a trade off between time taken to copy the characters and retrieval overhead
// slopSize positions the buffer before the desired position in case there is some backtracking // slopSize positions the buffer before the desired position in case there is some backtracking
enum {bufferSize=4000, slopSize=bufferSize/8}; enum {bufferSize=4000, slopSize=bufferSize/8};
char buf[bufferSize+1]; char buf[bufferSize+1];
WindowID id;
PropSet &props;
int startPos; int startPos;
int endPos; int endPos;
int lenDoc;
int offset; // Optional but including an offset makes GCC generate better code
int codePage; int codePage;
bool InternalIsLeadByte(char ch);
void Fill(int position); virtual bool InternalIsLeadByte(char ch)=0;
virtual void Fill(int position)=0;
public: public:
Accessor(WindowID id_, PropSet &props_, int offset_=0) : Accessor() : startPos(extremePosition), endPos(0), codePage(0) {}
id(id_), props(props_), startPos(0x7FFFFFFF), endPos(0), virtual ~Accessor() {}
lenDoc(-1), offset(offset_), codePage(0) {
}
void SetCodePage(int codePage_) { codePage = codePage_; }
char operator[](int position) { char operator[](int position) {
position += offset;
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
Fill(position); Fill(position);
} }
@@ -35,7 +34,6 @@ public:
} }
char SafeGetCharAt(int position, char chDefault=' ') { char SafeGetCharAt(int position, char chDefault=' ') {
// Safe version of operator[], returning a defined value for invalid position // Safe version of operator[], returning a defined value for invalid position
position += offset;
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
Fill(position); Fill(position);
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
@@ -48,41 +46,25 @@ public:
bool IsLeadByte(char ch) { bool IsLeadByte(char ch) {
return codePage && InternalIsLeadByte(ch); return codePage && InternalIsLeadByte(ch);
} }
char StyleAt(int position); void SetCodePage(int codePage_) { codePage = codePage_; }
int GetLine(int position);
int LineStart(int line); virtual char StyleAt(int position)=0;
int LevelAt(int line); virtual int GetLine(int position)=0;
int Length(); virtual int LineStart(int line)=0;
void Flush() { virtual int LevelAt(int line)=0;
startPos = 0x7FFFFFFF; virtual int Length()=0;
lenDoc = -1; virtual void Flush()=0;
} virtual int GetLineState(int line)=0;
int GetLineState(int line); virtual int SetLineState(int line, int state)=0;
int SetLineState(int line, int state); virtual int GetPropertyInt(const char *key, int defaultValue=0)=0;
PropSet &GetPropSet() { return props; }
}; // Style setting
virtual void StartAt(unsigned int start, char chMask=31)=0;
class StylingContext; virtual void SetFlags(char chFlags_, char chWhile_)=0;
virtual unsigned int GetStartSegment()=0;
typedef bool (*PFNIsCommentLeader)(StylingContext &styler, int pos, int len); virtual void StartSegment(unsigned int pos)=0;
virtual void ColourTo(unsigned int pos, int chAttr)=0;
class StylingContext : public Accessor { virtual void SetLevel(int line, int level)=0;
char styleBuf[bufferSize]; virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0;
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
public:
StylingContext(WindowID id_, PropSet &props_, int offset_=0) :
Accessor(id_,props_,offset_), validLen(0), chFlags(0) {}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
int GetLine(int position);
void SetLevel(int line, int level);
void Flush();
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
}; };

View File

@@ -4,7 +4,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], StylingContext &styler); WordList *keywordlists[], Accessor &styler);
class LexerModule { class LexerModule {
static LexerModule *base; static LexerModule *base;
@@ -14,7 +14,7 @@ class LexerModule {
public: public:
LexerModule(int language_, LexerFunction fn_); LexerModule(int language_, LexerFunction fn_);
static void Colourise(unsigned int startPos, int lengthDoc, int initStyle, static void Colourise(unsigned int startPos, int lengthDoc, int initStyle,
int language, WordList *keywordlists[], StylingContext &styler); int language, WordList *keywordlists[], Accessor &styler);
}; };
inline bool iswordchar(char ch) { inline bool iswordchar(char ch) {

View File

@@ -45,6 +45,7 @@
#pragma warning(disable: 4800 4244 4309) #pragma warning(disable: 4800 4244 4309)
#endif #endif
#include <windows.h> #include <windows.h>
#include <commctrl.h>
#include <richedit.h> #include <richedit.h>
#endif #endif
@@ -221,6 +222,7 @@ public:
// A surface abstracts a place to draw // A surface abstracts a place to draw
class Surface { class Surface {
private: private:
bool unicodeMode;
#if PLAT_GTK #if PLAT_GTK
GdkDrawable *drawable; GdkDrawable *drawable;
GdkGC *gc; GdkGC *gc;
@@ -268,6 +270,7 @@ public:
bool Initialised(); bool Initialised();
void PenColour(Colour fore); void PenColour(Colour fore);
int LogPixelsY(); int LogPixelsY();
int DeviceHeightFont(int points);
void MoveTo(int x_, int y_); void MoveTo(int x_, int y_);
void LineTo(int x_, int y_); void LineTo(int x_, int y_);
void Polygon(Point *pts, int npts, Colour fore, Colour back); void Polygon(Point *pts, int npts, Colour fore, Colour back);
@@ -293,6 +296,10 @@ public:
int SetPalette(Palette *pal, bool inBackGround); int SetPalette(Palette *pal, bool inBackGround);
void SetClip(PRectangle rc); void SetClip(PRectangle rc);
void FlushCachedState(); void FlushCachedState();
void SetUnicodeMode(bool unicodeMode_) {
unicodeMode=unicodeMode_;
}
}; };
// Class to hide the details of window manipulation // Class to hide the details of window manipulation
@@ -303,6 +310,7 @@ protected:
WindowID id; WindowID id;
public: public:
Window() : id(0) {} Window() : id(0) {}
Window(const Window &source) : id(source.id) {}
virtual ~Window(); virtual ~Window();
Window &operator=(WindowID id_) { Window &operator=(WindowID id_) {
id = id_; id = id_;

View File

@@ -75,7 +75,7 @@ public:
else else
return 0; return 0;
} }
char operator[](int i) { char operator[](int i) const {
if (s) if (s)
return s[i]; return s[i];
else else
@@ -95,7 +95,7 @@ public:
} }
return *this; return *this;
} }
int value() { int value() const {
if (s) if (s)
return atoi(s); return atoi(s);
else else
@@ -168,7 +168,7 @@ public:
WordList(bool onlyLineEnds_ = false) : WordList(bool onlyLineEnds_ = false) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {} words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {}
~WordList() { Clear(); } ~WordList() { Clear(); }
operator bool() { return list; } operator bool() { return list ? true : false; }
const char *operator[](int ind) { return words[ind]; } const char *operator[](int ind) { return words[ind]; }
void Clear(); void Clear();
void Set(const char *s); void Set(const char *s);

View File

@@ -21,6 +21,7 @@
#define SCLEX_ERRORLIST 10 #define SCLEX_ERRORLIST 10
#define SCLEX_MAKEFILE 11 #define SCLEX_MAKEFILE 11
#define SCLEX_BATCH 12 #define SCLEX_BATCH 12
#define SCLEX_XCODE 13
// Lexical states for SCLEX_PYTHON // Lexical states for SCLEX_PYTHON
#define SCE_P_DEFAULT 0 #define SCE_P_DEFAULT 0

View File

@@ -107,6 +107,9 @@ extern "C" {
#define SCI_STARTSTYLING SCI_START + 32 #define SCI_STARTSTYLING SCI_START + 32
#define SCI_SETSTYLING SCI_START + 33 #define SCI_SETSTYLING SCI_START + 33
// This is the same value as CP_UTF8 in Windows
#define SC_CP_UTF8 65001
#define SCI_SETBUFFEREDDRAW SCI_START + 35 #define SCI_SETBUFFEREDDRAW SCI_START + 35
#define SCI_SETTABWIDTH SCI_START + 36 #define SCI_SETTABWIDTH SCI_START + 36
#define SCI_SETCODEPAGE SCI_START + 37 #define SCI_SETCODEPAGE SCI_START + 37
@@ -213,6 +216,21 @@ extern "C" {
#define SCI_AUTOCPOSSTART SCI_START + 103 #define SCI_AUTOCPOSSTART SCI_START + 103
#define SCI_AUTOCCOMPLETE SCI_START + 104 #define SCI_AUTOCCOMPLETE SCI_START + 104
#define SCI_AUTOCSTOPS SCI_START + 105 #define SCI_AUTOCSTOPS SCI_START + 105
#define SCI_AUTOCSETSEPARATOR SCI_START + 106
#define SCI_AUTOCGETSEPARATOR SCI_START + 107
#define SCI_AUTOCSELECT SCI_START + 108
#define SCI_GETTABWIDTH SCI_START + 121
#define SCI_SETINDENT SCI_START + 122
#define SCI_GETINDENT SCI_START + 123
#define SCI_SETUSETABS SCI_START + 124
#define SCI_GETUSETABS SCI_START + 125
#define SCI_SETLINEINDENTATION SCI_START + 126
#define SCI_GETLINEINDENTATION SCI_START + 127
#define SCI_GETLINEINDENTPOSITION SCI_START + 128
#define SCI_SETHSCROLLBAR SCI_START + 130
#define SCI_GETHSCROLLBAR SCI_START + 131
#define SCI_CALLTIPSHOW SCI_START + 200 #define SCI_CALLTIPSHOW SCI_START + 200
#define SCI_CALLTIPCANCEL SCI_START + 201 #define SCI_CALLTIPCANCEL SCI_START + 201
@@ -284,6 +302,8 @@ extern "C" {
#define SCI_LINETRANSPOSE SCI_START + 339 #define SCI_LINETRANSPOSE SCI_START + 339
#define SCI_LOWERCASE SCI_START + 340 #define SCI_LOWERCASE SCI_START + 340
#define SCI_UPPERCASE SCI_START + 341 #define SCI_UPPERCASE SCI_START + 341
#define SCI_LINESCROLLDOWN SCI_START + 342
#define SCI_LINESCROLLUP SCI_START + 343
#define SCI_LINELENGTH SCI_START + 350 #define SCI_LINELENGTH SCI_START + 350
#define SCI_BRACEHIGHLIGHT SCI_START + 351 #define SCI_BRACEHIGHLIGHT SCI_START + 351
@@ -318,6 +338,7 @@ extern "C" {
#define SCI_SETCARETPOLICY SCI_START + 369 #define SCI_SETCARETPOLICY SCI_START + 369
#define SCI_LINESONSCREEN SCI_START + 370 #define SCI_LINESONSCREEN SCI_START + 370
#define SCI_USEPOPUP SCI_START + 371 #define SCI_USEPOPUP SCI_START + 371
#define SCI_SELECTIONISRECTANGLE SCI_START + 372
// GTK+ Specific // GTK+ Specific
#define SCI_GRABFOCUS SCI_START + 400 #define SCI_GRABFOCUS SCI_START + 400
@@ -350,8 +371,10 @@ typedef void (tMacroRecorder)(UINT iMessage, WPARAM wParam, LPARAM lParam,
#define SC_PERFORMED_REDO 0x40 #define SC_PERFORMED_REDO 0x40
#define SC_LASTSTEPINUNDOREDO 0x100 #define SC_LASTSTEPINUNDOREDO 0x100
#define SC_MOD_CHANGEMARKER 0x200 #define SC_MOD_CHANGEMARKER 0x200
#define SC_MOD_BEFOREINSERT 0x400
#define SC_MOD_BEFOREDELETE 0x800
#define SC_MODEVENTMASKALL 0x377 #define SC_MODEVENTMASKALL 0xF77
struct SCNotification { struct SCNotification {
NMHDR nmhdr; NMHDR nmhdr;

View File

@@ -0,0 +1,47 @@
// WindowAccessor.h - implementation of BufferAccess and StylingAccess on a Scintilla rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
class WindowAccessor : public Accessor {
// Private so WindowAccessor objects can not be copied
WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
WindowAccessor &operator=(const WindowAccessor &) { return *this; }
protected:
WindowID id;
PropSet &props;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
WindowAccessor(WindowID id_, PropSet &props_) :
Accessor(), id(id_), props(props_),
lenDoc(-1), validLen(0), chFlags(0) {
}
~WindowAccessor();
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
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);
}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
};

View File

@@ -15,6 +15,7 @@ AutoComplete::AutoComplete() {
active = false; active = false;
posStart = 0; posStart = 0;
strcpy(stopChars, ""); strcpy(stopChars, "");
separator = ' ';
} }
AutoComplete::~AutoComplete() { AutoComplete::~AutoComplete() {
@@ -44,6 +45,14 @@ bool AutoComplete::IsStopChar(char ch) {
return ch && strchr(stopChars, ch); return ch && strchr(stopChars, ch);
} }
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
char AutoComplete::GetSeparator() {
return separator;
}
int AutoComplete::SetList(const char *list) { int AutoComplete::SetList(const char *list) {
int maxStrLen = 12; int maxStrLen = 12;
lb.Clear(); lb.Clear();
@@ -53,7 +62,7 @@ int AutoComplete::SetList(const char *list) {
char *startword = words; char *startword = words;
int i = 0; int i = 0;
for (; words && words[i]; i++) { for (; words && words[i]; i++) {
if (words[i] == ' ') { if (words[i] == separator) {
words[i] = '\0'; words[i] = '\0';
lb.Append(startword); lb.Append(startword);
maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); maxStrLen = Platform::Maximum(maxStrLen, strlen(startword));

View File

@@ -9,6 +9,7 @@
class AutoComplete { class AutoComplete {
bool active; bool active;
char stopChars[256]; char stopChars[256];
char separator;
public: public:
ListBox lb; ListBox lb;
int posStart; int posStart;
@@ -27,7 +28,11 @@ public:
void SetStopChars(const char *stopChars_); void SetStopChars(const char *stopChars_);
bool IsStopChar(char ch); bool IsStopChar(char ch);
// The list string contains a sequence of words separated by spaces // The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
char GetSeparator();
// The list string contains a sequence of words separated by the separator character
int SetList(const char *list); int SetList(const char *list);
void Show(); void Show();

View File

@@ -6,13 +6,14 @@
#ifndef CALLTIP_H #ifndef CALLTIP_H
#define CALLTIP_H #define CALLTIP_H
const char callClassName[] = "CallTip";
class CallTip { class CallTip {
int startHighlight; int startHighlight;
int endHighlight; int endHighlight;
char *val; char *val;
Font font; Font font;
// Private so CallTip objects can not be copied
CallTip(const CallTip &) {}
CallTip &operator=(const CallTip &) { return *this; }
public: public:
Window wCallTip; Window wCallTip;
Window wDraw; Window wDraw;

View File

@@ -191,11 +191,23 @@ void LineVector::InsertValue(int pos, int value) {
} }
} }
lines++; lines++;
for (int i = lines + 1; i > pos; i--) { for (int i = lines; i > pos; i--) {
linesData[i] = linesData[i - 1]; linesData[i] = linesData[i - 1];
} }
linesData[pos].startPosition = value; linesData[pos].startPosition = value;
linesData[pos].handleSet = 0; linesData[pos].handleSet = 0;
if (levels) {
for (int j = lines; j > pos; j--) {
levels[j] = levels[j - 1];
}
if (pos == 0) {
levels[pos] = SC_FOLDLEVELBASE;
} else if (pos == (lines-1)) { // Last line will not be a folder
levels[pos] = SC_FOLDLEVELBASE;
} else {
levels[pos] = levels[pos-1];
}
}
} }
void LineVector::SetValue(int pos, int value) { void LineVector::SetValue(int pos, int value) {
@@ -221,6 +233,15 @@ void LineVector::Remove(int pos) {
for (int i = pos; i < lines; i++) { for (int i = pos; i < lines; i++) {
linesData[i] = linesData[i + 1]; linesData[i] = linesData[i + 1];
} }
if (levels) {
// Level information merges back onto previous line
int posAbove = pos-1;
if (posAbove < 0)
posAbove = 0;
for (int j = posAbove; j < lines; j++) {
levels[j] = levels[j + 1];
}
}
lines--; lines--;
} }
@@ -233,9 +254,8 @@ int LineVector::LineFromPosition(int pos) {
return lines - 1; return lines - 1;
int lower = 0; int lower = 0;
int upper = lines; int upper = lines;
int middle = 0;
do { do {
middle = (upper + lower + 1) / 2; // Round high int middle = (upper + lower + 1) / 2; // Round high
if (pos < linesData[middle].startPosition) { if (pos < linesData[middle].startPosition) {
upper = middle - 1; upper = middle - 1;
} else { } else {
@@ -316,12 +336,13 @@ Action::~Action() {
Destroy(); Destroy();
} }
void Action::Create(actionType at_, int position_, char *data_, int lenData_) { void Action::Create(actionType at_, int position_, char *data_, int lenData_, bool mayCoalesce_) {
delete []data; delete []data;
position = position_; position = position_;
at = at_; at = at_;
data = data_; data = data_;
lenData = lenData_; lenData = lenData_;
mayCoalesce = mayCoalesce_;
} }
void Action::Destroy() { void Action::Destroy() {
@@ -336,12 +357,14 @@ void Action::Grab(Action *source) {
at = source->at; at = source->at;
data = source->data; data = source->data;
lenData = source->lenData; lenData = source->lenData;
mayCoalesce = source->mayCoalesce;
// Ownership of source data transferred to this // Ownership of source data transferred to this
source->position = 0; source->position = 0;
source->at = startAction; source->at = startAction;
source->data = 0; source->data = 0;
source->lenData = 0; source->lenData = 0;
source->mayCoalesce = true;
} }
// The undo history stores a sequence of user operations that represent the user's view of the // The undo history stores a sequence of user operations that represent the user's view of the
@@ -426,6 +449,8 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
//Platform::DebugPrintf("action coalesced\n"); //Platform::DebugPrintf("action coalesced\n");
} }
} else { } else {
// Actions not at top level are always coalesced unless this is after return to top level
if (!actions[currentAction].mayCoalesce)
currentAction++; currentAction++;
} }
} else { } else {
@@ -445,6 +470,7 @@ void UndoHistory::BeginUndoAction() {
actions[currentAction].Create(startAction); actions[currentAction].Create(startAction);
maxAction = currentAction; maxAction = currentAction;
} }
actions[currentAction].mayCoalesce = false;
} }
undoSequenceDepth++; undoSequenceDepth++;
} }
@@ -458,6 +484,7 @@ void UndoHistory::EndUndoAction() {
actions[currentAction].Create(startAction); actions[currentAction].Create(startAction);
maxAction = currentAction; maxAction = currentAction;
} }
actions[currentAction].mayCoalesce = false;
} }
} }
@@ -499,8 +526,12 @@ int UndoHistory::StartUndo() {
return currentAction - act; return currentAction - act;
} }
const Action &UndoHistory::UndoStep() { const Action &UndoHistory::GetUndoStep() const {
return actions[currentAction--]; return actions[currentAction];
}
void UndoHistory::CompletedUndoStep() {
currentAction--;
} }
bool UndoHistory::CanRedo() const { bool UndoHistory::CanRedo() const {
@@ -520,8 +551,12 @@ int UndoHistory::StartRedo() {
return act - currentAction; return act - currentAction;
} }
const Action &UndoHistory::RedoStep() { const Action &UndoHistory::GetRedoStep() const {
return actions[currentAction++]; return actions[currentAction];
}
void UndoHistory::CompletedRedoStep() {
currentAction++;
} }
CellBuffer::CellBuffer(int initialLength) { CellBuffer::CellBuffer(int initialLength) {
@@ -673,7 +708,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) {
bool CellBuffer::SetStyleAt(int position, char style, char mask) { bool CellBuffer::SetStyleAt(int position, char style, char mask) {
char curVal = ByteAt(position*2 + 1); char curVal = ByteAt(position*2 + 1);
if ((curVal & mask) != style) { if ((curVal & mask) != style) {
SetByteAt(position*2 + 1, (curVal & ~mask) | style); SetByteAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style));
return true; return true;
} else { } else {
return false; return false;
@@ -686,7 +721,7 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas
while (lengthStyle--) { while (lengthStyle--) {
char curVal = ByteAt(bytePos); char curVal = ByteAt(bytePos);
if ((curVal & mask) != style) { if ((curVal & mask) != style) {
SetByteAt(bytePos, (curVal & ~mask) | style); SetByteAt(bytePos, static_cast<char>((curVal & ~mask) | style));
changed = true; changed = true;
} }
bytePos += 2; bytePos += 2;
@@ -947,8 +982,12 @@ int CellBuffer::StartUndo() {
return uh.StartUndo(); return uh.StartUndo();
} }
const Action &CellBuffer::UndoStep() { const Action &CellBuffer::GetUndoStep() const {
const Action &actionStep = uh.UndoStep(); return uh.GetUndoStep();
}
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) { if (actionStep.at == insertAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2); BasicDeleteChars(actionStep.position, actionStep.lenData*2);
} else if (actionStep.at == removeAction) { } else if (actionStep.at == removeAction) {
@@ -960,7 +999,7 @@ const Action &CellBuffer::UndoStep() {
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
delete []styledData; delete []styledData;
} }
return actionStep; uh.CompletedUndoStep();
} }
bool CellBuffer::CanRedo() { bool CellBuffer::CanRedo() {
@@ -971,8 +1010,12 @@ int CellBuffer::StartRedo() {
return uh.StartRedo(); return uh.StartRedo();
} }
const Action &CellBuffer::RedoStep() { const Action &CellBuffer::GetRedoStep() const {
const Action &actionStep = uh.RedoStep(); return uh.GetRedoStep();
}
void CellBuffer::PerformRedoStep() {
const Action &actionStep = uh.GetRedoStep();
if (actionStep.at == insertAction) { if (actionStep.at == insertAction) {
char *styledData = new char[actionStep.lenData * 2]; char *styledData = new char[actionStep.lenData * 2];
for (int i = 0; i < actionStep.lenData; i++) { for (int i = 0; i < actionStep.lenData; i++) {
@@ -984,7 +1027,7 @@ const Action &CellBuffer::RedoStep() {
} else if (actionStep.at == removeAction) { } else if (actionStep.at == removeAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2); BasicDeleteChars(actionStep.position, actionStep.lenData*2);
} }
return actionStep; uh.CompletedRedoStep();
} }
int CellBuffer::SetLineState(int line, int state) { int CellBuffer::SetLineState(int line, int state) {

View File

@@ -79,10 +79,11 @@ public:
int position; int position;
char *data; char *data;
int lenData; int lenData;
bool mayCoalesce;
Action(); Action();
~Action(); ~Action();
void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0); void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true);
void Destroy(); void Destroy();
void Grab(Action *source); void Grab(Action *source);
}; };
@@ -119,10 +120,12 @@ public:
// called that many times. Similarly for redo. // called that many times. Similarly for redo.
bool CanUndo() const; bool CanUndo() const;
int StartUndo(); int StartUndo();
const Action &UndoStep(); const Action &GetUndoStep() const;
void CompletedUndoStep();
bool CanRedo() const; bool CanRedo() const;
int StartRedo(); int StartRedo();
const Action &RedoStep(); const Action &GetRedoStep() const;
void CompletedRedoStep();
}; };
// Holder for an expandable array of characters that supports undo and line markers // Holder for an expandable array of characters that supports undo and line markers
@@ -171,7 +174,7 @@ public:
// Setting styles for positions outside the range of the buffer is safe and has no effect. // Setting styles for positions outside the range of the buffer is safe and has no effect.
// True is returned if the style of a character changed. // True is returned if the style of a character changed.
bool SetStyleAt(int position, char style, char mask=(char)0xff); bool SetStyleAt(int position, char style, char mask='\377');
bool SetStyleFor(int position, int length, char style, char mask); bool SetStyleFor(int position, int length, char style, char mask);
const char *DeleteChars(int position, int deleteLength); const char *DeleteChars(int position, int deleteLength);
@@ -206,10 +209,12 @@ public:
// called that many times. Similarly for redo. // called that many times. Similarly for redo.
bool CanUndo(); bool CanUndo();
int StartUndo(); int StartUndo();
const Action &UndoStep(); const Action &GetUndoStep() const;
void PerformUndoStep();
bool CanRedo(); bool CanRedo();
int StartRedo(); int StartRedo();
const Action &RedoStep(); const Action &GetRedoStep() const;
void PerformRedoStep();
int SetLineState(int line, int state); int SetLineState(int line, int state);
int GetLineState(int line); int GetLineState(int line);

View File

@@ -30,7 +30,6 @@ void ContractionState::MakeValid() const {
if (!valid) { if (!valid) {
// Could be cleverer by keeping the index of the last still valid entry // Could be cleverer by keeping the index of the last still valid entry
// rather than invalidating all. // rather than invalidating all.
int linePrev = -1;
int lineDisplay = 0; int lineDisplay = 0;
for (int line=0; line<linesInDoc; line++) { for (int line=0; line<linesInDoc; line++) {
lines[line].displayLine = lineDisplay; lines[line].displayLine = lineDisplay;
@@ -113,7 +112,7 @@ void ContractionState::InsertLines(int lineDoc, int lineCount) {
} }
linesInDoc += lineCount; linesInDoc += lineCount;
linesInDisplay += lineCount; linesInDisplay += lineCount;
for (int i = linesInDoc + 1; i >= lineDoc + lineCount; i--) { for (int i = linesInDoc; i >= lineDoc + lineCount; i--) {
lines[i].visible = lines[i - lineCount].visible; lines[i].visible = lines[i - lineCount].visible;
lines[i].expanded = lines[i - lineCount].expanded; lines[i].expanded = lines[i - lineCount].expanded;
} }
@@ -130,16 +129,18 @@ void ContractionState::DeleteLines(int lineDoc, int lineCount) {
linesInDisplay -= lineCount; linesInDisplay -= lineCount;
return; return;
} }
int delta = 0; int deltaDisplayed = 0;
for (int d=0;d<lineCount;d++) for (int d=0;d<lineCount;d++) {
if (lines[lineDoc+d].visible) if (lines[lineDoc+d].visible)
delta--; deltaDisplayed--;
}
for (int i = lineDoc; i < linesInDoc-lineCount; i++) { for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
if (i != 0) // Line zero is always visible
lines[i].visible = lines[i + lineCount].visible; lines[i].visible = lines[i + lineCount].visible;
lines[i].expanded = lines[i + lineCount].expanded; lines[i].expanded = lines[i + lineCount].expanded;
} }
linesInDoc -= lineCount; linesInDoc -= lineCount;
linesInDisplay += delta; linesInDisplay += deltaDisplayed;
valid = false; valid = false;
} }
@@ -154,6 +155,10 @@ bool ContractionState::GetVisible(int lineDoc) const {
} }
bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
if (lineDocStart == 0)
lineDocStart++;
if (lineDocStart > lineDocEnd)
return false;
if (size == 0) { if (size == 0) {
Grow(linesInDoc + growSize); Grow(linesInDoc + growSize);
} }

View File

@@ -32,7 +32,10 @@ Document::Document() {
} }
endStyled = 0; endStyled = 0;
enteredCount = 0; enteredCount = 0;
enteredReadOnlyCount = 0;
tabInChars = 8; tabInChars = 8;
indentInChars = 0;
useTabs = true;
watchers = 0; watchers = 0;
lenWatchers = 0; lenWatchers = 0;
} }
@@ -201,6 +204,10 @@ bool Document::IsCrLf(int pos) {
bool Document::IsDBCS(int pos) { bool Document::IsDBCS(int pos) {
#if PLAT_WIN #if PLAT_WIN
if (dbcsCodePage) { 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 // Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte. // not be a DBCS trail byte.
int startLine = pos; int startLine = pos;
@@ -215,12 +222,35 @@ bool Document::IsDBCS(int pos) {
startLine++; startLine++;
} }
} }
}
return false; return false;
#else #else
return false; return false;
#endif #endif
} }
int Document::LenChar(int pos) {
if (IsCrLf(pos)) {
return 2;
} else if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
if (ch < 0x80)
return 1;
int len = 2;
if (ch >= (0x80+0x40+0x20))
len = 3;
int lengthDoc = Length();
if ((pos + len) > lengthDoc)
return lengthDoc-pos;
else
return len;
} else if (IsDBCS(pos)) {
return 2;
} else {
return 1;
}
}
// Normalise a position so that it is not halfway through a two byte character. // Normalise a position so that it is not halfway through a two byte character.
// This can occur in two situations - // This can occur in two situations -
// When lines are terminated with \r\n pairs which should be treated as one character. // When lines are terminated with \r\n pairs which should be treated as one character.
@@ -252,6 +282,17 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
#if PLAT_WIN #if PLAT_WIN
if (dbcsCodePage) { if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
while ((pos > 0) && (pos < Length()) && (ch >= 0x80) && (ch < (0x80 + 0x40))) {
// ch is a trail byte
if (moveDir > 0)
pos++;
else
pos--;
ch = static_cast<unsigned char>(cb.CharAt(pos));
}
} else {
// Anchor DBCS calculations at start of line because start of line can // Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte. // not be a DBCS trail byte.
int startLine = pos; int startLine = pos;
@@ -277,6 +318,7 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos - 1; return pos - 1;
} }
} }
}
#endif #endif
return pos; return pos;
@@ -292,41 +334,60 @@ void Document::ModifiedAt(int pos) {
// Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number // Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number
void Document::DeleteChars(int pos, int len) { void Document::DeleteChars(int pos, int len) {
if (cb.IsReadOnly() && enteredReadOnlyCount==0) {
enteredReadOnlyCount++;
NotifyModifyAttempt();
enteredReadOnlyCount--;
}
if (enteredCount == 0) { if (enteredCount == 0) {
enteredCount++; enteredCount++;
if (cb.IsReadOnly())
NotifyModifyAttempt();
if (!cb.IsReadOnly()) { if (!cb.IsReadOnly()) {
NotifyModified(
DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_USER,
pos, len,
0, 0));
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
bool startSavePoint = cb.IsSavePoint(); bool startSavePoint = cb.IsSavePoint();
const char *text = cb.DeleteChars(pos*2, len * 2); const char *text = cb.DeleteChars(pos*2, len * 2);
if (startSavePoint && cb.IsCollectingUndo()) if (startSavePoint && cb.IsCollectingUndo())
NotifySavePoint(!startSavePoint); NotifySavePoint(!startSavePoint);
ModifiedAt(pos); ModifiedAt(pos);
int modFlags = SC_MOD_DELETETEXT | SC_PERFORMED_USER; NotifyModified(
DocModification mh(modFlags, pos, len, LinesTotal() - prevLinesTotal, text); DocModification(
NotifyModified(mh); SC_MOD_DELETETEXT | SC_PERFORMED_USER,
pos, len,
LinesTotal() - prevLinesTotal, text));
} }
enteredCount--; enteredCount--;
} }
} }
void Document::InsertStyledString(int position, char *s, int insertLength) { void Document::InsertStyledString(int position, char *s, int insertLength) {
if (cb.IsReadOnly() && enteredReadOnlyCount==0) {
enteredReadOnlyCount++;
NotifyModifyAttempt();
enteredReadOnlyCount--;
}
if (enteredCount == 0) { if (enteredCount == 0) {
enteredCount++; enteredCount++;
if (cb.IsReadOnly())
NotifyModifyAttempt();
if (!cb.IsReadOnly()) { if (!cb.IsReadOnly()) {
NotifyModified(
DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_USER,
position / 2, insertLength / 2,
0, 0));
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
bool startSavePoint = cb.IsSavePoint(); bool startSavePoint = cb.IsSavePoint();
const char *text = cb.InsertString(position, s, insertLength); const char *text = cb.InsertString(position, s, insertLength);
if (startSavePoint && cb.IsCollectingUndo()) if (startSavePoint && cb.IsCollectingUndo())
NotifySavePoint(!startSavePoint); NotifySavePoint(!startSavePoint);
ModifiedAt(position / 2); ModifiedAt(position / 2);
NotifyModified(
int modFlags = SC_MOD_INSERTTEXT | SC_PERFORMED_USER; DocModification(
DocModification mh(modFlags, position / 2, insertLength / 2, LinesTotal() - prevLinesTotal, text); SC_MOD_INSERTTEXT | SC_PERFORMED_USER,
NotifyModified(mh); position / 2, insertLength / 2,
LinesTotal() - prevLinesTotal, text));
} }
enteredCount--; enteredCount--;
} }
@@ -341,7 +402,15 @@ int Document::Undo() {
//Platform::DebugPrintf("Steps=%d\n", steps); //Platform::DebugPrintf("Steps=%d\n", steps);
for (int step=0; step<steps; step++) { for (int step=0; step<steps; step++) {
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
const Action &action = cb.UndoStep(); const Action &action = cb.GetUndoStep();
if (action.at == removeAction) {
NotifyModified(DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
int cellPosition = action.position / 2; int cellPosition = action.position / 2;
ModifiedAt(cellPosition); ModifiedAt(cellPosition);
newPos = cellPosition; newPos = cellPosition;
@@ -376,10 +445,17 @@ int Document::Redo() {
int steps = cb.StartRedo(); int steps = cb.StartRedo();
for (int step=0; step<steps; step++) { for (int step=0; step<steps; step++) {
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
const Action &action = cb.RedoStep(); const Action &action = cb.GetRedoStep();
int cellPosition = action.position / 2; if (action.at == insertAction) {
ModifiedAt(cellPosition); NotifyModified(DocModification(
newPos = cellPosition; SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
}
cb.PerformRedoStep();
ModifiedAt(action.position / 2);
newPos = action.position / 2;
int modFlags = SC_PERFORMED_REDO; int modFlags = SC_PERFORMED_REDO;
if (action.at == insertAction) { if (action.at == insertAction) {
@@ -390,7 +466,8 @@ int Document::Redo() {
} }
if (step == steps-1) if (step == steps-1)
modFlags |= SC_LASTSTEPINUNDOREDO; modFlags |= SC_LASTSTEPINUNDOREDO;
NotifyModified(DocModification(modFlags, cellPosition, action.lenData, NotifyModified(
DocModification(modFlags, action.position / 2, action.lenData,
LinesTotal() - prevLinesTotal, action.data)); LinesTotal() - prevLinesTotal, action.data));
} }
@@ -433,13 +510,7 @@ void Document::ChangeChar(int pos, char ch) {
} }
void Document::DelChar(int pos) { void Document::DelChar(int pos) {
if (IsCrLf(pos)) { DeleteChars(pos, LenChar(pos));
DeleteChars(pos, 2);
} else if (IsDBCS(pos)) {
DeleteChars(pos, 2);
} else if (pos < Length()) {
DeleteChars(pos, 1);
}
} }
int Document::DelCharBack(int pos) { int Document::DelCharBack(int pos) {
@@ -448,6 +519,10 @@ int Document::DelCharBack(int pos) {
} else if (IsCrLf(pos - 2)) { } else if (IsCrLf(pos - 2)) {
DeleteChars(pos - 2, 2); DeleteChars(pos - 2, 2);
return pos - 2; return pos - 2;
} else if (SC_CP_UTF8 == dbcsCodePage) {
int startChar = MovePositionOutsideChar(pos-1, -1, false);
DeleteChars(startChar, pos - startChar);
return startChar;
} else if (IsDBCS(pos - 1)) { } else if (IsDBCS(pos - 1)) {
DeleteChars(pos - 2, 2); DeleteChars(pos - 2, 2);
return pos - 2; return pos - 2;
@@ -457,27 +532,80 @@ int Document::DelCharBack(int pos) {
} }
} }
void Document::Indent(bool forwards, int lineBottom, int lineTop) { static bool isindentchar(char ch) {
if (forwards) { return (ch == ' ') || (ch == '\t');
// Indent by a tab }
for (int line = lineBottom; line >= lineTop; line--) {
InsertChar(LineStart(line), '\t'); static int NextTab(int pos, int tabSize) {
return ((pos / tabSize) + 1) * tabSize;
}
static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {
length--; // ensure space for \0
if (!insertSpaces) {
while ((indent >= tabSize) && (length > 0)) {
*linebuf++ = '\t';
indent -= tabSize;
length--;
} }
} else { }
while ((indent > 0) && (length > 0)) {
*linebuf++ = ' ';
indent--;
length--;
}
*linebuf = '\0';
}
int Document::GetLineIndentation(int line) {
int indent = 0;
if ((line >= 0) && (line < LinesTotal())) {
int lineStart = LineStart(line);
int length = Length();
for (int i=lineStart;i<length;i++) {
char ch = cb.CharAt(i);
if (ch == ' ')
indent++;
else if (ch == '\t')
indent = NextTab(indent, tabInChars);
else
return indent;
}
}
return indent;
}
void Document::SetLineIndentation(int line, int indent) {
int indentOfLine = GetLineIndentation(line);
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
char linebuf[1000];
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertString(thisLineStart, linebuf);
}
}
int Document::GetLineIndentPosition(int line) {
int pos = LineStart(line);
int length = Length();
while ((pos < length) && isindentchar(cb.CharAt(pos))) {
pos++;
}
return pos;
}
void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab // Dedent - suck white space off the front of the line to dedent by equivalent of a tab
for (int line = lineBottom; line >= lineTop; line--) { for (int line = lineBottom; line >= lineTop; line--) {
int ispc = 0; int indentOfLine = GetLineIndentation(line);
while (ispc < tabInChars && cb.CharAt(LineStart(line) + ispc) == ' ') if (forwards)
ispc++; SetLineIndentation(line, indentOfLine + IndentSize());
int posStartLine = LineStart(line); else
if (ispc == tabInChars) { SetLineIndentation(line, indentOfLine - IndentSize());
DeleteChars(posStartLine, ispc);
} else if (cb.CharAt(posStartLine + ispc) == '\t') {
DeleteChars(posStartLine, ispc + 1);
} else { // Hit a non-white
DeleteChars(posStartLine, ispc);
}
}
} }
} }
@@ -522,6 +650,8 @@ void Document::ConvertLineEnds(int eolModeSet) {
} }
bool Document::IsWordChar(unsigned char ch) { bool Document::IsWordChar(unsigned char ch) {
if ((SC_CP_UTF8 == dbcsCodePage) && (ch >0x80))
return true;
return wordchars[ch]; return wordchars[ch];
} }
@@ -588,16 +718,14 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv
// Compute actual search ranges needed // Compute actual search ranges needed
int lengthFind = strlen(s); int lengthFind = strlen(s);
int endSearch = 0; int endSearch = endPos;
if (startPos <= endPos) { if (startPos <= endPos) {
endSearch = endPos - lengthFind + 1; endSearch = endPos - lengthFind + 1;
} else {
endSearch = endPos;
} }
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind); //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
char firstChar = s[0]; char firstChar = s[0];
if (!caseSensitive) if (!caseSensitive)
firstChar = toupper(firstChar); firstChar = static_cast<char>(toupper(firstChar));
int pos = startPos; int pos = startPos;
while (forward ? (pos < endSearch) : (pos >= endSearch)) { while (forward ? (pos < endSearch) : (pos >= endSearch)) {
char ch = CharAt(pos); char ch = CharAt(pos);
@@ -646,15 +774,15 @@ void Document::ChangeCase(Range r, bool makeUpperCase) {
for (int pos=r.start; pos<r.end; pos++) { for (int pos=r.start; pos<r.end; pos++) {
char ch = CharAt(pos); char ch = CharAt(pos);
if (dbcsCodePage && IsDBCS(pos)) { if (dbcsCodePage && IsDBCS(pos)) {
pos++; pos += LenChar(pos);
} else { } else {
if (makeUpperCase) { if (makeUpperCase) {
if (islower(ch)) { if (islower(ch)) {
ChangeChar(pos, toupper(ch)); ChangeChar(pos, static_cast<char>(toupper(ch)));
} }
} else { } else {
if (isupper(ch)) { if (isupper(ch)) {
ChangeChar(pos, tolower(ch)); ChangeChar(pos, static_cast<char>(tolower(ch)));
} }
} }
} }
@@ -795,5 +923,3 @@ void Document::NotifyModified(DocModification mh) {
watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData); watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData);
} }
} }

View File

@@ -74,9 +74,10 @@ private:
CellBuffer cb; CellBuffer cb;
bool wordchars[256]; bool wordchars[256];
int stylingPos; int stylingPos;
int stylingMask; char stylingMask;
int endStyled; int endStyled;
int enteredCount; int enteredCount;
int enteredReadOnlyCount;
WatcherWithUserData *watchers; WatcherWithUserData *watchers;
int lenWatchers; int lenWatchers;
@@ -86,8 +87,11 @@ public:
int stylingBitsMask; int stylingBitsMask;
int eolMode; int eolMode;
// dbcsCodePage can also be SC_CP_UTF8 to enable UTF-8 mode
int dbcsCodePage; int dbcsCodePage;
int tabInChars; int tabInChars;
int indentInChars;
bool useTabs;
Document(); Document();
virtual ~Document(); virtual ~Document();
@@ -98,6 +102,7 @@ public:
int LineFromPosition(int pos); int LineFromPosition(int pos);
int ClampPositionIntoDocument(int pos); int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos); bool IsCrLf(int pos);
int LenChar(int pos);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document // Gateways to modifying document
@@ -115,6 +120,10 @@ public:
void EndUndoAction() { cb.EndUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); }
void SetSavePoint(); void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); } bool IsSavePoint() { return cb.IsSavePoint(); }
int GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line);
void Indent(bool forwards, int lineBottom, int lineTop); void Indent(bool forwards, int lineBottom, int lineTop);
void ConvertLineEnds(int eolModeSet); void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); } void SetReadOnly(bool set) { cb.SetReadOnly(set); }
@@ -183,6 +192,8 @@ private:
void NotifyModifyAttempt(); void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint); void NotifySavePoint(bool atSavePoint);
void NotifyModified(DocModification mh); void NotifyModified(DocModification mh);
int IndentSize() { return indentInChars ? indentInChars : tabInChars; }
}; };
// To optimise processing of document modifications by DocWatchers, a hint is passed indicating the // To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
@@ -209,6 +220,16 @@ public:
line(0), line(0),
foldLevelNow(0), foldLevelNow(0),
foldLevelPrev(0) {} foldLevelPrev(0) {}
DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
position(act.position / 2),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),
line(0),
foldLevelNow(0),
foldLevelPrev(0) {}
}; };
// A class that wants to receive notifications from a Document must be derived from DocWatcher // A class that wants to receive notifications from a Document must be derived from DocWatcher

View File

@@ -0,0 +1,174 @@
// SciTE - Scintilla based Text Editor
// Accessor.cxx - rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "SVector.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "CellBuffer.h"
#include "Scintilla.h"
#include "Document.h"
DocumentAccessor::~DocumentAccessor() {
}
bool DocumentAccessor::InternalIsLeadByte(char ch) {
#if PLAT_GTK
// TODO: support DBCS under GTK+
return false;
#elif PLAT_WIN
if (SC_CP_UTF8 == codePage)
// For lexing, all characters >= 0x80 are treated the
// same so none is considered a lead byte.
return false;
else
return IsDBCSLeadByteEx(codePage, ch);
#elif PLAT_WX
return false;
#endif
}
void DocumentAccessor::Fill(int position) {
if (lenDoc == -1)
lenDoc = pdoc->Length();
startPos = position - slopSize;
if (startPos + bufferSize > lenDoc)
startPos = lenDoc - bufferSize;
if (startPos < 0)
startPos = 0;
endPos = startPos + bufferSize;
if (endPos > lenDoc)
endPos = lenDoc;
pdoc->GetCharRange(buf, startPos, endPos-startPos);
buf[endPos-startPos] = '\0';
}
char DocumentAccessor::StyleAt(int position) {
return pdoc->StyleAt(position);
}
int DocumentAccessor::GetLine(int position) {
return pdoc->LineFromPosition(position);
}
int DocumentAccessor::LineStart(int line) {
return pdoc->LineStart(line);
}
int DocumentAccessor::LevelAt(int line) {
return pdoc->GetLevel(line);
}
int DocumentAccessor::Length() {
if (lenDoc == -1)
lenDoc = pdoc->Length();
return lenDoc;
}
int DocumentAccessor::GetLineState(int line) {
return pdoc->GetLineState(line);
}
int DocumentAccessor::SetLineState(int line, int state) {
return pdoc->SetLineState(line, state);
}
void DocumentAccessor::StartAt(unsigned int start, char chMask) {
pdoc->StartStyling(start, chMask);
}
void DocumentAccessor::StartSegment(unsigned int pos) {
startSeg = pos;
}
void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range
if (pos != startSeg - 1) {
if (pos < startSeg) {
Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos);
}
if (validLen + (pos - startSeg + 1) >= bufferSize)
Flush();
if (validLen + (pos - startSeg + 1) >= bufferSize) {
// Too big for buffer so send directly
pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
} else {
if (chAttr != chWhile)
chFlags = 0;
chAttr |= chFlags;
for (unsigned int i = startSeg; i <= pos; i++) {
styleBuf[validLen++] = static_cast<char>(chAttr);
}
}
}
startSeg = pos+1;
}
void DocumentAccessor::SetLevel(int line, int level) {
pdoc->SetLevel(line, level);
}
void DocumentAccessor::Flush() {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) {
pdoc->SetStyles(validLen, styleBuf);
validLen = 0;
}
}
int DocumentAccessor::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
// indentation compared to the previous line.
// 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;
bool inPrevPrefix = line > 0;
int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
while ((ch == ' ' || ch == '\t') && (pos < end)) {
if (inPrevPrefix) {
char chPrev = (*this)[posPrev++];
if (chPrev == ' ' || chPrev == '\t') {
if (chPrev != ch)
spaceFlags |= wsInconsistent;
} else {
inPrevPrefix = false;
}
}
if (ch == ' ') {
spaceFlags |= wsSpace;
indent++;
} else { // Tab
spaceFlags |= wsTab;
if (spaceFlags & wsSpace)
spaceFlags |= wsSpaceTab;
indent = (indent / 8 + 1) * 8;
}
ch = (*this)[++pos];
}
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
return indent | SC_FOLDLEVELWHITEFLAG;
else
return indent;
}

View File

@@ -0,0 +1,49 @@
// DocumentAccessor.h - implementation of BufferAccess and StylingAccess on a Scintilla rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
class Document;
class DocumentAccessor : public Accessor {
// Private so DocumentAccessor objects can not be copied
DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
DocumentAccessor &operator=(const DocumentAccessor &) { return *this; }
protected:
Document *pdoc;
PropSet &props;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
DocumentAccessor(Document *pdoc_, PropSet &props_) :
Accessor(), pdoc(pdoc_), props(props_),
lenDoc(-1), validLen(0), chFlags(0) {
}
~DocumentAccessor();
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
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);
}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
};

View File

@@ -69,6 +69,7 @@ Editor::Editor() {
xOffset = 0; xOffset = 0;
xCaretMargin = 50; xCaretMargin = 50;
horizontalScrollBarVisible = true;
currentPos = 0; currentPos = 0;
anchor = 0; anchor = 0;
@@ -189,7 +190,7 @@ bool IsControlCharacter(char ch) {
return ch >= 0 && ch < ' '; return ch >= 0 && ch < ' ';
} }
const char *ControlCharacterString(char ch) { const char *ControlCharacterString(unsigned char ch) {
const char *reps[] = { const char *reps[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
@@ -210,6 +211,7 @@ Point Editor::LocationFromPosition(unsigned int pos) {
//Platform::DebugPrintf("line=%d\n", line); //Platform::DebugPrintf("line=%d\n", line);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
Point pt; Point pt;
pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight?
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
@@ -252,6 +254,7 @@ int Editor::PositionFromLocation(Point pt) {
//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
LineLayout ll; LineLayout ll;
@@ -273,6 +276,7 @@ int Editor::PositionFromLineX(int line, int x) {
//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
LineLayout ll; LineLayout ll;
@@ -485,7 +489,7 @@ void Editor::ScrollTo(int line) {
} }
} }
void Editor::ScrollText(int linesToMove) { void Editor::ScrollText(int /* linesToMove */) {
//Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove); //Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove);
Redraw(); Redraw();
} }
@@ -499,6 +503,19 @@ void Editor::HorizontalScrollTo(int xPos) {
Redraw(); Redraw();
} }
void Editor::MoveCaretInsideView() {
PRectangle rcClient = GetTextRectangle();
Point pt = LocationFromPosition(currentPos);
if (pt.y < rcClient.top) {
MovePositionTo(PositionFromLocation(
Point(lastXChosen, rcClient.top)));
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen()-1) * vs.lineHeight;
MovePositionTo(PositionFromLocation(
Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)));
}
}
void Editor::EnsureCaretVisible(bool useMargin) { void Editor::EnsureCaretVisible(bool useMargin) {
//Platform::DebugPrintf("EnsureCaretVisible %d\n", xOffset); //Platform::DebugPrintf("EnsureCaretVisible %d\n", xOffset);
PRectangle rcClient = GetTextRectangle(); PRectangle rcClient = GetTextRectangle();
@@ -652,11 +669,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
sprintf(number, "%d", line + 1); sprintf(number, "%d", line + 1);
if (foldFlags & 64) if (foldFlags & 64)
sprintf(number, "%X", pdoc->GetLevel(line)); sprintf(number, "%X", pdoc->GetLevel(line));
int xpos = 0;
PRectangle rcNumber=rcMarker; PRectangle rcNumber=rcMarker;
// Right justify // Right justify
int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number)); int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number));
xpos = rcNumber.right - width - 3; int xpos = rcNumber.right - width - 3;
rcNumber.left = xpos; rcNumber.left = xpos;
if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) { if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) {
surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font, surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font,
@@ -720,8 +736,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
styleByte = pdoc->StyleAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc);
if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
ll.chars[numCharsInLine] = chDoc; ll.chars[numCharsInLine] = chDoc;
ll.styles[numCharsInLine] = styleByte & styleMask; ll.styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
ll.indicators[numCharsInLine] = styleByte & ~styleMask; ll.indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
numCharsInLine++; numCharsInLine++;
} }
} }
@@ -1017,14 +1033,13 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
} }
//Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset);
Surface *surface = 0;
if (rcArea.right > vs.fixedColumnWidth) { if (rcArea.right > vs.fixedColumnWidth) {
Surface *surface = surfaceWindow;
if (bufferedDraw) { if (bufferedDraw) {
surface = &pixmapLine; surface = &pixmapLine;
} else {
surface = surfaceWindow;
} }
surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
int visibleLine = topLine + screenLinePaintFirst; int visibleLine = topLine + screenLinePaintFirst;
int line = cs.DocFromDisplay(visibleLine); int line = cs.DocFromDisplay(visibleLine);
@@ -1060,9 +1075,11 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// Highlight the current braces if any // Highlight the current braces if any
if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd))
ll.styles[braces[0] - posLineStart] = bracesMatchStyle; ll.styles[braces[0] - posLineStart] =
static_cast<char>(bracesMatchStyle);
if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd))
ll.styles[braces[1] - posLineStart] = bracesMatchStyle; ll.styles[braces[1] - posLineStart] =
static_cast<char>(bracesMatchStyle);
// Draw the line // Draw the line
if (cs.GetVisible(line)) if (cs.GetVisible(line))
@@ -1086,9 +1103,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// Draw the Caret // Draw the Caret
if (line == lineCaret) { if (line == lineCaret) {
int xposCaret = ll.positions[posCaret - posLineStart] + xStart; int offset = Platform::Minimum(posCaret - posLineStart, LineLayout::maxLineLength);
int xposCaret = ll.positions[offset] + xStart;
int widthOverstrikeCaret = int widthOverstrikeCaret =
ll.positions[posCaret - posLineStart + 1] - ll.positions[posCaret - posLineStart]; ll.positions[offset + 1] - ll.positions[offset];
if (posCaret == pdoc->Length()) // At end of document if (posCaret == pdoc->Length()) // At end of document
widthOverstrikeCaret = vs.aveCharWidth; widthOverstrikeCaret = vs.aveCharWidth;
if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line
@@ -1163,8 +1181,10 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) {
Surface *surface = new Surface(); Surface *surface = new Surface();
surface->Init(pfr->hdc); surface->Init(pfr->hdc);
surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
Surface *surfaceMeasure = new Surface(); Surface *surfaceMeasure = new Surface();
surfaceMeasure->Init(pfr->hdcTarget); surfaceMeasure->Init(pfr->hdcTarget);
surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
ViewStyle vsPrint(vs); ViewStyle vsPrint(vs);
@@ -1270,6 +1290,10 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) {
return endPosPrint; return endPosPrint;
} }
// Empty method is overridden on GTK+ to show / hide scrollbars
void Editor::ReconfigureScrollBars() {
}
void Editor::SetScrollBarsTo(PRectangle) { void Editor::SetScrollBarsTo(PRectangle) {
RefreshStyleData(); RefreshStyleData();
@@ -1295,6 +1319,13 @@ void Editor::SetScrollBars() {
} }
void Editor::AddChar(char ch) { void Editor::AddChar(char ch) {
char s[2];
s[0] = ch;
s[1] = '\0';
AddCharUTF(s, 1);
}
void Editor::AddCharUTF(char *s, unsigned int len) {
bool wasSelection = currentPos != anchor; bool wasSelection = currentPos != anchor;
ClearSelection(); ClearSelection();
if (inOverstrike && !wasSelection) { if (inOverstrike && !wasSelection) {
@@ -1304,11 +1335,11 @@ void Editor::AddChar(char ch) {
} }
} }
} }
pdoc->InsertChar(currentPos, ch); pdoc->InsertString(currentPos, s, len);
SetEmptySelection(currentPos + 1); SetEmptySelection(currentPos + len);
EnsureCaretVisible(); EnsureCaretVisible();
SetLastXChosen(); SetLastXChosen();
NotifyChar(ch); NotifyChar(s[0]);
} }
void Editor::ClearSelection() { void Editor::ClearSelection() {
@@ -1429,7 +1460,7 @@ void Editor::DelCharBack() {
void Editor::NotifyFocus(bool) { void Editor::NotifyFocus(bool) {
} }
void Editor::NotifyStyleNeeded(int endStyleNeeded) { void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
SCNotification scn; SCNotification scn;
scn.nmhdr.code = SCN_STYLENEEDED; scn.nmhdr.code = SCN_STYLENEEDED;
scn.position = endStyleNeeded; scn.position = endStyleNeeded;
@@ -1437,7 +1468,7 @@ void Editor::NotifyStyleNeeded(int endStyleNeeded) {
} }
void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) { void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) {
NotifyStyleNeeded(endStyleNeeded); NotifyStyleToNeeded(endStyleNeeded);
} }
void Editor::NotifyChar(char ch) { void Editor::NotifyChar(char ch) {
@@ -1581,6 +1612,11 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
braces[1] = endPos; braces[1] = endPos;
} }
} }
}
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
} }
if (mh.linesAdded != 0) { if (mh.linesAdded != 0) {
@@ -1588,7 +1624,6 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
// lineOfPos should be calculated in context of state before modification, shouldn't it // lineOfPos should be calculated in context of state before modification, shouldn't it
int lineOfPos = pdoc->LineFromPosition(mh.position); int lineOfPos = pdoc->LineFromPosition(mh.position);
if (mh.linesAdded > 0) { if (mh.linesAdded > 0) {
NotifyNeedShown(mh.position, mh.length);
cs.InsertLines(lineOfPos, mh.linesAdded); cs.InsertLines(lineOfPos, mh.linesAdded);
} else { } else {
cs.DeleteLines(lineOfPos, -mh.linesAdded); cs.DeleteLines(lineOfPos, -mh.linesAdded);
@@ -1642,7 +1677,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
} }
} }
void Editor::NotifyDeleted(Document *document, void *userData) { void Editor::NotifyDeleted(Document *, void *) {
/* Do nothing */ /* Do nothing */
} }
@@ -1806,6 +1841,10 @@ int Editor::KeyCommand(UINT iMessage) {
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y + vs.lineHeight)), true); Point(lastXChosen, pt.y + vs.lineHeight)), true);
break; break;
case SCI_LINESCROLLDOWN:
ScrollTo(topLine + 1);
MoveCaretInsideView();
break;
case SCI_LINEUP: case SCI_LINEUP:
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y - vs.lineHeight))); Point(lastXChosen, pt.y - vs.lineHeight)));
@@ -1814,6 +1853,10 @@ int Editor::KeyCommand(UINT iMessage) {
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y - vs.lineHeight)), true); Point(lastXChosen, pt.y - vs.lineHeight)), true);
break; break;
case SCI_LINESCROLLUP:
ScrollTo(topLine - 1);
MoveCaretInsideView();
break;
case SCI_CHARLEFT: case SCI_CHARLEFT:
if (SelectionEmpty()) { if (SelectionEmpty()) {
MovePositionTo(MovePositionSoVisible(currentPos - 1, -1)); MovePositionTo(MovePositionSoVisible(currentPos - 1, -1));
@@ -1909,6 +1952,7 @@ int Editor::KeyCommand(UINT iMessage) {
break; break;
case SCI_DELETEBACK: case SCI_DELETEBACK:
DelCharBack(); DelCharBack();
SetLastXChosen();
EnsureCaretVisible(); EnsureCaretVisible();
break; break;
case SCI_TAB: case SCI_TAB:
@@ -1961,6 +2005,7 @@ int Editor::KeyCommand(UINT iMessage) {
int startWord = pdoc->NextWordStart(currentPos, -1); int startWord = pdoc->NextWordStart(currentPos, -1);
pdoc->DeleteChars(startWord, currentPos - startWord); pdoc->DeleteChars(startWord, currentPos - startWord);
MovePositionTo(startWord); MovePositionTo(startWord);
SetLastXChosen();
} }
break; break;
case SCI_DELWORDRIGHT: { case SCI_DELWORDRIGHT: {
@@ -2628,12 +2673,13 @@ char BraceOpposite(char ch) {
// TODO: should be able to extend styled region to find matching brace // TODO: should be able to extend styled region to find matching brace
// TODO: may need to make DBCS safe // TODO: may need to make DBCS safe
// so should be moved into Document // so should be moved into Document
int Editor::BraceMatch(int position, int maxReStyle) { int Editor::BraceMatch(int position, int /*maxReStyle*/) {
char chBrace = pdoc->CharAt(position); char chBrace = pdoc->CharAt(position);
char chSeek = BraceOpposite(chBrace); char chSeek = BraceOpposite(chBrace);
if (!chSeek) if (chSeek == '\0')
return - 1; return - 1;
char styBrace = pdoc->StyleAt(position) & pdoc->stylingBitsMask; char styBrace = static_cast<char>(
pdoc->StyleAt(position) & pdoc->stylingBitsMask);
int direction = -1; int direction = -1;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1; direction = 1;
@@ -2641,7 +2687,7 @@ int Editor::BraceMatch(int position, int maxReStyle) {
position = position + direction; position = position + direction;
while ((position >= 0) && (position < pdoc->Length())) { while ((position >= 0) && (position < pdoc->Length())) {
char chAtPos = pdoc->CharAt(position); char chAtPos = pdoc->CharAt(position);
char styAtPos = pdoc->StyleAt(position) & pdoc->stylingBitsMask; char styAtPos = static_cast<char>(pdoc->StyleAt(position) & pdoc->stylingBitsMask);
if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) { if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) {
if (chAtPos == chBrace) if (chAtPos == chBrace)
depth++; depth++;
@@ -2750,6 +2796,11 @@ void Editor::EnsureLineVisible(int line) {
} }
} }
static bool ValidMargin(WPARAM wParam) {
return wParam < ViewStyle::margins;
}
LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
//Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam);
@@ -3313,11 +3364,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break; break;
case SCI_STARTSTYLING: case SCI_STARTSTYLING:
pdoc->StartStyling(wParam, lParam); pdoc->StartStyling(wParam, static_cast<char>(lParam));
break; break;
case SCI_SETSTYLING: case SCI_SETSTYLING:
pdoc->SetStyleFor(wParam, lParam); pdoc->SetStyleFor(wParam, static_cast<char>(lParam));
break; break;
case SCI_SETSTYLINGEX: // Specify a complete styling buffer case SCI_SETSTYLINGEX: // Specify a complete styling buffer
@@ -3345,6 +3396,44 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
InvalidateStyleRedraw(); InvalidateStyleRedraw();
break; break;
case SCI_GETTABWIDTH:
return pdoc->tabInChars;
case SCI_SETINDENT:
pdoc->indentInChars = wParam;
InvalidateStyleRedraw();
break;
case SCI_GETINDENT:
return pdoc->indentInChars;
case SCI_SETUSETABS:
pdoc->useTabs = wParam;
InvalidateStyleRedraw();
break;
case SCI_GETUSETABS:
return pdoc->useTabs;
case SCI_SETLINEINDENTATION:
pdoc->SetLineIndentation(wParam, lParam);
break;
case SCI_GETLINEINDENTATION:
return pdoc->GetLineIndentation(wParam);
case SCI_GETLINEINDENTPOSITION:
return pdoc->GetLineIndentPosition(wParam);
case SCI_SETHSCROLLBAR :
horizontalScrollBarVisible = wParam;
SetScrollBars();
ReconfigureScrollBars();
break;
case SCI_GETHSCROLLBAR:
return horizontalScrollBarVisible;
case SCI_SETCODEPAGE: case SCI_SETCODEPAGE:
pdoc->dbcsCodePage = wParam; pdoc->dbcsCodePage = wParam;
break; break;
@@ -3416,53 +3505,53 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
return -1; return -1;
case SCI_SETMARGINTYPEN: case SCI_SETMARGINTYPEN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL); vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL);
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINTYPEN: case SCI_GETMARGINTYPEN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER; return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER;
else else
return 0; return 0;
case SCI_SETMARGINWIDTHN: case SCI_SETMARGINWIDTHN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].width = lParam; vs.ms[wParam].width = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINWIDTHN: case SCI_GETMARGINWIDTHN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].width; return vs.ms[wParam].width;
else else
return 0; return 0;
case SCI_SETMARGINMASKN: case SCI_SETMARGINMASKN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].mask = lParam; vs.ms[wParam].mask = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINMASKN: case SCI_GETMARGINMASKN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].mask; return vs.ms[wParam].mask;
else else
return 0; return 0;
case SCI_SETMARGINSENSITIVEN: case SCI_SETMARGINSENSITIVEN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].sensitive = lParam; vs.ms[wParam].sensitive = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINSENSITIVEN: case SCI_GETMARGINSENSITIVEN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].sensitive ? 1 : 0; return vs.ms[wParam].sensitive ? 1 : 0;
else else
return 0; return 0;
@@ -3606,7 +3695,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
case SCI_SEARCHNEXT: case SCI_SEARCHNEXT:
case SCI_SEARCHPREV: case SCI_SEARCHPREV:
return SearchText(iMessage, wParam, lParam); return SearchText(iMessage, wParam, lParam);
break;
case SCI_SETCARETPOLICY: case SCI_SETCARETPOLICY:
caretPolicy = wParam; caretPolicy = wParam;
@@ -3745,6 +3833,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
case SCI_LINETRANSPOSE: case SCI_LINETRANSPOSE:
case SCI_LOWERCASE: case SCI_LOWERCASE:
case SCI_UPPERCASE: case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
case SCI_LINESCROLLUP:
return KeyCommand(iMessage); return KeyCommand(iMessage);
case SCI_BRACEHIGHLIGHT: case SCI_BRACEHIGHLIGHT:
@@ -3808,6 +3898,9 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
SetSelection(currentPos, anchor); // Ensure selection inside document SetSelection(currentPos, anchor); // Ensure selection inside document
return 0; return 0;
case SCI_SELECTIONISRECTANGLE:
return (selType == selRectangle) ? 1 : 0;
#ifdef MACRO_SUPPORT #ifdef MACRO_SUPPORT
case SCI_STARTRECORD: case SCI_STARTRECORD:
recordingMacro = 1; recordingMacro = 1;

View File

@@ -38,6 +38,9 @@ public:
}; };
class Editor : public DocWatcher { class Editor : public DocWatcher {
// Private so Editor objects can not be copied
Editor(const Editor &) : DocWatcher() {}
Editor &operator=(const Editor &) { return *this; }
protected: // ScintillaBase subclass needs access to much of Editor protected: // ScintillaBase subclass needs access to much of Editor
// On GTK+, Scintilla is a container widget holding two scroll bars and a drawing area // On GTK+, Scintilla is a container widget holding two scroll bars and a drawing area
@@ -61,13 +64,14 @@ protected: // ScintillaBase subclass needs access to much of Editor
int xOffset; // Horizontal scrolled amount in pixels int xOffset; // Horizontal scrolled amount in pixels
int xCaretMargin; // Ensure this many pixels visible on both sides of caret int xCaretMargin; // Ensure this many pixels visible on both sides of caret
bool horizontalScrollBarVisible;
Surface pixmapLine; Surface pixmapLine;
Surface pixmapSelMargin; Surface pixmapSelMargin;
Surface pixmapSelPattern; Surface pixmapSelPattern;
// Intellimouse support - currently only implemented for Windows // Intellimouse support - currently only implemented for Windows
unsigned int ucWheelScrollLines; unsigned int ucWheelScrollLines;
short cWheelDelta; //wheel delta from roll int cWheelDelta; //wheel delta from roll
KeyMap kmap; KeyMap kmap;
@@ -171,6 +175,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void ScrollTo(int line); void ScrollTo(int line);
virtual void ScrollText(int linesToMove); virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos); void HorizontalScrollTo(int xPos);
void MoveCaretInsideView();
void EnsureCaretVisible(bool useMargin=true); void EnsureCaretVisible(bool useMargin=true);
void ShowCaretAtCurrentPosition(); void ShowCaretAtCurrentPosition();
void DropCaret(); void DropCaret();
@@ -186,10 +191,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void SetVerticalScrollPos() = 0; virtual void SetVerticalScrollPos() = 0;
virtual void SetHorizontalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0;
virtual bool ModifyScrollBars(int nMax, int nPage) = 0; virtual bool ModifyScrollBars(int nMax, int nPage) = 0;
virtual void ReconfigureScrollBars();
void SetScrollBarsTo(PRectangle rsClient); void SetScrollBarsTo(PRectangle rsClient);
void SetScrollBars(); void SetScrollBars();
virtual void AddChar(char ch); void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len);
void ClearSelection(); void ClearSelection();
void ClearAll(); void ClearAll();
void Cut(); void Cut();
@@ -207,7 +214,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0; virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleNeeded(int endStyleNeeded); virtual void NotifyStyleToNeeded(int endStyleNeeded);
void NotifyChar(char ch); void NotifyChar(char ch);
void NotifySavePoint(bool isSavePoint); void NotifySavePoint(bool isSavePoint);
void NotifyModifyAttempt(); void NotifyModifyAttempt();

View File

@@ -61,56 +61,58 @@ UINT KeyMap::Find(int key, int modifiers) {
} }
KeyToCommand KeyMap::MapDefault[] = { KeyToCommand KeyMap::MapDefault[] = {
VK_DOWN, SCI_NORM, SCI_LINEDOWN, {VK_DOWN, SCI_NORM, SCI_LINEDOWN},
VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, {VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
VK_UP, SCI_NORM, SCI_LINEUP, {VK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, {VK_UP, SCI_NORM, SCI_LINEUP},
VK_LEFT, SCI_NORM, SCI_CHARLEFT, {VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND, {VK_UP, SCI_CTRL, SCI_LINESCROLLUP},
VK_LEFT, SCI_CTRL, SCI_WORDLEFT, {VK_LEFT, SCI_NORM, SCI_CHARLEFT},
VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND, {VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, {VK_LEFT, SCI_CTRL, SCI_WORDLEFT},
VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, {VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, {VK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, {VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
VK_HOME, SCI_NORM, SCI_VCHOME, {VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, {VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, {VK_HOME, SCI_NORM, SCI_VCHOME},
VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, {VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND},
VK_END, SCI_NORM, SCI_LINEEND, {VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
VK_END, SCI_SHIFT, SCI_LINEENDEXTEND, {VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
VK_END, SCI_CTRL, SCI_DOCUMENTEND, {VK_END, SCI_NORM, SCI_LINEEND},
VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND, {VK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
VK_PRIOR, SCI_NORM, SCI_PAGEUP, {VK_END, SCI_CTRL, SCI_DOCUMENTEND},
VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, {VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
VK_NEXT, SCI_NORM, SCI_PAGEDOWN, {VK_PRIOR, SCI_NORM, SCI_PAGEUP},
VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, {VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
VK_DELETE, SCI_NORM, WM_CLEAR, {VK_NEXT, SCI_NORM, SCI_PAGEDOWN},
VK_DELETE, SCI_SHIFT, WM_CUT, {VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND},
VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT, {VK_DELETE, SCI_NORM, WM_CLEAR},
VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, {VK_DELETE, SCI_SHIFT, WM_CUT},
VK_INSERT, SCI_SHIFT, WM_PASTE, {VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT},
VK_INSERT, SCI_CTRL, WM_COPY, {VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE},
VK_ESCAPE, SCI_NORM, SCI_CANCEL, {VK_INSERT, SCI_SHIFT, WM_PASTE},
VK_BACK, SCI_NORM, SCI_DELETEBACK, {VK_INSERT, SCI_CTRL, WM_COPY},
VK_BACK, SCI_CTRL, SCI_DELWORDLEFT, {VK_ESCAPE, SCI_NORM, SCI_CANCEL},
'Z', SCI_CTRL, WM_UNDO, {VK_BACK, SCI_NORM, SCI_DELETEBACK},
'Y', SCI_CTRL, SCI_REDO, {VK_BACK, SCI_CTRL, SCI_DELWORDLEFT},
'X', SCI_CTRL, WM_CUT, {'Z', SCI_CTRL, WM_UNDO},
'C', SCI_CTRL, WM_COPY, {'Y', SCI_CTRL, SCI_REDO},
'V', SCI_CTRL, WM_PASTE, {'X', SCI_CTRL, WM_CUT},
'A', SCI_CTRL, SCI_SELECTALL, {'C', SCI_CTRL, WM_COPY},
VK_TAB, SCI_NORM, SCI_TAB, {'V', SCI_CTRL, WM_PASTE},
VK_TAB, SCI_SHIFT, SCI_BACKTAB, {'A', SCI_CTRL, SCI_SELECTALL},
VK_RETURN, SCI_NORM, SCI_NEWLINE, {VK_TAB, SCI_NORM, SCI_TAB},
VK_ADD, SCI_CTRL, SCI_ZOOMIN, {VK_TAB, SCI_SHIFT, SCI_BACKTAB},
VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT, {VK_RETURN, SCI_NORM, SCI_NEWLINE},
{VK_ADD, SCI_CTRL, SCI_ZOOMIN},
{VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
//'L', SCI_CTRL, SCI_FORMFEED, //'L', SCI_CTRL, SCI_FORMFEED,
'L', SCI_CTRL, SCI_LINECUT, {'L', SCI_CTRL, SCI_LINECUT},
'L', SCI_CSHIFT, SCI_LINEDELETE, {'L', SCI_CSHIFT, SCI_LINEDELETE},
'T', SCI_CTRL, SCI_LINETRANSPOSE, {'T', SCI_CTRL, SCI_LINETRANSPOSE},
'U', SCI_CTRL, SCI_LOWERCASE, {'U', SCI_CTRL, SCI_LOWERCASE},
'U', SCI_CSHIFT, SCI_UPPERCASE, {'U', SCI_CSHIFT, SCI_UPPERCASE},
0,0,0, {0,0,0},
}; };

View File

@@ -26,7 +26,7 @@ LexerModule::LexerModule(int language_, LexerFunction fn_) :
} }
void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle, void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle,
int language, WordList *keywordlists[], StylingContext &styler) { int language, WordList *keywordlists[], Accessor &styler) {
LexerModule *lm = base; LexerModule *lm = base;
while (lm) { while (lm) {
if (lm->language == language) { if (lm->language == language) {
@@ -43,5 +43,3 @@ void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle,
styler.ColourTo(startPos + lengthDoc - 1, 0); styler.ColourTo(startPos + lengthDoc - 1, 0);
} }
} }

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
bool wordIsUUID = false; bool wordIsUUID = false;
@@ -39,29 +39,37 @@ static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keyw
} }
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
StylingContext &styler) { Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
styler.StartAt(startPos); styler.StartAt(startPos);
bool fold = styler.GetPropSet().GetInt("fold"); bool fold = styler.GetPropertyInt("fold");
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev; int levelCurrent = levelPrev;
int state = initStyle; int state = initStyle;
if (state == SCE_C_STRINGEOL) // Does not leak onto next line
state = SCE_C_DEFAULT;
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length; unsigned int lengthDoc = startPos + length;
int visChars = 0; int visChars = 0;
styler.StartSegment(startPos); styler.StartSegment(startPos);
bool lastWordWasUUID = false; bool lastWordWasUUID = false;
for (unsigned int i = startPos; i <= lengthDoc; i++) { for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
// End of line
if (state == SCE_C_STRINGEOL) {
styler.ColourTo(i, state);
state = SCE_C_DEFAULT;
}
if (fold) {
int lev = levelPrev; int lev = levelPrev;
if (visChars == 0) if (visChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
@@ -72,6 +80,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
visChars = 0; visChars = 0;
levelPrev = levelCurrent; levelPrev = levelCurrent;
} }
}
if (!isspace(ch)) if (!isspace(ch))
visChars++; visChars++;
@@ -82,12 +91,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
continue; continue;
} }
if (state == SCE_C_STRINGEOL) {
if (ch != '\r' && ch != '\n') {
styler.ColourTo(i-1, state);
state = SCE_C_DEFAULT;
}
}
if (state == SCE_C_DEFAULT) { if (state == SCE_C_DEFAULT) {
if (iswordstart(ch)) { if (iswordstart(ch)) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, state);
@@ -148,7 +151,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else { } else {
if (state == SCE_C_PREPROCESSOR) { if (state == SCE_C_PREPROCESSOR) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, state);
state = SCE_C_DEFAULT; state = SCE_C_DEFAULT;
} }
@@ -163,7 +166,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_COMMENTDOC) { } else if (state == SCE_C_COMMENTDOC) {
if (ch == '/' && chPrev == '*') { if (ch == '/' && chPrev == '*') {
if (((i > styler.GetStartSegment() + 3) || ( if (((i > styler.GetStartSegment() + 2) || (
(initStyle == SCE_C_COMMENTDOC) && (initStyle == SCE_C_COMMENTDOC) &&
(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
styler.ColourTo(i, state); styler.ColourTo(i, state);
@@ -177,7 +180,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_STRING) { } else if (state == SCE_C_STRING) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL; state = SCE_C_STRINGEOL;
} else if (ch == '\\') { } else if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
@@ -194,7 +197,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_CHARACTER) { } else if (state == SCE_C_CHARACTER) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL; state = SCE_C_STRINGEOL;
} else if (ch == '\\') { } else if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') {

View File

@@ -18,11 +18,11 @@
#include "SciLexer.h" #include "SciLexer.h"
enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython };
static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, int prevValue) {
char s[100]; char s[100];
s[0] = '\0'; s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
//Platform::DebugPrintf("Scripting indicator [%s]\n", s); //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
@@ -38,7 +38,7 @@ static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, u
return prevValue; return prevValue;
} }
static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') ||
(styler[start] == '-') || (styler[start] == '#'); (styler[start] == '-') || (styler[start] == '#');
char chAttr = SCE_H_ATTRIBUTEUNKNOWN; char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
@@ -48,7 +48,7 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
char s[100]; char s[100];
s[0] = '\0'; s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
if (keywords.InList(s)) if (keywords.InList(s))
@@ -58,14 +58,14 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
} }
static int classifyTagHTML(unsigned int start, unsigned int end, static int classifyTagHTML(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
// Copy after the '<' // Copy after the '<'
unsigned int i = 0; unsigned int i = 0;
for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) {
char ch = styler[cPos]; char ch = styler[cPos];
if (ch != '<') if (ch != '<')
s[i++] = tolower(ch); s[i++] = static_cast<char>(tolower(ch));
} }
s[i] = '\0'; s[i] = '\0';
char chAttr = SCE_H_TAGUNKNOWN; char chAttr = SCE_H_TAGUNKNOWN;
@@ -86,7 +86,7 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
} }
static void classifyWordHTJS(unsigned int start, unsigned int end, static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -104,7 +104,7 @@ static void classifyWordHTJS(unsigned int start, unsigned int end,
} }
static void classifyWordHTJSA(unsigned int start, unsigned int end, static void classifyWordHTJSA(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -121,11 +121,11 @@ static void classifyWordHTJSA(unsigned int start, unsigned int end,
styler.ColourTo(end, chAttr); styler.ColourTo(end, chAttr);
} }
static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_HB_IDENTIFIER; char chAttr = SCE_HB_IDENTIFIER;
@@ -145,11 +145,11 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT; return SCE_HB_DEFAULT;
} }
static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_HBA_IDENTIFIER; char chAttr = SCE_HBA_IDENTIFIER;
@@ -169,7 +169,7 @@ static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &key
return SCE_HBA_DEFAULT; return SCE_HBA_DEFAULT;
} }
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -189,7 +189,7 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
strcpy(prevWord, s); strcpy(prevWord, s);
} }
static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -226,7 +226,7 @@ static bool isLineEnd(char ch) {
} }
static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
StylingContext &styler) { Accessor &styler) {
WordList &keywords=*keywordlists[0]; WordList &keywords=*keywordlists[0];
WordList &keywords2=*keywordlists[1]; WordList &keywords2=*keywordlists[1];
@@ -261,7 +261,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
char chPrev2 = ' '; char chPrev2 = ' ';
styler.StartSegment(startPos); styler.StartSegment(startPos);
int lengthDoc = startPos + length; int lengthDoc = startPos + length;
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
char ch = styler[i]; char ch = styler[i];
char chNext = styler.SafeGetCharAt(i + 1); char chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &styler) { static void ColouriseBatchLine(char *lineBuffer, int endLine, Accessor &styler) {
if (0 == strncmp(lineBuffer, "REM", 3)) { if (0 == strncmp(lineBuffer, "REM", 3)) {
styler.ColourTo(endLine, 1); styler.ColourTo(endLine, 1);
} else if (0 == strncmp(lineBuffer, "rem", 3)) { } else if (0 == strncmp(lineBuffer, "rem", 3)) {
@@ -33,7 +33,7 @@ static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &st
} }
} }
static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -49,7 +49,7 @@ static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *
ColouriseBatchLine(lineBuffer, startPos + length, styler); ColouriseBatchLine(lineBuffer, startPos + length, styler);
} }
static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, StylingContext &styler) { static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, Accessor &styler) {
int i = 0; int i = 0;
while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces
i++; i++;
@@ -75,7 +75,7 @@ static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine,
} }
} }
static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -96,7 +96,7 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler); ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler);
} }
static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) {
int i = 0; int i = 0;
while (isspace(lineBuffer[i]) && (i < lengthLine)) while (isspace(lineBuffer[i]) && (i < lengthLine))
i++; i++;
@@ -107,7 +107,7 @@ static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, Styl
} }
} }
static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -123,7 +123,7 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler); ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler);
} }
static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) {
if (lineBuffer[0] == '>') { if (lineBuffer[0] == '>') {
// Command or return status // Command or return status
styler.ColourTo(endPos, 4); styler.ColourTo(endPos, 4);
@@ -158,7 +158,6 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
state = 14; state = 14;
} else if (state == 11 && lineBuffer[i] == ')') { } else if (state == 11 && lineBuffer[i] == ')') {
state = 12; state = 12;
break;
} else if (state == 12 && lineBuffer[i] == ':') { } else if (state == 12 && lineBuffer[i] == ':') {
state = 13; state = 13;
} else if (state == 14 && lineBuffer[i] == ')') { } else if (state == 14 && lineBuffer[i] == ')') {
@@ -170,7 +169,7 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
} }
if (state == 3) { if (state == 3) {
styler.ColourTo(endPos, 2); styler.ColourTo(endPos, 2);
} else if ((state == 14) || (state == 15)) { } else if ((state == 13) || (state == 14) || (state == 15)) {
styler.ColourTo(endPos, 3); styler.ColourTo(endPos, 3);
} else { } else {
styler.ColourTo(endPos, 0); styler.ColourTo(endPos, 0);
@@ -178,7 +177,7 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
} }
} }
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);

View File

@@ -31,7 +31,7 @@ inline bool isPerlOperator(char ch) {
return false; return false;
} }
static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -54,7 +54,7 @@ static bool isEndVar(char ch) {
ch != '_' && ch != '\''; ch != '_' && ch != '\'';
} }
static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) { if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
return false; return false;
} }
@@ -67,16 +67,6 @@ static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *
return true; return true;
} }
static bool isOKQuote(char ch) {
if (isalnum(ch))
return false;
if (isspace(ch))
return false;
if (iscntrl(ch))
return false;
return true;
}
static char opposite(char ch) { static char opposite(char ch) {
if (ch == '(') if (ch == '(')
return ')'; return ')';
@@ -90,7 +80,7 @@ static char opposite(char ch) {
} }
static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
// Lexer for perl often has to backtrack to start of current style to determine // Lexer for perl often has to backtrack to start of current style to determine
// which characters are being used as quotes, how deeply nested is the // which characters are being used as quotes, how deeply nested is the
@@ -120,7 +110,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void ClassifyWordPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -37,56 +37,70 @@ static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywo
strcpy(prevWord, s); strcpy(prevWord, s);
} }
static bool IsPyComment(StylingContext &styler, int pos, int len) { static bool IsPyComment(Accessor &styler, int pos, int len) {
return len>0 && styler[pos]=='#'; return len>0 && styler[pos]=='#';
} }
static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
int lengthDoc = startPos + length;
// Backtrack to previous line in case need to fix its fold status or tab whinging
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
// Python uses a different mask because bad indentation is marked by oring with 32 // Python uses a different mask because bad indentation is marked by oring with 32
styler.StartAt(startPos, 127); styler.StartAt(startPos, 127);
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
//Platform::DebugPrintf("Python coloured\n"); bool fold = styler.GetPropertyInt("fold");
bool fold = styler.GetPropSet().GetInt("fold"); int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level");
char prevWord[200]; char prevWord[200];
prevWord[0] = '\0'; prevWord[0] = '\0';
if (length == 0) if (length == 0)
return ; return ;
int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0; int spaceFlags = 0;
// TODO: Need to check previous line for indentation for both folding and bad indentation
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
int state = initStyle & 31; int state = initStyle & 31;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
indentCurrent |= SC_FOLDLEVELWHITEFLAG;
char chPrev = ' '; char chPrev = ' ';
char chPrev2 = ' '; char chPrev2 = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
char chNext2 = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
int lengthDoc = startPos + length;
bool atStartLine = true; bool atStartLine = true;
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
if (atStartLine) { if (atStartLine) {
char chBad = static_cast<char>(64);
char chGood = static_cast<char>(0);
char chFlags = chGood;
if (whingeLevel == 1) { if (whingeLevel == 1) {
styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
} else if (whingeLevel == 2) { } else if (whingeLevel == 2) {
styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
} else if (whingeLevel == 3) { } else if (whingeLevel == 3) {
styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
} else if (whingeLevel == 4) { } else if (whingeLevel == 4) {
styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); chFlags = (spaceFlags & wsTab) ? chBad : chGood;
} }
styler.SetFlags(chFlags, static_cast<char>(state));
atStartLine = false; atStartLine = false;
} }
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
@@ -97,6 +111,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
int lev = indentCurrent; int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment); int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment);
if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
indentNext |= SC_FOLDLEVELWHITEFLAG;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers // Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
@@ -167,7 +183,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
} }
} else if (state == SCE_P_WORD) { } else if (state == SCE_P_WORD) {
if (!iswordchar(ch)) { if (!iswordchar(ch)) {
classifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); ClassifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
state = SCE_P_DEFAULT; state = SCE_P_DEFAULT;
if (ch == '#') { if (ch == '#') {
state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
@@ -245,7 +261,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
chPrev = ch; chPrev = ch;
} }
if (state == SCE_P_WORD) { if (state == SCE_P_WORD) {
classifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord); ClassifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord);
} else { } else {
styler.ColourTo(lengthDoc, state); styler.ColourTo(lengthDoc, state);
} }

View File

@@ -17,11 +17,11 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = toupper(styler[start + i]); s[i] = static_cast<char>(toupper(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_C_IDENTIFIER; char chAttr = SCE_C_IDENTIFIER;
@@ -35,29 +35,27 @@ static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keyw
} }
static void ColouriseSQLDoc(unsigned int startPos, int length, static void ColouriseSQLDoc(unsigned int startPos, int length,
int initStyle, WordList *keywordlists[], StylingContext &styler) { int initStyle, WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
styler.StartAt(startPos); styler.StartAt(startPos);
bool fold = styler.GetPropSet().GetInt("fold"); bool fold = styler.GetPropertyInt("fold");
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0; int spaceFlags = 0;
int indentCurrent = 0;
int state = initStyle; int state = initStyle;
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
unsigned int lengthDoc = startPos + length; unsigned int lengthDoc = startPos + length;
bool prevCr = false; for (unsigned int i = startPos; i < lengthDoc; i++) {
for (unsigned int i = startPos; i <= lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
int lev = indentCurrent; int lev = indentCurrent;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers // Only non whitespace lines can be headers

View File

@@ -17,12 +17,12 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_C_DEFAULT; char chAttr = SCE_C_DEFAULT;
@@ -43,7 +43,7 @@ static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywor
} }
static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];

View File

@@ -51,20 +51,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {
} else if (markType == SC_MARK_PLUS) { } else if (markType == SC_MARK_PLUS) {
int armSize = dimOn2-2; int armSize = dimOn2-2;
Point xpts[] = {
Point(centreX - armSize, centreY),
Point(centreX, centreY),
Point(centreX, centreY - armSize),
Point(centreX, centreY - armSize),
Point(centreX, centreY),
Point(centreX + armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX, centreY),
Point(centreX, centreY + armSize),
Point(centreX, centreY + armSize),
Point(centreX, centreY),
Point(centreX - armSize, centreY),
};
Point pts[] = { Point pts[] = {
Point(centreX - armSize, centreY - 1), Point(centreX - armSize, centreY - 1),
Point(centreX - 1, centreY - 1), Point(centreX - 1, centreY - 1),
@@ -90,12 +76,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {
Point(centreX + armSize, centreY +1), Point(centreX + armSize, centreY +1),
Point(centreX - armSize, centreY + 1), Point(centreX - armSize, centreY + 1),
}; };
Point xpts[] = {
Point(centreX - armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX - armSize, centreY),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
fore.allocated, back.allocated); fore.allocated, back.allocated);

View File

@@ -39,7 +39,7 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
fpc++; fpc++;
lenData--; lenData--;
} }
*s++ = '\0'; *s = '\0';
return true; return true;
} }
} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) { } else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
@@ -122,7 +122,7 @@ SString PropSet::Get(const char *key) {
int PropSet::GetInt(const char *key, int defaultValue) { int PropSet::GetInt(const char *key, int defaultValue) {
SString val = Get(key); SString val = Get(key);
if (val.length()) if (val.length())
return Get(key).value(); return val.value();
else else
return defaultValue; return defaultValue;
} }
@@ -376,7 +376,7 @@ bool WordList::InList(const char *s) {
for (int i = 0; words[i][0]; i++) for (int i = 0; words[i][0]; i++)
len++; len++;
SortWordList(words, len); SortWordList(words, len);
for (int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1; starts[k] = -1;
for (int l = len - 1; l >= 0; l--) { for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0]; unsigned char indexChar = words[l][0];

View File

@@ -15,6 +15,8 @@
#include "SciLexer.h" #include "SciLexer.h"
#include "PropSet.h" #include "PropSet.h"
#include "Accessor.h" #include "Accessor.h"
#include "WindowAccessor.h"
#include "DocumentAccessor.h"
#include "KeyWords.h" #include "KeyWords.h"
#endif #endif
#include "ContractionState.h" #include "ContractionState.h"
@@ -50,11 +52,11 @@ void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) {
ct.RefreshColourPalette(pal, want); ct.RefreshColourPalette(pal, want);
} }
void ScintillaBase::AddChar(char ch) { void ScintillaBase::AddCharUTF(char *s, unsigned int len) {
bool acActiveBeforeCharAdded = ac.Active(); bool acActiveBeforeCharAdded = ac.Active();
Editor::AddChar(ch); Editor::AddCharUTF(s, len);
if (acActiveBeforeCharAdded) if (acActiveBeforeCharAdded)
AutoCompleteChanged(ch); AutoCompleteChanged(s[0]);
} }
void ScintillaBase::Command(int cmdId) { void ScintillaBase::Command(int cmdId) {
@@ -276,7 +278,8 @@ void ScintillaBase::Colourise(int start, int end) {
end = lengthDoc; end = lengthDoc;
int len = end - start; int len = end - start;
StylingContext styler(wMain.GetID(), props); //WindowAccessor styler(wMain.GetID(), props);
DocumentAccessor styler(pdoc, props);
int styleStart = 0; int styleStart = 0;
if (start > 0) if (start > 0)
@@ -288,7 +291,7 @@ void ScintillaBase::Colourise(int start, int end) {
} }
#endif #endif
void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded) { void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
#ifdef SCI_LEXER #ifdef SCI_LEXER
if (lexLanguage != SCLEX_CONTAINER) { if (lexLanguage != SCLEX_CONTAINER) {
int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0); int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0);
@@ -298,7 +301,7 @@ void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded) {
return; return;
} }
#endif #endif
Editor::NotifyStyleNeeded(endStyleNeeded); Editor::NotifyStyleToNeeded(endStyleNeeded);
} }
LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
@@ -321,10 +324,21 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
AutoCompleteCompleted(); AutoCompleteCompleted();
break; break;
case SCI_AUTOCSETSEPARATOR:
ac.SetSeparator(wParam);
break;
case SCI_AUTOCGETSEPARATOR:
return ac.GetSeparator();
case SCI_AUTOCSTOPS: case SCI_AUTOCSTOPS:
ac.SetStopChars(reinterpret_cast<char *>(lParam)); ac.SetStopChars(reinterpret_cast<char *>(lParam));
break; break;
case SCI_AUTOCSELECT:
ac.Select(reinterpret_cast<char *>(lParam));
break;
case SCI_CALLTIPSHOW: { case SCI_CALLTIPSHOW: {
AutoCompleteCancel(); AutoCompleteCancel();
if (!ct.wCallTip.Created()) { if (!ct.wCallTip.Created()) {
@@ -384,7 +398,7 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break; break;
case SCI_SETKEYWORDS: case SCI_SETKEYWORDS:
if ((wParam >= 0) && (wParam < numWordLists)) { if (wParam < numWordLists) {
keyWordLists[wParam]->Clear(); keyWordLists[wParam]->Clear();
keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam)); keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
} }

View File

@@ -7,6 +7,9 @@
#define SCINTILLABASE_H #define SCINTILLABASE_H
class ScintillaBase : public Editor { class ScintillaBase : public Editor {
// Private so ScintillaBase objects can not be copied
ScintillaBase(const ScintillaBase &) : Editor() {}
ScintillaBase &operator=(const ScintillaBase &) { return *this; }
protected: protected:
// Enumeration of commands and child windows // Enumeration of commands and child windows
enum { enum {
@@ -42,7 +45,7 @@ protected:
virtual void RefreshColourPalette(Palette &pal, bool want); virtual void RefreshColourPalette(Palette &pal, bool want);
virtual void AddChar(char ch); virtual void AddCharUTF(char *s, unsigned int len);
void Command(int cmdId); void Command(int cmdId);
virtual int KeyCommand(UINT iMessage); virtual int KeyCommand(UINT iMessage);
@@ -59,7 +62,7 @@ protected:
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
virtual void NotifyStyleNeeded(int endStyleNeeded); virtual void NotifyStyleToNeeded(int endStyleNeeded);
public: public:
// Public so scintilla_send_message can use it // Public so scintilla_send_message can use it
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);

View File

@@ -16,6 +16,18 @@ Style::Style() {
false, false, false); false, false, false);
} }
Style::Style(const Style &source) {
Clear(Colour(0,0,0), Colour(0xff,0xff,0xff),
0, 0,
false, false, false);
fore.desired = source.fore.desired;
back.desired = source.back.desired;
bold = source.bold;
italic = source.italic;
size = source.size;
eolFilled = source.eolFilled;
}
Style::~Style() { Style::~Style() {
if (aliasOfDefaultFont) if (aliasOfDefaultFont)
font.SetID(0); font.SetID(0);
@@ -78,7 +90,7 @@ void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) {
font.SetID(0); font.SetID(0);
else else
font.Release(); font.Release();
int deviceHeight = (sizeZoomed * surface.LogPixelsY()) / 72; int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle && aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName); (EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) { if (aliasOfDefaultFont) {
@@ -99,5 +111,3 @@ void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) {
aveCharWidth = surface.AverageCharWidth(font); aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' '); spaceWidth = surface.WidthChar(font, ' ');
} }

View File

@@ -26,6 +26,7 @@ public:
unsigned int spaceWidth; unsigned int spaceWidth;
Style(); Style();
Style(const Style &source);
~Style(); ~Style();
Style &operator=(const Style &source); Style &operator=(const Style &source);
void Clear(Colour fore_, Colour back_, void Clear(Colour fore_, Colour back_,

View File

@@ -0,0 +1,77 @@
// UniConversion.h - functions to handle UFT-8 and UCS-2 strings
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "UniConversion.h"
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) {
unsigned int len = 0;
for (unsigned int i = 0; i < tlen && uptr[i]; i++) {
unsigned int uch = uptr[i];
if (uch < 0x80)
len++;
else if (uch < 0x800)
len+=2;
else
len +=3;
}
return len;
}
void UTF8FromUCS2(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) {
int k = 0;
for (unsigned int i = 0; i < tlen && uptr[i]; i++) {
unsigned int uch = uptr[i];
if (uch < 0x80) {
putf[k++] = static_cast<char>(uch);
} else if (uch < 0x800) {
putf[k++] = static_cast<char>(0xC0 | (uch >> 6));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
} else {
putf[k++] = static_cast<char>(0xE0 | (uch >> 12));
putf[k++] = static_cast<char>(0x80 | ((uch >> 6) & 0x3f));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
}
}
putf[len] = '\0';
}
unsigned int UCS2Length(const char *s, unsigned int len) {
unsigned int ulen = 0;
for (unsigned int i=0;i<len;i++) {
unsigned char ch = static_cast<unsigned char>(s[i]);
if ((ch < 0x80) || (ch > (0x80 + 0x40)))
ulen++;
}
return ulen;
}
unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen) {
#ifdef USE_API
return ::MultiByteToWideChar(CP_UTF8, 0, s, len, tbuf, tlen);
#else
unsigned int ui=0;
const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
unsigned int i=0;
while ((i<len) && (ui<tlen)) {
unsigned char ch = us[i++];
if (ch < 0x80) {
tbuf[ui] = ch;
} else if (ch < 0x80 + 0x40 + 0x20) {
tbuf[ui] = static_cast<wchar_t>((ch & 0x1F) << 6);
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F));
} else {
tbuf[ui] = static_cast<wchar_t>((ch & 0xF) << 12);
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + ((ch & 0x7F) << 6));
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F));
}
ui++;
}
return ui;
#endif
}

View File

@@ -0,0 +1,9 @@
// UniConversion.h - functions to handle UFT-8 and UCS-2 strings
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen);
void UTF8FromUCS2(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len);
unsigned int UCS2Length(const char *s, unsigned int len);
unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen);

View File

@@ -225,5 +225,3 @@ void ViewStyle::ClearStyles() {
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
styles[styleIndex].fontName = fontNames.Save(name); styles[styleIndex].fontName = fontNames.Save(name);
} }

View File

@@ -11,20 +11,29 @@
#include "PropSet.h" #include "PropSet.h"
#include "Accessor.h" #include "Accessor.h"
#include "WindowAccessor.h"
#include "Scintilla.h" #include "Scintilla.h"
bool Accessor::InternalIsLeadByte(char ch) { WindowAccessor::~WindowAccessor() {
}
bool WindowAccessor::InternalIsLeadByte(char ch) {
#if PLAT_GTK #if PLAT_GTK
// TODO: support DBCS under GTK+ // TODO: support DBCS under GTK+
return false; return false;
#elif PLAT_WIN #elif PLAT_WIN
if (SC_CP_UTF8 == codePage)
// For lexing, all characters >= 0x80 are treated the
// same so none is considered a lead byte.
return false;
else
return IsDBCSLeadByteEx(codePage, ch); return IsDBCSLeadByteEx(codePage, ch);
#elif PLAT_WX #elif PLAT_WX
return false; return false;
#endif #endif
} }
void Accessor::Fill(int position) { void WindowAccessor::Fill(int position) {
if (lenDoc == -1) if (lenDoc == -1)
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
startPos = position - slopSize; startPos = position - slopSize;
@@ -40,46 +49,46 @@ void Accessor::Fill(int position) {
Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)); Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr));
} }
char Accessor::StyleAt(int position) { char WindowAccessor::StyleAt(int position) {
return static_cast<char>(Platform::SendScintilla( return static_cast<char>(Platform::SendScintilla(
id, SCI_GETSTYLEAT, position, 0)); id, SCI_GETSTYLEAT, position, 0));
} }
int Accessor::GetLine(int position) { int WindowAccessor::GetLine(int position) {
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
} }
int Accessor::LineStart(int line) { int WindowAccessor::LineStart(int line) {
return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); return Platform::SendScintilla(id, EM_LINEINDEX, line, 0);
} }
int Accessor::LevelAt(int line) { int WindowAccessor::LevelAt(int line) {
return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
} }
int Accessor::Length() { int WindowAccessor::Length() {
if (lenDoc == -1) if (lenDoc == -1)
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
return lenDoc; return lenDoc;
} }
int Accessor::GetLineState(int line) { int WindowAccessor::GetLineState(int line) {
return Platform::SendScintilla(id, SCI_GETLINESTATE, line); return Platform::SendScintilla(id, SCI_GETLINESTATE, line);
} }
int Accessor::SetLineState(int line, int state) { int WindowAccessor::SetLineState(int line, int state) {
return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state); return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state);
} }
void StylingContext::StartAt(unsigned int start, char chMask) { void WindowAccessor::StartAt(unsigned int start, char chMask) {
Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask); Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask);
} }
void StylingContext::StartSegment(unsigned int pos) { void WindowAccessor::StartSegment(unsigned int pos) {
startSeg = pos; startSeg = pos;
} }
void StylingContext::ColourTo(unsigned int pos, int chAttr) { void WindowAccessor::ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range // Only perform styling if non empty range
if (pos != startSeg - 1) { if (pos != startSeg - 1) {
if (pos < startSeg) { if (pos < startSeg) {
@@ -96,22 +105,20 @@ void StylingContext::ColourTo(unsigned int pos, int chAttr) {
chFlags = 0; chFlags = 0;
chAttr |= chFlags; chAttr |= chFlags;
for (unsigned int i = startSeg; i <= pos; i++) { for (unsigned int i = startSeg; i <= pos; i++) {
styleBuf[validLen++] = chAttr; styleBuf[validLen++] = static_cast<char>(chAttr);
} }
} }
} }
startSeg = pos+1; startSeg = pos+1;
} }
int StylingContext::GetLine(int position) { void WindowAccessor::SetLevel(int line, int level) {
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
}
void StylingContext::SetLevel(int line, int level) {
Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level); Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level);
} }
void StylingContext::Flush() { void WindowAccessor::Flush() {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) { if (validLen > 0) {
Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen,
reinterpret_cast<LPARAM>(styleBuf)); reinterpret_cast<LPARAM>(styleBuf));
@@ -119,7 +126,7 @@ void StylingContext::Flush() {
} }
} }
int StylingContext::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
int end = Length(); int end = Length();
int spaceFlags = 0; int spaceFlags = 0;

View File

@@ -116,7 +116,7 @@ wxStyledTextCtrl::~wxStyledTextCtrl() {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) { long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) {
return m_swx->WndProc(msg, wp, lp); return m_swx->WndProc(msg, wp, lp);
} }
@@ -146,8 +146,9 @@ wxString wxStyledTextCtrl::GetLine(int line) {
int len = GetLineLength(line); int len = GetLineLength(line);
char* buff = text.GetWriteBuf(len+1); char* buff = text.GetWriteBuf(len+1);
*((WORD*)buff) = len+1; *((WORD*)buff) = len;
SendMsg(EM_GETLINE, line, (long)buff); SendMsg(EM_GETLINE, line, (long)buff);
buff[len] = 0;
text.UngetWriteBuf(); text.UngetWriteBuf();
return text; return text;
} }
@@ -426,16 +427,16 @@ int wxStyledTextCtrl::GetCurrentLine() {
} }
wxString wxStyledTextCtrl::GetCurrentLineText(/*int* linePos*/) { wxString wxStyledTextCtrl::GetCurrentLineText(int* linePos) {
wxString text; wxString text;
int len = GetLineLength(GetCurrentLine()); int len = GetLineLength(GetCurrentLine());
char* buff = text.GetWriteBuf(len+1); char* buff = text.GetWriteBuf(len+1);
int pos = SendMsg(SCI_GETCURLINE, len+1, (long)buff); int pos = SendMsg(SCI_GETCURLINE, len, (long)buff);
text.UngetWriteBuf(); text.UngetWriteBuf();
/* if (linePos) if (linePos)
*linePos = pos; */ *linePos = pos;
return text; return text;
} }
@@ -457,7 +458,7 @@ int wxStyledTextCtrl::LineFromPoint(wxPoint pt) {
wxPoint wxStyledTextCtrl::PointFromPosition(int pos) { wxPoint wxStyledTextCtrl::PointFromPosition(int pos) {
Point pt; Point pt;
SendMsg(EM_POSFROMCHAR, pos, (long)&pt); SendMsg(EM_POSFROMCHAR, (long)&pt, pos);
return wxPoint(pt.x, pt.y); return wxPoint(pt.x, pt.y);
} }
@@ -538,6 +539,27 @@ int wxStyledTextCtrl::GetSelectionType() {
} }
int wxStyledTextCtrl::GetLinesOnScreen() {
return SendMsg(SCI_LINESONSCREEN);
}
bool wxStyledTextCtrl::IsSelectionRectangle() {
return SendMsg(SCI_SELECTIONISRECTANGLE) != 0;
}
void wxStyledTextCtrl::SetUseHorizontalScrollBar(bool use) {
SendMsg(SCI_SETHSCROLLBAR, use);
}
bool wxStyledTextCtrl::GetUseHorizontalScrollBar() {
return SendMsg(SCI_GETHSCROLLBAR) != 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@@ -645,6 +667,16 @@ void wxStyledTextCtrl::SetStyleBytes(int length, char* styleBytes) {
} }
void wxStyledTextCtrl::SetLineState(int line, int value) {
SendMsg(SCI_SETLINESTATE, line, value);
}
int wxStyledTextCtrl::GetLineState(int line) {
return SendMsg(SCI_GETLINESTATE, line);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Style Definition // Style Definition
@@ -905,11 +937,41 @@ void wxStyledTextCtrl::SetTabWidth(int numChars) {
} }
void wxStyledTextCtrl::SetIndent(int numChars) {
SendMsg(SCI_SETINDENT, numChars);
}
void wxStyledTextCtrl::SetUseTabs(bool usetabs) {
SendMsg(SCI_SETUSETABS, usetabs);
}
void wxStyledTextCtrl::SetLineIndentation(int line, int indentation) {
SendMsg(SCI_SETLINEINDENTATION, line, indentation);
}
int wxStyledTextCtrl:: GetLineIndentation(int line) {
return SendMsg(SCI_GETLINEINDENTATION, line);
}
int wxStyledTextCtrl::GetLineIndentationPos(int line) {
return SendMsg(SCI_GETLINEINDENTPOSITION, line);
}
void wxStyledTextCtrl::SetWordChars(const wxString& wordChars) { void wxStyledTextCtrl::SetWordChars(const wxString& wordChars) {
SendMsg(SCI_SETTABWIDTH, 0, (long)wordChars.c_str()); SendMsg(SCI_SETTABWIDTH, 0, (long)wordChars.c_str());
} }
void wxStyledTextCtrl::SetUsePop(bool usepopup) {
SendMsg(SCI_USEPOPUP, usepopup);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Brace highlighting // Brace highlighting
@@ -1053,6 +1115,21 @@ void wxStyledTextCtrl::AutoCompStopChars(const wxString& stopChars) {
} }
void wxStyledTextCtrl::AutoCompSetSeparator(char separator) {
SendMsg(SCI_AUTOCSETSEPARATOR, separator);
}
char wxStyledTextCtrl::AutoCompGetSeparator() {
return SendMsg(SCI_AUTOCGETSEPARATOR);
}
void wxStyledTextCtrl::AutoCompSelect(const wxString& stringtoselect) {
SendMsg(SCI_AUTOCSELECT, (long)stringtoselect.c_str());
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Call tips // Call tips

View File

@@ -130,7 +130,9 @@ enum {
wxSTC_CMD_LINEDELETE, wxSTC_CMD_LINEDELETE,
wxSTC_CMD_LINETRANSPOSE, wxSTC_CMD_LINETRANSPOSE,
wxSTC_CMD_LOWERCASE, wxSTC_CMD_LOWERCASE,
wxSTC_CMD_UPPERCASE wxSTC_CMD_UPPERCASE,
wxSTC_CMD_LINESCROLLDOWN,
wxSTC_CMD_LINESCROLLUP
}; };
@@ -253,7 +255,11 @@ public:
int GetLineStartPos(int line); int GetLineStartPos(int line);
int GetLineLengthAtPos(int pos); int GetLineLengthAtPos(int pos);
int GetLineLength(int line); int GetLineLength(int line);
wxString GetCurrentLineText(); #ifdef SWIG
wxString GetCurrentLineText(int* OUTPUT);
#else
wxString GetCurrentLineText(int* linePos);
#endif
int GetCurrentLine(); int GetCurrentLine();
int PositionFromPoint(wxPoint pt); int PositionFromPoint(wxPoint pt);
int LineFromPoint(wxPoint pt); int LineFromPoint(wxPoint pt);
@@ -274,7 +280,10 @@ public:
void EnsureCaretVisible(); void EnsureCaretVisible();
void SetCaretPolicy(int policy, int slop=0); void SetCaretPolicy(int policy, int slop=0);
int GetSelectionType(); int GetSelectionType();
int GetLinesOnScreen();
bool IsSelectionRectangle();
void SetUseHorizontalScrollBar(bool use);
bool GetUseHorizontalScrollBar();
// Searching // Searching
@@ -303,6 +312,8 @@ public:
void StartStyling(int pos, int mask); void StartStyling(int pos, int mask);
void SetStyleFor(int length, int style); void SetStyleFor(int length, int style);
void SetStyleBytes(int length, char* styleBytes); void SetStyleBytes(int length, char* styleBytes);
void SetLineState(int line, int value);
int GetLineState(int line);
// Style Definition // Style Definition
@@ -348,8 +359,15 @@ public:
// Other settings // Other settings
void SetBufferedDraw(bool isBuffered); void SetBufferedDraw(bool isBuffered);
void SetTabWidth(int numChars); void SetTabWidth(int numChars);
void SetIndent(int numChars);
void SetUseTabs(bool usetabs);
void SetLineIndentation(int line, int indentation);
int GetLineIndentation(int line);
int GetLineIndentationPos(int line);
void SetWordChars(const wxString& wordChars); void SetWordChars(const wxString& wordChars);
void SetUsePop(bool usepopup);
// Brace highlighting // Brace highlighting
void BraceHighlight(int pos1, int pos2); void BraceHighlight(int pos1, int pos2);
@@ -387,7 +405,9 @@ public:
int AutoCompPosAtStart(); int AutoCompPosAtStart();
void AutoCompComplete(); void AutoCompComplete();
void AutoCompStopChars(const wxString& stopChars); void AutoCompStopChars(const wxString& stopChars);
void AutoCompSetSeparator(char separator);
char AutoCompGetSeparator();
void AutoCompSelect(const wxString& stringtoselect);
// Call tips // Call tips
void CallTipShow(int pos, const wxString& text); void CallTipShow(int pos, const wxString& text);

View File

@@ -23,7 +23,16 @@ HEADER_SUBDIR=stc
HEADERS=stc.h HEADERS=stc.h
OBJECTS=PlatWX.o ScintillaWX.o stc.o \ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Accessor.o \ DocumentAccessor.o \
LexCPP.o \
LexHTML.o \
LexOthers.o \
LexPerl.o \
LexPython.o \
LexSQL.o \
LexVB.o \
UniConversion.o \
WindowAccessor.o \
AutoComplete.o \ AutoComplete.o \
CallTip.o \ CallTip.o \
CellBuffer.o \ CellBuffer.o \
@@ -33,18 +42,12 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Indicator.o \ Indicator.o \
KeyMap.o \ KeyMap.o \
KeyWords.o \ KeyWords.o \
LexCPP.o \
LexHTML.o \
LexOthers.o \
LexPerl.o \
LexPython.o \
LexSQL.o \
LexVB.o \
LineMarker.o \ LineMarker.o \
PropSet.o \ PropSet.o \
ScintillaBase.o \ ScintillaBase.o \
Style.o \ Style.o \
ViewStyle.o ViewStyle.o \
APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include

View File

@@ -196,6 +196,12 @@ int Surface::LogPixelsY() {
return hdc->GetPPI().y; return hdc->GetPPI().y;
} }
int Surface::DeviceHeightFont(int points) {
return points * LogPixelsY() / 72;
}
void Surface::MoveTo(int x_, int y_) { void Surface::MoveTo(int x_, int y_) {
x = x_; x = x_;
y = y_; y = y_;

View File

@@ -195,9 +195,8 @@ void ScintillaWX::NotifyParent(SCNotification scn) {
void ScintillaWX::Copy() { void ScintillaWX::Copy() {
if (currentPos != anchor) { if (currentPos != anchor) {
char* text = CopySelectionRange(); char* text = CopySelectionRange();
textDO.SetText(text);
wxTheClipboard->Open(); wxTheClipboard->Open();
wxTheClipboard->SetData(&textDO); wxTheClipboard->SetData(new wxTextDataObject(text));
wxTheClipboard->Close(); wxTheClipboard->Close();
} }
} }

View File

@@ -139,7 +139,6 @@ private:
bool capturedMouse; bool capturedMouse;
wxStyledTextCtrl* stc; wxStyledTextCtrl* stc;
wxTextDataObject textDO;
wxSTCDropTarget* dropTarget; wxSTCDropTarget* dropTarget;
wxDragResult dragResult; wxDragResult dragResult;
}; };

View File

@@ -25,17 +25,13 @@ OBJECTS = \
AutoComplete.obj \ AutoComplete.obj \
CallTip.obj \ CallTip.obj \
CellBuffer.obj \ CellBuffer.obj \
ContractionState.obj\ ContractionState.obj \
Document.obj \ Document.obj \
DocumentAccessor.obj \
Editor.obj \ Editor.obj \
Indicator.obj \ Indicator.obj \
KeyMap.obj \ KeyMap.obj \
KeyWords.obj \ KeyWords.obj \
LineMarker.obj \
PropSet.obj \
ScintillaBase.obj \
Style.obj \
ViewStyle.obj \
LexCPP.obj \ LexCPP.obj \
LexHTML.obj \ LexHTML.obj \
LexOthers.obj \ LexOthers.obj \
@@ -43,11 +39,19 @@ OBJECTS = \
LexPython.obj \ LexPython.obj \
LexSQL.obj \ LexSQL.obj \
LexVB.obj \ LexVB.obj \
LineMarker.obj \
PropSet.obj \
ScintillaBase.obj \
Style.obj \
UniConversion.obj \
ViewStyle.obj \
WindowAccessor.obj \
\ \
PlatWX.obj \ PlatWX.obj \
ScintillaWX.obj \ ScintillaWX.obj \
stc.obj \ stc.obj \
!include $(WXDIR)\src\makelib.b32 !include $(WXDIR)\src\makelib.b32
CFG = stc.cfg CFG = stc.cfg

View File

@@ -32,6 +32,9 @@ OBJECTS = \
$(S)/LexPython.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \
$(S)/LexSQL.$(OBJSUFF) \ $(S)/LexSQL.$(OBJSUFF) \
$(S)/LexVB.$(OBJSUFF) \ $(S)/LexVB.$(OBJSUFF) \
$(S)/DocumentAccessor.$(OBJSUFF)\
$(S)/UniConversion.$(OBJSUFF) \
$(S)/WindowAccessor.$(OBJSUFF) \
PlatWX.$(OBJSUFF) \ PlatWX.$(OBJSUFF) \
ScintillaWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \
stc.$(OBJSUFF) stc.$(OBJSUFF)

View File

@@ -15,21 +15,16 @@ NOPCH=1
!include $(WXDIR)\src\makevc.env !include $(WXDIR)\src\makevc.env
OBJECTS = \ OBJECTS = \
$(D)\Accessor.obj \
$(D)\AutoComplete.obj \ $(D)\AutoComplete.obj \
$(D)\CallTip.obj \ $(D)\CallTip.obj \
$(D)\CellBuffer.obj \ $(D)\CellBuffer.obj \
$(D)\ContractionState.obj\ $(D)\ContractionState.obj\
$(D)\Document.obj \ $(D)\Document.obj \
$(D)\DocumentAccessor.obj\
$(D)\Editor.obj \ $(D)\Editor.obj \
$(D)\Indicator.obj \ $(D)\Indicator.obj \
$(D)\KeyMap.obj \ $(D)\KeyMap.obj \
$(D)\KeyWords.obj \ $(D)\KeyWords.obj \
$(D)\LineMarker.obj \
$(D)\PropSet.obj \
$(D)\ScintillaBase.obj \
$(D)\Style.obj \
$(D)\ViewStyle.obj \
$(D)\LexCPP.obj \ $(D)\LexCPP.obj \
$(D)\LexHTML.obj \ $(D)\LexHTML.obj \
$(D)\LexOthers.obj \ $(D)\LexOthers.obj \
@@ -37,6 +32,13 @@ OBJECTS = \
$(D)\LexPython.obj \ $(D)\LexPython.obj \
$(D)\LexSQL.obj \ $(D)\LexSQL.obj \
$(D)\LexVB.obj \ $(D)\LexVB.obj \
$(D)\LineMarker.obj \
$(D)\PropSet.obj \
$(D)\ScintillaBase.obj \
$(D)\Style.obj \
$(D)\UniConversion.obj \
$(D)\ViewStyle.obj \
$(D)\WindowAccessor.obj \
\ \
$(D)\PlatWX.obj \ $(D)\PlatWX.obj \
$(D)\ScintillaWX.obj \ $(D)\ScintillaWX.obj \

View File

@@ -5,29 +5,28 @@
enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
class Accessor;
typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
// Interface to data in a Scintilla
class Accessor { class Accessor {
protected: protected:
// bufferSize is a trade off between time taken to copy the characters and SendMessage overhead enum {extremePosition=0x7FFFFFFF};
// bufferSize is a trade off between time taken to copy the characters and retrieval overhead
// slopSize positions the buffer before the desired position in case there is some backtracking // slopSize positions the buffer before the desired position in case there is some backtracking
enum {bufferSize=4000, slopSize=bufferSize/8}; enum {bufferSize=4000, slopSize=bufferSize/8};
char buf[bufferSize+1]; char buf[bufferSize+1];
WindowID id;
PropSet &props;
int startPos; int startPos;
int endPos; int endPos;
int lenDoc;
int offset; // Optional but including an offset makes GCC generate better code
int codePage; int codePage;
bool InternalIsLeadByte(char ch);
void Fill(int position); virtual bool InternalIsLeadByte(char ch)=0;
virtual void Fill(int position)=0;
public: public:
Accessor(WindowID id_, PropSet &props_, int offset_=0) : Accessor() : startPos(extremePosition), endPos(0), codePage(0) {}
id(id_), props(props_), startPos(0x7FFFFFFF), endPos(0), virtual ~Accessor() {}
lenDoc(-1), offset(offset_), codePage(0) {
}
void SetCodePage(int codePage_) { codePage = codePage_; }
char operator[](int position) { char operator[](int position) {
position += offset;
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
Fill(position); Fill(position);
} }
@@ -35,7 +34,6 @@ public:
} }
char SafeGetCharAt(int position, char chDefault=' ') { char SafeGetCharAt(int position, char chDefault=' ') {
// Safe version of operator[], returning a defined value for invalid position // Safe version of operator[], returning a defined value for invalid position
position += offset;
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
Fill(position); Fill(position);
if (position < startPos || position >= endPos) { if (position < startPos || position >= endPos) {
@@ -48,41 +46,25 @@ public:
bool IsLeadByte(char ch) { bool IsLeadByte(char ch) {
return codePage && InternalIsLeadByte(ch); return codePage && InternalIsLeadByte(ch);
} }
char StyleAt(int position); void SetCodePage(int codePage_) { codePage = codePage_; }
int GetLine(int position);
int LineStart(int line); virtual char StyleAt(int position)=0;
int LevelAt(int line); virtual int GetLine(int position)=0;
int Length(); virtual int LineStart(int line)=0;
void Flush() { virtual int LevelAt(int line)=0;
startPos = 0x7FFFFFFF; virtual int Length()=0;
lenDoc = -1; virtual void Flush()=0;
} virtual int GetLineState(int line)=0;
int GetLineState(int line); virtual int SetLineState(int line, int state)=0;
int SetLineState(int line, int state); virtual int GetPropertyInt(const char *key, int defaultValue=0)=0;
PropSet &GetPropSet() { return props; }
}; // Style setting
virtual void StartAt(unsigned int start, char chMask=31)=0;
class StylingContext; virtual void SetFlags(char chFlags_, char chWhile_)=0;
virtual unsigned int GetStartSegment()=0;
typedef bool (*PFNIsCommentLeader)(StylingContext &styler, int pos, int len); virtual void StartSegment(unsigned int pos)=0;
virtual void ColourTo(unsigned int pos, int chAttr)=0;
class StylingContext : public Accessor { virtual void SetLevel(int line, int level)=0;
char styleBuf[bufferSize]; virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0;
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
public:
StylingContext(WindowID id_, PropSet &props_, int offset_=0) :
Accessor(id_,props_,offset_), validLen(0), chFlags(0) {}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
int GetLine(int position);
void SetLevel(int line, int level);
void Flush();
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
}; };

View File

@@ -4,7 +4,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], StylingContext &styler); WordList *keywordlists[], Accessor &styler);
class LexerModule { class LexerModule {
static LexerModule *base; static LexerModule *base;
@@ -14,7 +14,7 @@ class LexerModule {
public: public:
LexerModule(int language_, LexerFunction fn_); LexerModule(int language_, LexerFunction fn_);
static void Colourise(unsigned int startPos, int lengthDoc, int initStyle, static void Colourise(unsigned int startPos, int lengthDoc, int initStyle,
int language, WordList *keywordlists[], StylingContext &styler); int language, WordList *keywordlists[], Accessor &styler);
}; };
inline bool iswordchar(char ch) { inline bool iswordchar(char ch) {

View File

@@ -45,6 +45,7 @@
#pragma warning(disable: 4800 4244 4309) #pragma warning(disable: 4800 4244 4309)
#endif #endif
#include <windows.h> #include <windows.h>
#include <commctrl.h>
#include <richedit.h> #include <richedit.h>
#endif #endif
@@ -221,6 +222,7 @@ public:
// A surface abstracts a place to draw // A surface abstracts a place to draw
class Surface { class Surface {
private: private:
bool unicodeMode;
#if PLAT_GTK #if PLAT_GTK
GdkDrawable *drawable; GdkDrawable *drawable;
GdkGC *gc; GdkGC *gc;
@@ -268,6 +270,7 @@ public:
bool Initialised(); bool Initialised();
void PenColour(Colour fore); void PenColour(Colour fore);
int LogPixelsY(); int LogPixelsY();
int DeviceHeightFont(int points);
void MoveTo(int x_, int y_); void MoveTo(int x_, int y_);
void LineTo(int x_, int y_); void LineTo(int x_, int y_);
void Polygon(Point *pts, int npts, Colour fore, Colour back); void Polygon(Point *pts, int npts, Colour fore, Colour back);
@@ -293,6 +296,10 @@ public:
int SetPalette(Palette *pal, bool inBackGround); int SetPalette(Palette *pal, bool inBackGround);
void SetClip(PRectangle rc); void SetClip(PRectangle rc);
void FlushCachedState(); void FlushCachedState();
void SetUnicodeMode(bool unicodeMode_) {
unicodeMode=unicodeMode_;
}
}; };
// Class to hide the details of window manipulation // Class to hide the details of window manipulation
@@ -303,6 +310,7 @@ protected:
WindowID id; WindowID id;
public: public:
Window() : id(0) {} Window() : id(0) {}
Window(const Window &source) : id(source.id) {}
virtual ~Window(); virtual ~Window();
Window &operator=(WindowID id_) { Window &operator=(WindowID id_) {
id = id_; id = id_;

View File

@@ -75,7 +75,7 @@ public:
else else
return 0; return 0;
} }
char operator[](int i) { char operator[](int i) const {
if (s) if (s)
return s[i]; return s[i];
else else
@@ -95,7 +95,7 @@ public:
} }
return *this; return *this;
} }
int value() { int value() const {
if (s) if (s)
return atoi(s); return atoi(s);
else else
@@ -168,7 +168,7 @@ public:
WordList(bool onlyLineEnds_ = false) : WordList(bool onlyLineEnds_ = false) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {} words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {}
~WordList() { Clear(); } ~WordList() { Clear(); }
operator bool() { return list; } operator bool() { return list ? true : false; }
const char *operator[](int ind) { return words[ind]; } const char *operator[](int ind) { return words[ind]; }
void Clear(); void Clear();
void Set(const char *s); void Set(const char *s);

View File

@@ -21,6 +21,7 @@
#define SCLEX_ERRORLIST 10 #define SCLEX_ERRORLIST 10
#define SCLEX_MAKEFILE 11 #define SCLEX_MAKEFILE 11
#define SCLEX_BATCH 12 #define SCLEX_BATCH 12
#define SCLEX_XCODE 13
// Lexical states for SCLEX_PYTHON // Lexical states for SCLEX_PYTHON
#define SCE_P_DEFAULT 0 #define SCE_P_DEFAULT 0

View File

@@ -107,6 +107,9 @@ extern "C" {
#define SCI_STARTSTYLING SCI_START + 32 #define SCI_STARTSTYLING SCI_START + 32
#define SCI_SETSTYLING SCI_START + 33 #define SCI_SETSTYLING SCI_START + 33
// This is the same value as CP_UTF8 in Windows
#define SC_CP_UTF8 65001
#define SCI_SETBUFFEREDDRAW SCI_START + 35 #define SCI_SETBUFFEREDDRAW SCI_START + 35
#define SCI_SETTABWIDTH SCI_START + 36 #define SCI_SETTABWIDTH SCI_START + 36
#define SCI_SETCODEPAGE SCI_START + 37 #define SCI_SETCODEPAGE SCI_START + 37
@@ -213,6 +216,21 @@ extern "C" {
#define SCI_AUTOCPOSSTART SCI_START + 103 #define SCI_AUTOCPOSSTART SCI_START + 103
#define SCI_AUTOCCOMPLETE SCI_START + 104 #define SCI_AUTOCCOMPLETE SCI_START + 104
#define SCI_AUTOCSTOPS SCI_START + 105 #define SCI_AUTOCSTOPS SCI_START + 105
#define SCI_AUTOCSETSEPARATOR SCI_START + 106
#define SCI_AUTOCGETSEPARATOR SCI_START + 107
#define SCI_AUTOCSELECT SCI_START + 108
#define SCI_GETTABWIDTH SCI_START + 121
#define SCI_SETINDENT SCI_START + 122
#define SCI_GETINDENT SCI_START + 123
#define SCI_SETUSETABS SCI_START + 124
#define SCI_GETUSETABS SCI_START + 125
#define SCI_SETLINEINDENTATION SCI_START + 126
#define SCI_GETLINEINDENTATION SCI_START + 127
#define SCI_GETLINEINDENTPOSITION SCI_START + 128
#define SCI_SETHSCROLLBAR SCI_START + 130
#define SCI_GETHSCROLLBAR SCI_START + 131
#define SCI_CALLTIPSHOW SCI_START + 200 #define SCI_CALLTIPSHOW SCI_START + 200
#define SCI_CALLTIPCANCEL SCI_START + 201 #define SCI_CALLTIPCANCEL SCI_START + 201
@@ -284,6 +302,8 @@ extern "C" {
#define SCI_LINETRANSPOSE SCI_START + 339 #define SCI_LINETRANSPOSE SCI_START + 339
#define SCI_LOWERCASE SCI_START + 340 #define SCI_LOWERCASE SCI_START + 340
#define SCI_UPPERCASE SCI_START + 341 #define SCI_UPPERCASE SCI_START + 341
#define SCI_LINESCROLLDOWN SCI_START + 342
#define SCI_LINESCROLLUP SCI_START + 343
#define SCI_LINELENGTH SCI_START + 350 #define SCI_LINELENGTH SCI_START + 350
#define SCI_BRACEHIGHLIGHT SCI_START + 351 #define SCI_BRACEHIGHLIGHT SCI_START + 351
@@ -318,6 +338,7 @@ extern "C" {
#define SCI_SETCARETPOLICY SCI_START + 369 #define SCI_SETCARETPOLICY SCI_START + 369
#define SCI_LINESONSCREEN SCI_START + 370 #define SCI_LINESONSCREEN SCI_START + 370
#define SCI_USEPOPUP SCI_START + 371 #define SCI_USEPOPUP SCI_START + 371
#define SCI_SELECTIONISRECTANGLE SCI_START + 372
// GTK+ Specific // GTK+ Specific
#define SCI_GRABFOCUS SCI_START + 400 #define SCI_GRABFOCUS SCI_START + 400
@@ -350,8 +371,10 @@ typedef void (tMacroRecorder)(UINT iMessage, WPARAM wParam, LPARAM lParam,
#define SC_PERFORMED_REDO 0x40 #define SC_PERFORMED_REDO 0x40
#define SC_LASTSTEPINUNDOREDO 0x100 #define SC_LASTSTEPINUNDOREDO 0x100
#define SC_MOD_CHANGEMARKER 0x200 #define SC_MOD_CHANGEMARKER 0x200
#define SC_MOD_BEFOREINSERT 0x400
#define SC_MOD_BEFOREDELETE 0x800
#define SC_MODEVENTMASKALL 0x377 #define SC_MODEVENTMASKALL 0xF77
struct SCNotification { struct SCNotification {
NMHDR nmhdr; NMHDR nmhdr;

View File

@@ -0,0 +1,47 @@
// WindowAccessor.h - implementation of BufferAccess and StylingAccess on a Scintilla rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
class WindowAccessor : public Accessor {
// Private so WindowAccessor objects can not be copied
WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
WindowAccessor &operator=(const WindowAccessor &) { return *this; }
protected:
WindowID id;
PropSet &props;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
WindowAccessor(WindowID id_, PropSet &props_) :
Accessor(), id(id_), props(props_),
lenDoc(-1), validLen(0), chFlags(0) {
}
~WindowAccessor();
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
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);
}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
};

View File

@@ -15,6 +15,7 @@ AutoComplete::AutoComplete() {
active = false; active = false;
posStart = 0; posStart = 0;
strcpy(stopChars, ""); strcpy(stopChars, "");
separator = ' ';
} }
AutoComplete::~AutoComplete() { AutoComplete::~AutoComplete() {
@@ -44,6 +45,14 @@ bool AutoComplete::IsStopChar(char ch) {
return ch && strchr(stopChars, ch); return ch && strchr(stopChars, ch);
} }
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
char AutoComplete::GetSeparator() {
return separator;
}
int AutoComplete::SetList(const char *list) { int AutoComplete::SetList(const char *list) {
int maxStrLen = 12; int maxStrLen = 12;
lb.Clear(); lb.Clear();
@@ -53,7 +62,7 @@ int AutoComplete::SetList(const char *list) {
char *startword = words; char *startword = words;
int i = 0; int i = 0;
for (; words && words[i]; i++) { for (; words && words[i]; i++) {
if (words[i] == ' ') { if (words[i] == separator) {
words[i] = '\0'; words[i] = '\0';
lb.Append(startword); lb.Append(startword);
maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); maxStrLen = Platform::Maximum(maxStrLen, strlen(startword));

View File

@@ -9,6 +9,7 @@
class AutoComplete { class AutoComplete {
bool active; bool active;
char stopChars[256]; char stopChars[256];
char separator;
public: public:
ListBox lb; ListBox lb;
int posStart; int posStart;
@@ -27,7 +28,11 @@ public:
void SetStopChars(const char *stopChars_); void SetStopChars(const char *stopChars_);
bool IsStopChar(char ch); bool IsStopChar(char ch);
// The list string contains a sequence of words separated by spaces // The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
char GetSeparator();
// The list string contains a sequence of words separated by the separator character
int SetList(const char *list); int SetList(const char *list);
void Show(); void Show();

View File

@@ -6,13 +6,14 @@
#ifndef CALLTIP_H #ifndef CALLTIP_H
#define CALLTIP_H #define CALLTIP_H
const char callClassName[] = "CallTip";
class CallTip { class CallTip {
int startHighlight; int startHighlight;
int endHighlight; int endHighlight;
char *val; char *val;
Font font; Font font;
// Private so CallTip objects can not be copied
CallTip(const CallTip &) {}
CallTip &operator=(const CallTip &) { return *this; }
public: public:
Window wCallTip; Window wCallTip;
Window wDraw; Window wDraw;

View File

@@ -191,11 +191,23 @@ void LineVector::InsertValue(int pos, int value) {
} }
} }
lines++; lines++;
for (int i = lines + 1; i > pos; i--) { for (int i = lines; i > pos; i--) {
linesData[i] = linesData[i - 1]; linesData[i] = linesData[i - 1];
} }
linesData[pos].startPosition = value; linesData[pos].startPosition = value;
linesData[pos].handleSet = 0; linesData[pos].handleSet = 0;
if (levels) {
for (int j = lines; j > pos; j--) {
levels[j] = levels[j - 1];
}
if (pos == 0) {
levels[pos] = SC_FOLDLEVELBASE;
} else if (pos == (lines-1)) { // Last line will not be a folder
levels[pos] = SC_FOLDLEVELBASE;
} else {
levels[pos] = levels[pos-1];
}
}
} }
void LineVector::SetValue(int pos, int value) { void LineVector::SetValue(int pos, int value) {
@@ -221,6 +233,15 @@ void LineVector::Remove(int pos) {
for (int i = pos; i < lines; i++) { for (int i = pos; i < lines; i++) {
linesData[i] = linesData[i + 1]; linesData[i] = linesData[i + 1];
} }
if (levels) {
// Level information merges back onto previous line
int posAbove = pos-1;
if (posAbove < 0)
posAbove = 0;
for (int j = posAbove; j < lines; j++) {
levels[j] = levels[j + 1];
}
}
lines--; lines--;
} }
@@ -233,9 +254,8 @@ int LineVector::LineFromPosition(int pos) {
return lines - 1; return lines - 1;
int lower = 0; int lower = 0;
int upper = lines; int upper = lines;
int middle = 0;
do { do {
middle = (upper + lower + 1) / 2; // Round high int middle = (upper + lower + 1) / 2; // Round high
if (pos < linesData[middle].startPosition) { if (pos < linesData[middle].startPosition) {
upper = middle - 1; upper = middle - 1;
} else { } else {
@@ -316,12 +336,13 @@ Action::~Action() {
Destroy(); Destroy();
} }
void Action::Create(actionType at_, int position_, char *data_, int lenData_) { void Action::Create(actionType at_, int position_, char *data_, int lenData_, bool mayCoalesce_) {
delete []data; delete []data;
position = position_; position = position_;
at = at_; at = at_;
data = data_; data = data_;
lenData = lenData_; lenData = lenData_;
mayCoalesce = mayCoalesce_;
} }
void Action::Destroy() { void Action::Destroy() {
@@ -336,12 +357,14 @@ void Action::Grab(Action *source) {
at = source->at; at = source->at;
data = source->data; data = source->data;
lenData = source->lenData; lenData = source->lenData;
mayCoalesce = source->mayCoalesce;
// Ownership of source data transferred to this // Ownership of source data transferred to this
source->position = 0; source->position = 0;
source->at = startAction; source->at = startAction;
source->data = 0; source->data = 0;
source->lenData = 0; source->lenData = 0;
source->mayCoalesce = true;
} }
// The undo history stores a sequence of user operations that represent the user's view of the // The undo history stores a sequence of user operations that represent the user's view of the
@@ -426,6 +449,8 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
//Platform::DebugPrintf("action coalesced\n"); //Platform::DebugPrintf("action coalesced\n");
} }
} else { } else {
// Actions not at top level are always coalesced unless this is after return to top level
if (!actions[currentAction].mayCoalesce)
currentAction++; currentAction++;
} }
} else { } else {
@@ -445,6 +470,7 @@ void UndoHistory::BeginUndoAction() {
actions[currentAction].Create(startAction); actions[currentAction].Create(startAction);
maxAction = currentAction; maxAction = currentAction;
} }
actions[currentAction].mayCoalesce = false;
} }
undoSequenceDepth++; undoSequenceDepth++;
} }
@@ -458,6 +484,7 @@ void UndoHistory::EndUndoAction() {
actions[currentAction].Create(startAction); actions[currentAction].Create(startAction);
maxAction = currentAction; maxAction = currentAction;
} }
actions[currentAction].mayCoalesce = false;
} }
} }
@@ -499,8 +526,12 @@ int UndoHistory::StartUndo() {
return currentAction - act; return currentAction - act;
} }
const Action &UndoHistory::UndoStep() { const Action &UndoHistory::GetUndoStep() const {
return actions[currentAction--]; return actions[currentAction];
}
void UndoHistory::CompletedUndoStep() {
currentAction--;
} }
bool UndoHistory::CanRedo() const { bool UndoHistory::CanRedo() const {
@@ -520,8 +551,12 @@ int UndoHistory::StartRedo() {
return act - currentAction; return act - currentAction;
} }
const Action &UndoHistory::RedoStep() { const Action &UndoHistory::GetRedoStep() const {
return actions[currentAction++]; return actions[currentAction];
}
void UndoHistory::CompletedRedoStep() {
currentAction++;
} }
CellBuffer::CellBuffer(int initialLength) { CellBuffer::CellBuffer(int initialLength) {
@@ -673,7 +708,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) {
bool CellBuffer::SetStyleAt(int position, char style, char mask) { bool CellBuffer::SetStyleAt(int position, char style, char mask) {
char curVal = ByteAt(position*2 + 1); char curVal = ByteAt(position*2 + 1);
if ((curVal & mask) != style) { if ((curVal & mask) != style) {
SetByteAt(position*2 + 1, (curVal & ~mask) | style); SetByteAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style));
return true; return true;
} else { } else {
return false; return false;
@@ -686,7 +721,7 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas
while (lengthStyle--) { while (lengthStyle--) {
char curVal = ByteAt(bytePos); char curVal = ByteAt(bytePos);
if ((curVal & mask) != style) { if ((curVal & mask) != style) {
SetByteAt(bytePos, (curVal & ~mask) | style); SetByteAt(bytePos, static_cast<char>((curVal & ~mask) | style));
changed = true; changed = true;
} }
bytePos += 2; bytePos += 2;
@@ -947,8 +982,12 @@ int CellBuffer::StartUndo() {
return uh.StartUndo(); return uh.StartUndo();
} }
const Action &CellBuffer::UndoStep() { const Action &CellBuffer::GetUndoStep() const {
const Action &actionStep = uh.UndoStep(); return uh.GetUndoStep();
}
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) { if (actionStep.at == insertAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2); BasicDeleteChars(actionStep.position, actionStep.lenData*2);
} else if (actionStep.at == removeAction) { } else if (actionStep.at == removeAction) {
@@ -960,7 +999,7 @@ const Action &CellBuffer::UndoStep() {
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
delete []styledData; delete []styledData;
} }
return actionStep; uh.CompletedUndoStep();
} }
bool CellBuffer::CanRedo() { bool CellBuffer::CanRedo() {
@@ -971,8 +1010,12 @@ int CellBuffer::StartRedo() {
return uh.StartRedo(); return uh.StartRedo();
} }
const Action &CellBuffer::RedoStep() { const Action &CellBuffer::GetRedoStep() const {
const Action &actionStep = uh.RedoStep(); return uh.GetRedoStep();
}
void CellBuffer::PerformRedoStep() {
const Action &actionStep = uh.GetRedoStep();
if (actionStep.at == insertAction) { if (actionStep.at == insertAction) {
char *styledData = new char[actionStep.lenData * 2]; char *styledData = new char[actionStep.lenData * 2];
for (int i = 0; i < actionStep.lenData; i++) { for (int i = 0; i < actionStep.lenData; i++) {
@@ -984,7 +1027,7 @@ const Action &CellBuffer::RedoStep() {
} else if (actionStep.at == removeAction) { } else if (actionStep.at == removeAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData*2); BasicDeleteChars(actionStep.position, actionStep.lenData*2);
} }
return actionStep; uh.CompletedRedoStep();
} }
int CellBuffer::SetLineState(int line, int state) { int CellBuffer::SetLineState(int line, int state) {

View File

@@ -79,10 +79,11 @@ public:
int position; int position;
char *data; char *data;
int lenData; int lenData;
bool mayCoalesce;
Action(); Action();
~Action(); ~Action();
void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0); void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true);
void Destroy(); void Destroy();
void Grab(Action *source); void Grab(Action *source);
}; };
@@ -119,10 +120,12 @@ public:
// called that many times. Similarly for redo. // called that many times. Similarly for redo.
bool CanUndo() const; bool CanUndo() const;
int StartUndo(); int StartUndo();
const Action &UndoStep(); const Action &GetUndoStep() const;
void CompletedUndoStep();
bool CanRedo() const; bool CanRedo() const;
int StartRedo(); int StartRedo();
const Action &RedoStep(); const Action &GetRedoStep() const;
void CompletedRedoStep();
}; };
// Holder for an expandable array of characters that supports undo and line markers // Holder for an expandable array of characters that supports undo and line markers
@@ -171,7 +174,7 @@ public:
// Setting styles for positions outside the range of the buffer is safe and has no effect. // Setting styles for positions outside the range of the buffer is safe and has no effect.
// True is returned if the style of a character changed. // True is returned if the style of a character changed.
bool SetStyleAt(int position, char style, char mask=(char)0xff); bool SetStyleAt(int position, char style, char mask='\377');
bool SetStyleFor(int position, int length, char style, char mask); bool SetStyleFor(int position, int length, char style, char mask);
const char *DeleteChars(int position, int deleteLength); const char *DeleteChars(int position, int deleteLength);
@@ -206,10 +209,12 @@ public:
// called that many times. Similarly for redo. // called that many times. Similarly for redo.
bool CanUndo(); bool CanUndo();
int StartUndo(); int StartUndo();
const Action &UndoStep(); const Action &GetUndoStep() const;
void PerformUndoStep();
bool CanRedo(); bool CanRedo();
int StartRedo(); int StartRedo();
const Action &RedoStep(); const Action &GetRedoStep() const;
void PerformRedoStep();
int SetLineState(int line, int state); int SetLineState(int line, int state);
int GetLineState(int line); int GetLineState(int line);

View File

@@ -30,7 +30,6 @@ void ContractionState::MakeValid() const {
if (!valid) { if (!valid) {
// Could be cleverer by keeping the index of the last still valid entry // Could be cleverer by keeping the index of the last still valid entry
// rather than invalidating all. // rather than invalidating all.
int linePrev = -1;
int lineDisplay = 0; int lineDisplay = 0;
for (int line=0; line<linesInDoc; line++) { for (int line=0; line<linesInDoc; line++) {
lines[line].displayLine = lineDisplay; lines[line].displayLine = lineDisplay;
@@ -113,7 +112,7 @@ void ContractionState::InsertLines(int lineDoc, int lineCount) {
} }
linesInDoc += lineCount; linesInDoc += lineCount;
linesInDisplay += lineCount; linesInDisplay += lineCount;
for (int i = linesInDoc + 1; i >= lineDoc + lineCount; i--) { for (int i = linesInDoc; i >= lineDoc + lineCount; i--) {
lines[i].visible = lines[i - lineCount].visible; lines[i].visible = lines[i - lineCount].visible;
lines[i].expanded = lines[i - lineCount].expanded; lines[i].expanded = lines[i - lineCount].expanded;
} }
@@ -130,16 +129,18 @@ void ContractionState::DeleteLines(int lineDoc, int lineCount) {
linesInDisplay -= lineCount; linesInDisplay -= lineCount;
return; return;
} }
int delta = 0; int deltaDisplayed = 0;
for (int d=0;d<lineCount;d++) for (int d=0;d<lineCount;d++) {
if (lines[lineDoc+d].visible) if (lines[lineDoc+d].visible)
delta--; deltaDisplayed--;
}
for (int i = lineDoc; i < linesInDoc-lineCount; i++) { for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
if (i != 0) // Line zero is always visible
lines[i].visible = lines[i + lineCount].visible; lines[i].visible = lines[i + lineCount].visible;
lines[i].expanded = lines[i + lineCount].expanded; lines[i].expanded = lines[i + lineCount].expanded;
} }
linesInDoc -= lineCount; linesInDoc -= lineCount;
linesInDisplay += delta; linesInDisplay += deltaDisplayed;
valid = false; valid = false;
} }
@@ -154,6 +155,10 @@ bool ContractionState::GetVisible(int lineDoc) const {
} }
bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
if (lineDocStart == 0)
lineDocStart++;
if (lineDocStart > lineDocEnd)
return false;
if (size == 0) { if (size == 0) {
Grow(linesInDoc + growSize); Grow(linesInDoc + growSize);
} }

View File

@@ -32,7 +32,10 @@ Document::Document() {
} }
endStyled = 0; endStyled = 0;
enteredCount = 0; enteredCount = 0;
enteredReadOnlyCount = 0;
tabInChars = 8; tabInChars = 8;
indentInChars = 0;
useTabs = true;
watchers = 0; watchers = 0;
lenWatchers = 0; lenWatchers = 0;
} }
@@ -201,6 +204,10 @@ bool Document::IsCrLf(int pos) {
bool Document::IsDBCS(int pos) { bool Document::IsDBCS(int pos) {
#if PLAT_WIN #if PLAT_WIN
if (dbcsCodePage) { 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 // Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte. // not be a DBCS trail byte.
int startLine = pos; int startLine = pos;
@@ -215,12 +222,35 @@ bool Document::IsDBCS(int pos) {
startLine++; startLine++;
} }
} }
}
return false; return false;
#else #else
return false; return false;
#endif #endif
} }
int Document::LenChar(int pos) {
if (IsCrLf(pos)) {
return 2;
} else if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
if (ch < 0x80)
return 1;
int len = 2;
if (ch >= (0x80+0x40+0x20))
len = 3;
int lengthDoc = Length();
if ((pos + len) > lengthDoc)
return lengthDoc-pos;
else
return len;
} else if (IsDBCS(pos)) {
return 2;
} else {
return 1;
}
}
// Normalise a position so that it is not halfway through a two byte character. // Normalise a position so that it is not halfway through a two byte character.
// This can occur in two situations - // This can occur in two situations -
// When lines are terminated with \r\n pairs which should be treated as one character. // When lines are terminated with \r\n pairs which should be treated as one character.
@@ -252,6 +282,17 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
#if PLAT_WIN #if PLAT_WIN
if (dbcsCodePage) { if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
while ((pos > 0) && (pos < Length()) && (ch >= 0x80) && (ch < (0x80 + 0x40))) {
// ch is a trail byte
if (moveDir > 0)
pos++;
else
pos--;
ch = static_cast<unsigned char>(cb.CharAt(pos));
}
} else {
// Anchor DBCS calculations at start of line because start of line can // Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte. // not be a DBCS trail byte.
int startLine = pos; int startLine = pos;
@@ -277,6 +318,7 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos - 1; return pos - 1;
} }
} }
}
#endif #endif
return pos; return pos;
@@ -292,41 +334,60 @@ void Document::ModifiedAt(int pos) {
// Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number // Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number
void Document::DeleteChars(int pos, int len) { void Document::DeleteChars(int pos, int len) {
if (cb.IsReadOnly() && enteredReadOnlyCount==0) {
enteredReadOnlyCount++;
NotifyModifyAttempt();
enteredReadOnlyCount--;
}
if (enteredCount == 0) { if (enteredCount == 0) {
enteredCount++; enteredCount++;
if (cb.IsReadOnly())
NotifyModifyAttempt();
if (!cb.IsReadOnly()) { if (!cb.IsReadOnly()) {
NotifyModified(
DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_USER,
pos, len,
0, 0));
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
bool startSavePoint = cb.IsSavePoint(); bool startSavePoint = cb.IsSavePoint();
const char *text = cb.DeleteChars(pos*2, len * 2); const char *text = cb.DeleteChars(pos*2, len * 2);
if (startSavePoint && cb.IsCollectingUndo()) if (startSavePoint && cb.IsCollectingUndo())
NotifySavePoint(!startSavePoint); NotifySavePoint(!startSavePoint);
ModifiedAt(pos); ModifiedAt(pos);
int modFlags = SC_MOD_DELETETEXT | SC_PERFORMED_USER; NotifyModified(
DocModification mh(modFlags, pos, len, LinesTotal() - prevLinesTotal, text); DocModification(
NotifyModified(mh); SC_MOD_DELETETEXT | SC_PERFORMED_USER,
pos, len,
LinesTotal() - prevLinesTotal, text));
} }
enteredCount--; enteredCount--;
} }
} }
void Document::InsertStyledString(int position, char *s, int insertLength) { void Document::InsertStyledString(int position, char *s, int insertLength) {
if (cb.IsReadOnly() && enteredReadOnlyCount==0) {
enteredReadOnlyCount++;
NotifyModifyAttempt();
enteredReadOnlyCount--;
}
if (enteredCount == 0) { if (enteredCount == 0) {
enteredCount++; enteredCount++;
if (cb.IsReadOnly())
NotifyModifyAttempt();
if (!cb.IsReadOnly()) { if (!cb.IsReadOnly()) {
NotifyModified(
DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_USER,
position / 2, insertLength / 2,
0, 0));
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
bool startSavePoint = cb.IsSavePoint(); bool startSavePoint = cb.IsSavePoint();
const char *text = cb.InsertString(position, s, insertLength); const char *text = cb.InsertString(position, s, insertLength);
if (startSavePoint && cb.IsCollectingUndo()) if (startSavePoint && cb.IsCollectingUndo())
NotifySavePoint(!startSavePoint); NotifySavePoint(!startSavePoint);
ModifiedAt(position / 2); ModifiedAt(position / 2);
NotifyModified(
int modFlags = SC_MOD_INSERTTEXT | SC_PERFORMED_USER; DocModification(
DocModification mh(modFlags, position / 2, insertLength / 2, LinesTotal() - prevLinesTotal, text); SC_MOD_INSERTTEXT | SC_PERFORMED_USER,
NotifyModified(mh); position / 2, insertLength / 2,
LinesTotal() - prevLinesTotal, text));
} }
enteredCount--; enteredCount--;
} }
@@ -341,7 +402,15 @@ int Document::Undo() {
//Platform::DebugPrintf("Steps=%d\n", steps); //Platform::DebugPrintf("Steps=%d\n", steps);
for (int step=0; step<steps; step++) { for (int step=0; step<steps; step++) {
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
const Action &action = cb.UndoStep(); const Action &action = cb.GetUndoStep();
if (action.at == removeAction) {
NotifyModified(DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
int cellPosition = action.position / 2; int cellPosition = action.position / 2;
ModifiedAt(cellPosition); ModifiedAt(cellPosition);
newPos = cellPosition; newPos = cellPosition;
@@ -376,10 +445,17 @@ int Document::Redo() {
int steps = cb.StartRedo(); int steps = cb.StartRedo();
for (int step=0; step<steps; step++) { for (int step=0; step<steps; step++) {
int prevLinesTotal = LinesTotal(); int prevLinesTotal = LinesTotal();
const Action &action = cb.RedoStep(); const Action &action = cb.GetRedoStep();
int cellPosition = action.position / 2; if (action.at == insertAction) {
ModifiedAt(cellPosition); NotifyModified(DocModification(
newPos = cellPosition; SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
}
cb.PerformRedoStep();
ModifiedAt(action.position / 2);
newPos = action.position / 2;
int modFlags = SC_PERFORMED_REDO; int modFlags = SC_PERFORMED_REDO;
if (action.at == insertAction) { if (action.at == insertAction) {
@@ -390,7 +466,8 @@ int Document::Redo() {
} }
if (step == steps-1) if (step == steps-1)
modFlags |= SC_LASTSTEPINUNDOREDO; modFlags |= SC_LASTSTEPINUNDOREDO;
NotifyModified(DocModification(modFlags, cellPosition, action.lenData, NotifyModified(
DocModification(modFlags, action.position / 2, action.lenData,
LinesTotal() - prevLinesTotal, action.data)); LinesTotal() - prevLinesTotal, action.data));
} }
@@ -433,13 +510,7 @@ void Document::ChangeChar(int pos, char ch) {
} }
void Document::DelChar(int pos) { void Document::DelChar(int pos) {
if (IsCrLf(pos)) { DeleteChars(pos, LenChar(pos));
DeleteChars(pos, 2);
} else if (IsDBCS(pos)) {
DeleteChars(pos, 2);
} else if (pos < Length()) {
DeleteChars(pos, 1);
}
} }
int Document::DelCharBack(int pos) { int Document::DelCharBack(int pos) {
@@ -448,6 +519,10 @@ int Document::DelCharBack(int pos) {
} else if (IsCrLf(pos - 2)) { } else if (IsCrLf(pos - 2)) {
DeleteChars(pos - 2, 2); DeleteChars(pos - 2, 2);
return pos - 2; return pos - 2;
} else if (SC_CP_UTF8 == dbcsCodePage) {
int startChar = MovePositionOutsideChar(pos-1, -1, false);
DeleteChars(startChar, pos - startChar);
return startChar;
} else if (IsDBCS(pos - 1)) { } else if (IsDBCS(pos - 1)) {
DeleteChars(pos - 2, 2); DeleteChars(pos - 2, 2);
return pos - 2; return pos - 2;
@@ -457,27 +532,80 @@ int Document::DelCharBack(int pos) {
} }
} }
void Document::Indent(bool forwards, int lineBottom, int lineTop) { static bool isindentchar(char ch) {
if (forwards) { return (ch == ' ') || (ch == '\t');
// Indent by a tab }
for (int line = lineBottom; line >= lineTop; line--) {
InsertChar(LineStart(line), '\t'); static int NextTab(int pos, int tabSize) {
return ((pos / tabSize) + 1) * tabSize;
}
static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {
length--; // ensure space for \0
if (!insertSpaces) {
while ((indent >= tabSize) && (length > 0)) {
*linebuf++ = '\t';
indent -= tabSize;
length--;
} }
} else { }
while ((indent > 0) && (length > 0)) {
*linebuf++ = ' ';
indent--;
length--;
}
*linebuf = '\0';
}
int Document::GetLineIndentation(int line) {
int indent = 0;
if ((line >= 0) && (line < LinesTotal())) {
int lineStart = LineStart(line);
int length = Length();
for (int i=lineStart;i<length;i++) {
char ch = cb.CharAt(i);
if (ch == ' ')
indent++;
else if (ch == '\t')
indent = NextTab(indent, tabInChars);
else
return indent;
}
}
return indent;
}
void Document::SetLineIndentation(int line, int indent) {
int indentOfLine = GetLineIndentation(line);
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
char linebuf[1000];
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertString(thisLineStart, linebuf);
}
}
int Document::GetLineIndentPosition(int line) {
int pos = LineStart(line);
int length = Length();
while ((pos < length) && isindentchar(cb.CharAt(pos))) {
pos++;
}
return pos;
}
void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab // Dedent - suck white space off the front of the line to dedent by equivalent of a tab
for (int line = lineBottom; line >= lineTop; line--) { for (int line = lineBottom; line >= lineTop; line--) {
int ispc = 0; int indentOfLine = GetLineIndentation(line);
while (ispc < tabInChars && cb.CharAt(LineStart(line) + ispc) == ' ') if (forwards)
ispc++; SetLineIndentation(line, indentOfLine + IndentSize());
int posStartLine = LineStart(line); else
if (ispc == tabInChars) { SetLineIndentation(line, indentOfLine - IndentSize());
DeleteChars(posStartLine, ispc);
} else if (cb.CharAt(posStartLine + ispc) == '\t') {
DeleteChars(posStartLine, ispc + 1);
} else { // Hit a non-white
DeleteChars(posStartLine, ispc);
}
}
} }
} }
@@ -522,6 +650,8 @@ void Document::ConvertLineEnds(int eolModeSet) {
} }
bool Document::IsWordChar(unsigned char ch) { bool Document::IsWordChar(unsigned char ch) {
if ((SC_CP_UTF8 == dbcsCodePage) && (ch >0x80))
return true;
return wordchars[ch]; return wordchars[ch];
} }
@@ -588,16 +718,14 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv
// Compute actual search ranges needed // Compute actual search ranges needed
int lengthFind = strlen(s); int lengthFind = strlen(s);
int endSearch = 0; int endSearch = endPos;
if (startPos <= endPos) { if (startPos <= endPos) {
endSearch = endPos - lengthFind + 1; endSearch = endPos - lengthFind + 1;
} else {
endSearch = endPos;
} }
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind); //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
char firstChar = s[0]; char firstChar = s[0];
if (!caseSensitive) if (!caseSensitive)
firstChar = toupper(firstChar); firstChar = static_cast<char>(toupper(firstChar));
int pos = startPos; int pos = startPos;
while (forward ? (pos < endSearch) : (pos >= endSearch)) { while (forward ? (pos < endSearch) : (pos >= endSearch)) {
char ch = CharAt(pos); char ch = CharAt(pos);
@@ -646,15 +774,15 @@ void Document::ChangeCase(Range r, bool makeUpperCase) {
for (int pos=r.start; pos<r.end; pos++) { for (int pos=r.start; pos<r.end; pos++) {
char ch = CharAt(pos); char ch = CharAt(pos);
if (dbcsCodePage && IsDBCS(pos)) { if (dbcsCodePage && IsDBCS(pos)) {
pos++; pos += LenChar(pos);
} else { } else {
if (makeUpperCase) { if (makeUpperCase) {
if (islower(ch)) { if (islower(ch)) {
ChangeChar(pos, toupper(ch)); ChangeChar(pos, static_cast<char>(toupper(ch)));
} }
} else { } else {
if (isupper(ch)) { if (isupper(ch)) {
ChangeChar(pos, tolower(ch)); ChangeChar(pos, static_cast<char>(tolower(ch)));
} }
} }
} }
@@ -795,5 +923,3 @@ void Document::NotifyModified(DocModification mh) {
watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData); watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData);
} }
} }

View File

@@ -74,9 +74,10 @@ private:
CellBuffer cb; CellBuffer cb;
bool wordchars[256]; bool wordchars[256];
int stylingPos; int stylingPos;
int stylingMask; char stylingMask;
int endStyled; int endStyled;
int enteredCount; int enteredCount;
int enteredReadOnlyCount;
WatcherWithUserData *watchers; WatcherWithUserData *watchers;
int lenWatchers; int lenWatchers;
@@ -86,8 +87,11 @@ public:
int stylingBitsMask; int stylingBitsMask;
int eolMode; int eolMode;
// dbcsCodePage can also be SC_CP_UTF8 to enable UTF-8 mode
int dbcsCodePage; int dbcsCodePage;
int tabInChars; int tabInChars;
int indentInChars;
bool useTabs;
Document(); Document();
virtual ~Document(); virtual ~Document();
@@ -98,6 +102,7 @@ public:
int LineFromPosition(int pos); int LineFromPosition(int pos);
int ClampPositionIntoDocument(int pos); int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos); bool IsCrLf(int pos);
int LenChar(int pos);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document // Gateways to modifying document
@@ -115,6 +120,10 @@ public:
void EndUndoAction() { cb.EndUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); }
void SetSavePoint(); void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); } bool IsSavePoint() { return cb.IsSavePoint(); }
int GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line);
void Indent(bool forwards, int lineBottom, int lineTop); void Indent(bool forwards, int lineBottom, int lineTop);
void ConvertLineEnds(int eolModeSet); void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); } void SetReadOnly(bool set) { cb.SetReadOnly(set); }
@@ -183,6 +192,8 @@ private:
void NotifyModifyAttempt(); void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint); void NotifySavePoint(bool atSavePoint);
void NotifyModified(DocModification mh); void NotifyModified(DocModification mh);
int IndentSize() { return indentInChars ? indentInChars : tabInChars; }
}; };
// To optimise processing of document modifications by DocWatchers, a hint is passed indicating the // To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
@@ -209,6 +220,16 @@ public:
line(0), line(0),
foldLevelNow(0), foldLevelNow(0),
foldLevelPrev(0) {} foldLevelPrev(0) {}
DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
position(act.position / 2),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),
line(0),
foldLevelNow(0),
foldLevelPrev(0) {}
}; };
// A class that wants to receive notifications from a Document must be derived from DocWatcher // A class that wants to receive notifications from a Document must be derived from DocWatcher

View File

@@ -0,0 +1,174 @@
// SciTE - Scintilla based Text Editor
// Accessor.cxx - rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "SVector.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "CellBuffer.h"
#include "Scintilla.h"
#include "Document.h"
DocumentAccessor::~DocumentAccessor() {
}
bool DocumentAccessor::InternalIsLeadByte(char ch) {
#if PLAT_GTK
// TODO: support DBCS under GTK+
return false;
#elif PLAT_WIN
if (SC_CP_UTF8 == codePage)
// For lexing, all characters >= 0x80 are treated the
// same so none is considered a lead byte.
return false;
else
return IsDBCSLeadByteEx(codePage, ch);
#elif PLAT_WX
return false;
#endif
}
void DocumentAccessor::Fill(int position) {
if (lenDoc == -1)
lenDoc = pdoc->Length();
startPos = position - slopSize;
if (startPos + bufferSize > lenDoc)
startPos = lenDoc - bufferSize;
if (startPos < 0)
startPos = 0;
endPos = startPos + bufferSize;
if (endPos > lenDoc)
endPos = lenDoc;
pdoc->GetCharRange(buf, startPos, endPos-startPos);
buf[endPos-startPos] = '\0';
}
char DocumentAccessor::StyleAt(int position) {
return pdoc->StyleAt(position);
}
int DocumentAccessor::GetLine(int position) {
return pdoc->LineFromPosition(position);
}
int DocumentAccessor::LineStart(int line) {
return pdoc->LineStart(line);
}
int DocumentAccessor::LevelAt(int line) {
return pdoc->GetLevel(line);
}
int DocumentAccessor::Length() {
if (lenDoc == -1)
lenDoc = pdoc->Length();
return lenDoc;
}
int DocumentAccessor::GetLineState(int line) {
return pdoc->GetLineState(line);
}
int DocumentAccessor::SetLineState(int line, int state) {
return pdoc->SetLineState(line, state);
}
void DocumentAccessor::StartAt(unsigned int start, char chMask) {
pdoc->StartStyling(start, chMask);
}
void DocumentAccessor::StartSegment(unsigned int pos) {
startSeg = pos;
}
void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range
if (pos != startSeg - 1) {
if (pos < startSeg) {
Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos);
}
if (validLen + (pos - startSeg + 1) >= bufferSize)
Flush();
if (validLen + (pos - startSeg + 1) >= bufferSize) {
// Too big for buffer so send directly
pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
} else {
if (chAttr != chWhile)
chFlags = 0;
chAttr |= chFlags;
for (unsigned int i = startSeg; i <= pos; i++) {
styleBuf[validLen++] = static_cast<char>(chAttr);
}
}
}
startSeg = pos+1;
}
void DocumentAccessor::SetLevel(int line, int level) {
pdoc->SetLevel(line, level);
}
void DocumentAccessor::Flush() {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) {
pdoc->SetStyles(validLen, styleBuf);
validLen = 0;
}
}
int DocumentAccessor::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
// indentation compared to the previous line.
// 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;
bool inPrevPrefix = line > 0;
int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
while ((ch == ' ' || ch == '\t') && (pos < end)) {
if (inPrevPrefix) {
char chPrev = (*this)[posPrev++];
if (chPrev == ' ' || chPrev == '\t') {
if (chPrev != ch)
spaceFlags |= wsInconsistent;
} else {
inPrevPrefix = false;
}
}
if (ch == ' ') {
spaceFlags |= wsSpace;
indent++;
} else { // Tab
spaceFlags |= wsTab;
if (spaceFlags & wsSpace)
spaceFlags |= wsSpaceTab;
indent = (indent / 8 + 1) * 8;
}
ch = (*this)[++pos];
}
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
return indent | SC_FOLDLEVELWHITEFLAG;
else
return indent;
}

View File

@@ -0,0 +1,49 @@
// DocumentAccessor.h - implementation of BufferAccess and StylingAccess on a Scintilla rapid easy access to contents of a Scintilla
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
class Document;
class DocumentAccessor : public Accessor {
// Private so DocumentAccessor objects can not be copied
DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
DocumentAccessor &operator=(const DocumentAccessor &) { return *this; }
protected:
Document *pdoc;
PropSet &props;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
DocumentAccessor(Document *pdoc_, PropSet &props_) :
Accessor(), pdoc(pdoc_), props(props_),
lenDoc(-1), validLen(0), chFlags(0) {
}
~DocumentAccessor();
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
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);
}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
};

View File

@@ -69,6 +69,7 @@ Editor::Editor() {
xOffset = 0; xOffset = 0;
xCaretMargin = 50; xCaretMargin = 50;
horizontalScrollBarVisible = true;
currentPos = 0; currentPos = 0;
anchor = 0; anchor = 0;
@@ -189,7 +190,7 @@ bool IsControlCharacter(char ch) {
return ch >= 0 && ch < ' '; return ch >= 0 && ch < ' ';
} }
const char *ControlCharacterString(char ch) { const char *ControlCharacterString(unsigned char ch) {
const char *reps[] = { const char *reps[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
@@ -210,6 +211,7 @@ Point Editor::LocationFromPosition(unsigned int pos) {
//Platform::DebugPrintf("line=%d\n", line); //Platform::DebugPrintf("line=%d\n", line);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
Point pt; Point pt;
pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight?
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
@@ -252,6 +254,7 @@ int Editor::PositionFromLocation(Point pt) {
//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
LineLayout ll; LineLayout ll;
@@ -273,6 +276,7 @@ int Editor::PositionFromLineX(int line, int x) {
//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
Surface surface; Surface surface;
surface.Init(); surface.Init();
surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
unsigned int posLineStart = pdoc->LineStart(line); unsigned int posLineStart = pdoc->LineStart(line);
LineLayout ll; LineLayout ll;
@@ -485,7 +489,7 @@ void Editor::ScrollTo(int line) {
} }
} }
void Editor::ScrollText(int linesToMove) { void Editor::ScrollText(int /* linesToMove */) {
//Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove); //Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove);
Redraw(); Redraw();
} }
@@ -499,6 +503,19 @@ void Editor::HorizontalScrollTo(int xPos) {
Redraw(); Redraw();
} }
void Editor::MoveCaretInsideView() {
PRectangle rcClient = GetTextRectangle();
Point pt = LocationFromPosition(currentPos);
if (pt.y < rcClient.top) {
MovePositionTo(PositionFromLocation(
Point(lastXChosen, rcClient.top)));
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen()-1) * vs.lineHeight;
MovePositionTo(PositionFromLocation(
Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)));
}
}
void Editor::EnsureCaretVisible(bool useMargin) { void Editor::EnsureCaretVisible(bool useMargin) {
//Platform::DebugPrintf("EnsureCaretVisible %d\n", xOffset); //Platform::DebugPrintf("EnsureCaretVisible %d\n", xOffset);
PRectangle rcClient = GetTextRectangle(); PRectangle rcClient = GetTextRectangle();
@@ -652,11 +669,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
sprintf(number, "%d", line + 1); sprintf(number, "%d", line + 1);
if (foldFlags & 64) if (foldFlags & 64)
sprintf(number, "%X", pdoc->GetLevel(line)); sprintf(number, "%X", pdoc->GetLevel(line));
int xpos = 0;
PRectangle rcNumber=rcMarker; PRectangle rcNumber=rcMarker;
// Right justify // Right justify
int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number)); int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number));
xpos = rcNumber.right - width - 3; int xpos = rcNumber.right - width - 3;
rcNumber.left = xpos; rcNumber.left = xpos;
if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) { if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) {
surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font, surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font,
@@ -720,8 +736,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
styleByte = pdoc->StyleAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc);
if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
ll.chars[numCharsInLine] = chDoc; ll.chars[numCharsInLine] = chDoc;
ll.styles[numCharsInLine] = styleByte & styleMask; ll.styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
ll.indicators[numCharsInLine] = styleByte & ~styleMask; ll.indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
numCharsInLine++; numCharsInLine++;
} }
} }
@@ -1017,14 +1033,13 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
} }
//Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset);
Surface *surface = 0;
if (rcArea.right > vs.fixedColumnWidth) { if (rcArea.right > vs.fixedColumnWidth) {
Surface *surface = surfaceWindow;
if (bufferedDraw) { if (bufferedDraw) {
surface = &pixmapLine; surface = &pixmapLine;
} else {
surface = surfaceWindow;
} }
surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
int visibleLine = topLine + screenLinePaintFirst; int visibleLine = topLine + screenLinePaintFirst;
int line = cs.DocFromDisplay(visibleLine); int line = cs.DocFromDisplay(visibleLine);
@@ -1060,9 +1075,11 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// Highlight the current braces if any // Highlight the current braces if any
if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd))
ll.styles[braces[0] - posLineStart] = bracesMatchStyle; ll.styles[braces[0] - posLineStart] =
static_cast<char>(bracesMatchStyle);
if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd))
ll.styles[braces[1] - posLineStart] = bracesMatchStyle; ll.styles[braces[1] - posLineStart] =
static_cast<char>(bracesMatchStyle);
// Draw the line // Draw the line
if (cs.GetVisible(line)) if (cs.GetVisible(line))
@@ -1086,9 +1103,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// Draw the Caret // Draw the Caret
if (line == lineCaret) { if (line == lineCaret) {
int xposCaret = ll.positions[posCaret - posLineStart] + xStart; int offset = Platform::Minimum(posCaret - posLineStart, LineLayout::maxLineLength);
int xposCaret = ll.positions[offset] + xStart;
int widthOverstrikeCaret = int widthOverstrikeCaret =
ll.positions[posCaret - posLineStart + 1] - ll.positions[posCaret - posLineStart]; ll.positions[offset + 1] - ll.positions[offset];
if (posCaret == pdoc->Length()) // At end of document if (posCaret == pdoc->Length()) // At end of document
widthOverstrikeCaret = vs.aveCharWidth; widthOverstrikeCaret = vs.aveCharWidth;
if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line
@@ -1163,8 +1181,10 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) {
Surface *surface = new Surface(); Surface *surface = new Surface();
surface->Init(pfr->hdc); surface->Init(pfr->hdc);
surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
Surface *surfaceMeasure = new Surface(); Surface *surfaceMeasure = new Surface();
surfaceMeasure->Init(pfr->hdcTarget); surfaceMeasure->Init(pfr->hdcTarget);
surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage);
ViewStyle vsPrint(vs); ViewStyle vsPrint(vs);
@@ -1270,6 +1290,10 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) {
return endPosPrint; return endPosPrint;
} }
// Empty method is overridden on GTK+ to show / hide scrollbars
void Editor::ReconfigureScrollBars() {
}
void Editor::SetScrollBarsTo(PRectangle) { void Editor::SetScrollBarsTo(PRectangle) {
RefreshStyleData(); RefreshStyleData();
@@ -1295,6 +1319,13 @@ void Editor::SetScrollBars() {
} }
void Editor::AddChar(char ch) { void Editor::AddChar(char ch) {
char s[2];
s[0] = ch;
s[1] = '\0';
AddCharUTF(s, 1);
}
void Editor::AddCharUTF(char *s, unsigned int len) {
bool wasSelection = currentPos != anchor; bool wasSelection = currentPos != anchor;
ClearSelection(); ClearSelection();
if (inOverstrike && !wasSelection) { if (inOverstrike && !wasSelection) {
@@ -1304,11 +1335,11 @@ void Editor::AddChar(char ch) {
} }
} }
} }
pdoc->InsertChar(currentPos, ch); pdoc->InsertString(currentPos, s, len);
SetEmptySelection(currentPos + 1); SetEmptySelection(currentPos + len);
EnsureCaretVisible(); EnsureCaretVisible();
SetLastXChosen(); SetLastXChosen();
NotifyChar(ch); NotifyChar(s[0]);
} }
void Editor::ClearSelection() { void Editor::ClearSelection() {
@@ -1429,7 +1460,7 @@ void Editor::DelCharBack() {
void Editor::NotifyFocus(bool) { void Editor::NotifyFocus(bool) {
} }
void Editor::NotifyStyleNeeded(int endStyleNeeded) { void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
SCNotification scn; SCNotification scn;
scn.nmhdr.code = SCN_STYLENEEDED; scn.nmhdr.code = SCN_STYLENEEDED;
scn.position = endStyleNeeded; scn.position = endStyleNeeded;
@@ -1437,7 +1468,7 @@ void Editor::NotifyStyleNeeded(int endStyleNeeded) {
} }
void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) { void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) {
NotifyStyleNeeded(endStyleNeeded); NotifyStyleToNeeded(endStyleNeeded);
} }
void Editor::NotifyChar(char ch) { void Editor::NotifyChar(char ch) {
@@ -1581,6 +1612,11 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
braces[1] = endPos; braces[1] = endPos;
} }
} }
}
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
} }
if (mh.linesAdded != 0) { if (mh.linesAdded != 0) {
@@ -1588,7 +1624,6 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
// lineOfPos should be calculated in context of state before modification, shouldn't it // lineOfPos should be calculated in context of state before modification, shouldn't it
int lineOfPos = pdoc->LineFromPosition(mh.position); int lineOfPos = pdoc->LineFromPosition(mh.position);
if (mh.linesAdded > 0) { if (mh.linesAdded > 0) {
NotifyNeedShown(mh.position, mh.length);
cs.InsertLines(lineOfPos, mh.linesAdded); cs.InsertLines(lineOfPos, mh.linesAdded);
} else { } else {
cs.DeleteLines(lineOfPos, -mh.linesAdded); cs.DeleteLines(lineOfPos, -mh.linesAdded);
@@ -1642,7 +1677,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
} }
} }
void Editor::NotifyDeleted(Document *document, void *userData) { void Editor::NotifyDeleted(Document *, void *) {
/* Do nothing */ /* Do nothing */
} }
@@ -1806,6 +1841,10 @@ int Editor::KeyCommand(UINT iMessage) {
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y + vs.lineHeight)), true); Point(lastXChosen, pt.y + vs.lineHeight)), true);
break; break;
case SCI_LINESCROLLDOWN:
ScrollTo(topLine + 1);
MoveCaretInsideView();
break;
case SCI_LINEUP: case SCI_LINEUP:
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y - vs.lineHeight))); Point(lastXChosen, pt.y - vs.lineHeight)));
@@ -1814,6 +1853,10 @@ int Editor::KeyCommand(UINT iMessage) {
MovePositionTo(PositionFromLocation( MovePositionTo(PositionFromLocation(
Point(lastXChosen, pt.y - vs.lineHeight)), true); Point(lastXChosen, pt.y - vs.lineHeight)), true);
break; break;
case SCI_LINESCROLLUP:
ScrollTo(topLine - 1);
MoveCaretInsideView();
break;
case SCI_CHARLEFT: case SCI_CHARLEFT:
if (SelectionEmpty()) { if (SelectionEmpty()) {
MovePositionTo(MovePositionSoVisible(currentPos - 1, -1)); MovePositionTo(MovePositionSoVisible(currentPos - 1, -1));
@@ -1909,6 +1952,7 @@ int Editor::KeyCommand(UINT iMessage) {
break; break;
case SCI_DELETEBACK: case SCI_DELETEBACK:
DelCharBack(); DelCharBack();
SetLastXChosen();
EnsureCaretVisible(); EnsureCaretVisible();
break; break;
case SCI_TAB: case SCI_TAB:
@@ -1961,6 +2005,7 @@ int Editor::KeyCommand(UINT iMessage) {
int startWord = pdoc->NextWordStart(currentPos, -1); int startWord = pdoc->NextWordStart(currentPos, -1);
pdoc->DeleteChars(startWord, currentPos - startWord); pdoc->DeleteChars(startWord, currentPos - startWord);
MovePositionTo(startWord); MovePositionTo(startWord);
SetLastXChosen();
} }
break; break;
case SCI_DELWORDRIGHT: { case SCI_DELWORDRIGHT: {
@@ -2628,12 +2673,13 @@ char BraceOpposite(char ch) {
// TODO: should be able to extend styled region to find matching brace // TODO: should be able to extend styled region to find matching brace
// TODO: may need to make DBCS safe // TODO: may need to make DBCS safe
// so should be moved into Document // so should be moved into Document
int Editor::BraceMatch(int position, int maxReStyle) { int Editor::BraceMatch(int position, int /*maxReStyle*/) {
char chBrace = pdoc->CharAt(position); char chBrace = pdoc->CharAt(position);
char chSeek = BraceOpposite(chBrace); char chSeek = BraceOpposite(chBrace);
if (!chSeek) if (chSeek == '\0')
return - 1; return - 1;
char styBrace = pdoc->StyleAt(position) & pdoc->stylingBitsMask; char styBrace = static_cast<char>(
pdoc->StyleAt(position) & pdoc->stylingBitsMask);
int direction = -1; int direction = -1;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1; direction = 1;
@@ -2641,7 +2687,7 @@ int Editor::BraceMatch(int position, int maxReStyle) {
position = position + direction; position = position + direction;
while ((position >= 0) && (position < pdoc->Length())) { while ((position >= 0) && (position < pdoc->Length())) {
char chAtPos = pdoc->CharAt(position); char chAtPos = pdoc->CharAt(position);
char styAtPos = pdoc->StyleAt(position) & pdoc->stylingBitsMask; char styAtPos = static_cast<char>(pdoc->StyleAt(position) & pdoc->stylingBitsMask);
if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) { if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) {
if (chAtPos == chBrace) if (chAtPos == chBrace)
depth++; depth++;
@@ -2750,6 +2796,11 @@ void Editor::EnsureLineVisible(int line) {
} }
} }
static bool ValidMargin(WPARAM wParam) {
return wParam < ViewStyle::margins;
}
LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
//Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam);
@@ -3313,11 +3364,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break; break;
case SCI_STARTSTYLING: case SCI_STARTSTYLING:
pdoc->StartStyling(wParam, lParam); pdoc->StartStyling(wParam, static_cast<char>(lParam));
break; break;
case SCI_SETSTYLING: case SCI_SETSTYLING:
pdoc->SetStyleFor(wParam, lParam); pdoc->SetStyleFor(wParam, static_cast<char>(lParam));
break; break;
case SCI_SETSTYLINGEX: // Specify a complete styling buffer case SCI_SETSTYLINGEX: // Specify a complete styling buffer
@@ -3345,6 +3396,44 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
InvalidateStyleRedraw(); InvalidateStyleRedraw();
break; break;
case SCI_GETTABWIDTH:
return pdoc->tabInChars;
case SCI_SETINDENT:
pdoc->indentInChars = wParam;
InvalidateStyleRedraw();
break;
case SCI_GETINDENT:
return pdoc->indentInChars;
case SCI_SETUSETABS:
pdoc->useTabs = wParam;
InvalidateStyleRedraw();
break;
case SCI_GETUSETABS:
return pdoc->useTabs;
case SCI_SETLINEINDENTATION:
pdoc->SetLineIndentation(wParam, lParam);
break;
case SCI_GETLINEINDENTATION:
return pdoc->GetLineIndentation(wParam);
case SCI_GETLINEINDENTPOSITION:
return pdoc->GetLineIndentPosition(wParam);
case SCI_SETHSCROLLBAR :
horizontalScrollBarVisible = wParam;
SetScrollBars();
ReconfigureScrollBars();
break;
case SCI_GETHSCROLLBAR:
return horizontalScrollBarVisible;
case SCI_SETCODEPAGE: case SCI_SETCODEPAGE:
pdoc->dbcsCodePage = wParam; pdoc->dbcsCodePage = wParam;
break; break;
@@ -3416,53 +3505,53 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
return -1; return -1;
case SCI_SETMARGINTYPEN: case SCI_SETMARGINTYPEN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL); vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL);
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINTYPEN: case SCI_GETMARGINTYPEN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER; return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER;
else else
return 0; return 0;
case SCI_SETMARGINWIDTHN: case SCI_SETMARGINWIDTHN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].width = lParam; vs.ms[wParam].width = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINWIDTHN: case SCI_GETMARGINWIDTHN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].width; return vs.ms[wParam].width;
else else
return 0; return 0;
case SCI_SETMARGINMASKN: case SCI_SETMARGINMASKN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].mask = lParam; vs.ms[wParam].mask = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINMASKN: case SCI_GETMARGINMASKN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].mask; return vs.ms[wParam].mask;
else else
return 0; return 0;
case SCI_SETMARGINSENSITIVEN: case SCI_SETMARGINSENSITIVEN:
if (wParam >= 0 && wParam < ViewStyle::margins) { if (ValidMargin(wParam)) {
vs.ms[wParam].sensitive = lParam; vs.ms[wParam].sensitive = lParam;
InvalidateStyleRedraw(); InvalidateStyleRedraw();
} }
break; break;
case SCI_GETMARGINSENSITIVEN: case SCI_GETMARGINSENSITIVEN:
if (wParam >= 0 && wParam < ViewStyle::margins) if (ValidMargin(wParam))
return vs.ms[wParam].sensitive ? 1 : 0; return vs.ms[wParam].sensitive ? 1 : 0;
else else
return 0; return 0;
@@ -3606,7 +3695,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
case SCI_SEARCHNEXT: case SCI_SEARCHNEXT:
case SCI_SEARCHPREV: case SCI_SEARCHPREV:
return SearchText(iMessage, wParam, lParam); return SearchText(iMessage, wParam, lParam);
break;
case SCI_SETCARETPOLICY: case SCI_SETCARETPOLICY:
caretPolicy = wParam; caretPolicy = wParam;
@@ -3745,6 +3833,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
case SCI_LINETRANSPOSE: case SCI_LINETRANSPOSE:
case SCI_LOWERCASE: case SCI_LOWERCASE:
case SCI_UPPERCASE: case SCI_UPPERCASE:
case SCI_LINESCROLLDOWN:
case SCI_LINESCROLLUP:
return KeyCommand(iMessage); return KeyCommand(iMessage);
case SCI_BRACEHIGHLIGHT: case SCI_BRACEHIGHLIGHT:
@@ -3808,6 +3898,9 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
SetSelection(currentPos, anchor); // Ensure selection inside document SetSelection(currentPos, anchor); // Ensure selection inside document
return 0; return 0;
case SCI_SELECTIONISRECTANGLE:
return (selType == selRectangle) ? 1 : 0;
#ifdef MACRO_SUPPORT #ifdef MACRO_SUPPORT
case SCI_STARTRECORD: case SCI_STARTRECORD:
recordingMacro = 1; recordingMacro = 1;

View File

@@ -38,6 +38,9 @@ public:
}; };
class Editor : public DocWatcher { class Editor : public DocWatcher {
// Private so Editor objects can not be copied
Editor(const Editor &) : DocWatcher() {}
Editor &operator=(const Editor &) { return *this; }
protected: // ScintillaBase subclass needs access to much of Editor protected: // ScintillaBase subclass needs access to much of Editor
// On GTK+, Scintilla is a container widget holding two scroll bars and a drawing area // On GTK+, Scintilla is a container widget holding two scroll bars and a drawing area
@@ -61,13 +64,14 @@ protected: // ScintillaBase subclass needs access to much of Editor
int xOffset; // Horizontal scrolled amount in pixels int xOffset; // Horizontal scrolled amount in pixels
int xCaretMargin; // Ensure this many pixels visible on both sides of caret int xCaretMargin; // Ensure this many pixels visible on both sides of caret
bool horizontalScrollBarVisible;
Surface pixmapLine; Surface pixmapLine;
Surface pixmapSelMargin; Surface pixmapSelMargin;
Surface pixmapSelPattern; Surface pixmapSelPattern;
// Intellimouse support - currently only implemented for Windows // Intellimouse support - currently only implemented for Windows
unsigned int ucWheelScrollLines; unsigned int ucWheelScrollLines;
short cWheelDelta; //wheel delta from roll int cWheelDelta; //wheel delta from roll
KeyMap kmap; KeyMap kmap;
@@ -171,6 +175,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void ScrollTo(int line); void ScrollTo(int line);
virtual void ScrollText(int linesToMove); virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos); void HorizontalScrollTo(int xPos);
void MoveCaretInsideView();
void EnsureCaretVisible(bool useMargin=true); void EnsureCaretVisible(bool useMargin=true);
void ShowCaretAtCurrentPosition(); void ShowCaretAtCurrentPosition();
void DropCaret(); void DropCaret();
@@ -186,10 +191,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void SetVerticalScrollPos() = 0; virtual void SetVerticalScrollPos() = 0;
virtual void SetHorizontalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0;
virtual bool ModifyScrollBars(int nMax, int nPage) = 0; virtual bool ModifyScrollBars(int nMax, int nPage) = 0;
virtual void ReconfigureScrollBars();
void SetScrollBarsTo(PRectangle rsClient); void SetScrollBarsTo(PRectangle rsClient);
void SetScrollBars(); void SetScrollBars();
virtual void AddChar(char ch); void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len);
void ClearSelection(); void ClearSelection();
void ClearAll(); void ClearAll();
void Cut(); void Cut();
@@ -207,7 +214,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0; virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleNeeded(int endStyleNeeded); virtual void NotifyStyleToNeeded(int endStyleNeeded);
void NotifyChar(char ch); void NotifyChar(char ch);
void NotifySavePoint(bool isSavePoint); void NotifySavePoint(bool isSavePoint);
void NotifyModifyAttempt(); void NotifyModifyAttempt();

View File

@@ -61,56 +61,58 @@ UINT KeyMap::Find(int key, int modifiers) {
} }
KeyToCommand KeyMap::MapDefault[] = { KeyToCommand KeyMap::MapDefault[] = {
VK_DOWN, SCI_NORM, SCI_LINEDOWN, {VK_DOWN, SCI_NORM, SCI_LINEDOWN},
VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, {VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
VK_UP, SCI_NORM, SCI_LINEUP, {VK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, {VK_UP, SCI_NORM, SCI_LINEUP},
VK_LEFT, SCI_NORM, SCI_CHARLEFT, {VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND, {VK_UP, SCI_CTRL, SCI_LINESCROLLUP},
VK_LEFT, SCI_CTRL, SCI_WORDLEFT, {VK_LEFT, SCI_NORM, SCI_CHARLEFT},
VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND, {VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, {VK_LEFT, SCI_CTRL, SCI_WORDLEFT},
VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, {VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, {VK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, {VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
VK_HOME, SCI_NORM, SCI_VCHOME, {VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, {VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, {VK_HOME, SCI_NORM, SCI_VCHOME},
VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, {VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND},
VK_END, SCI_NORM, SCI_LINEEND, {VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
VK_END, SCI_SHIFT, SCI_LINEENDEXTEND, {VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
VK_END, SCI_CTRL, SCI_DOCUMENTEND, {VK_END, SCI_NORM, SCI_LINEEND},
VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND, {VK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
VK_PRIOR, SCI_NORM, SCI_PAGEUP, {VK_END, SCI_CTRL, SCI_DOCUMENTEND},
VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, {VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
VK_NEXT, SCI_NORM, SCI_PAGEDOWN, {VK_PRIOR, SCI_NORM, SCI_PAGEUP},
VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, {VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
VK_DELETE, SCI_NORM, WM_CLEAR, {VK_NEXT, SCI_NORM, SCI_PAGEDOWN},
VK_DELETE, SCI_SHIFT, WM_CUT, {VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND},
VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT, {VK_DELETE, SCI_NORM, WM_CLEAR},
VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, {VK_DELETE, SCI_SHIFT, WM_CUT},
VK_INSERT, SCI_SHIFT, WM_PASTE, {VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT},
VK_INSERT, SCI_CTRL, WM_COPY, {VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE},
VK_ESCAPE, SCI_NORM, SCI_CANCEL, {VK_INSERT, SCI_SHIFT, WM_PASTE},
VK_BACK, SCI_NORM, SCI_DELETEBACK, {VK_INSERT, SCI_CTRL, WM_COPY},
VK_BACK, SCI_CTRL, SCI_DELWORDLEFT, {VK_ESCAPE, SCI_NORM, SCI_CANCEL},
'Z', SCI_CTRL, WM_UNDO, {VK_BACK, SCI_NORM, SCI_DELETEBACK},
'Y', SCI_CTRL, SCI_REDO, {VK_BACK, SCI_CTRL, SCI_DELWORDLEFT},
'X', SCI_CTRL, WM_CUT, {'Z', SCI_CTRL, WM_UNDO},
'C', SCI_CTRL, WM_COPY, {'Y', SCI_CTRL, SCI_REDO},
'V', SCI_CTRL, WM_PASTE, {'X', SCI_CTRL, WM_CUT},
'A', SCI_CTRL, SCI_SELECTALL, {'C', SCI_CTRL, WM_COPY},
VK_TAB, SCI_NORM, SCI_TAB, {'V', SCI_CTRL, WM_PASTE},
VK_TAB, SCI_SHIFT, SCI_BACKTAB, {'A', SCI_CTRL, SCI_SELECTALL},
VK_RETURN, SCI_NORM, SCI_NEWLINE, {VK_TAB, SCI_NORM, SCI_TAB},
VK_ADD, SCI_CTRL, SCI_ZOOMIN, {VK_TAB, SCI_SHIFT, SCI_BACKTAB},
VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT, {VK_RETURN, SCI_NORM, SCI_NEWLINE},
{VK_ADD, SCI_CTRL, SCI_ZOOMIN},
{VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
//'L', SCI_CTRL, SCI_FORMFEED, //'L', SCI_CTRL, SCI_FORMFEED,
'L', SCI_CTRL, SCI_LINECUT, {'L', SCI_CTRL, SCI_LINECUT},
'L', SCI_CSHIFT, SCI_LINEDELETE, {'L', SCI_CSHIFT, SCI_LINEDELETE},
'T', SCI_CTRL, SCI_LINETRANSPOSE, {'T', SCI_CTRL, SCI_LINETRANSPOSE},
'U', SCI_CTRL, SCI_LOWERCASE, {'U', SCI_CTRL, SCI_LOWERCASE},
'U', SCI_CSHIFT, SCI_UPPERCASE, {'U', SCI_CSHIFT, SCI_UPPERCASE},
0,0,0, {0,0,0},
}; };

View File

@@ -26,7 +26,7 @@ LexerModule::LexerModule(int language_, LexerFunction fn_) :
} }
void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle, void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle,
int language, WordList *keywordlists[], StylingContext &styler) { int language, WordList *keywordlists[], Accessor &styler) {
LexerModule *lm = base; LexerModule *lm = base;
while (lm) { while (lm) {
if (lm->language == language) { if (lm->language == language) {
@@ -43,5 +43,3 @@ void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle,
styler.ColourTo(startPos + lengthDoc - 1, 0); styler.ColourTo(startPos + lengthDoc - 1, 0);
} }
} }

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
bool wordIsUUID = false; bool wordIsUUID = false;
@@ -39,29 +39,37 @@ static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keyw
} }
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
StylingContext &styler) { Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
styler.StartAt(startPos); styler.StartAt(startPos);
bool fold = styler.GetPropSet().GetInt("fold"); bool fold = styler.GetPropertyInt("fold");
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev; int levelCurrent = levelPrev;
int state = initStyle; int state = initStyle;
if (state == SCE_C_STRINGEOL) // Does not leak onto next line
state = SCE_C_DEFAULT;
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length; unsigned int lengthDoc = startPos + length;
int visChars = 0; int visChars = 0;
styler.StartSegment(startPos); styler.StartSegment(startPos);
bool lastWordWasUUID = false; bool lastWordWasUUID = false;
for (unsigned int i = startPos; i <= lengthDoc; i++) { for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
// End of line
if (state == SCE_C_STRINGEOL) {
styler.ColourTo(i, state);
state = SCE_C_DEFAULT;
}
if (fold) {
int lev = levelPrev; int lev = levelPrev;
if (visChars == 0) if (visChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
@@ -72,6 +80,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
visChars = 0; visChars = 0;
levelPrev = levelCurrent; levelPrev = levelCurrent;
} }
}
if (!isspace(ch)) if (!isspace(ch))
visChars++; visChars++;
@@ -82,12 +91,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
continue; continue;
} }
if (state == SCE_C_STRINGEOL) {
if (ch != '\r' && ch != '\n') {
styler.ColourTo(i-1, state);
state = SCE_C_DEFAULT;
}
}
if (state == SCE_C_DEFAULT) { if (state == SCE_C_DEFAULT) {
if (iswordstart(ch)) { if (iswordstart(ch)) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, state);
@@ -148,7 +151,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else { } else {
if (state == SCE_C_PREPROCESSOR) { if (state == SCE_C_PREPROCESSOR) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, state);
state = SCE_C_DEFAULT; state = SCE_C_DEFAULT;
} }
@@ -163,7 +166,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_COMMENTDOC) { } else if (state == SCE_C_COMMENTDOC) {
if (ch == '/' && chPrev == '*') { if (ch == '/' && chPrev == '*') {
if (((i > styler.GetStartSegment() + 3) || ( if (((i > styler.GetStartSegment() + 2) || (
(initStyle == SCE_C_COMMENTDOC) && (initStyle == SCE_C_COMMENTDOC) &&
(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
styler.ColourTo(i, state); styler.ColourTo(i, state);
@@ -177,7 +180,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_STRING) { } else if (state == SCE_C_STRING) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL; state = SCE_C_STRINGEOL;
} else if (ch == '\\') { } else if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
@@ -194,7 +197,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
} }
} else if (state == SCE_C_CHARACTER) { } else if (state == SCE_C_CHARACTER) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
styler.ColourTo(i-1, state); styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL; state = SCE_C_STRINGEOL;
} else if (ch == '\\') { } else if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') {

View File

@@ -18,11 +18,11 @@
#include "SciLexer.h" #include "SciLexer.h"
enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython };
static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, int prevValue) {
char s[100]; char s[100];
s[0] = '\0'; s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
//Platform::DebugPrintf("Scripting indicator [%s]\n", s); //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
@@ -38,7 +38,7 @@ static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, u
return prevValue; return prevValue;
} }
static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') ||
(styler[start] == '-') || (styler[start] == '#'); (styler[start] == '-') || (styler[start] == '#');
char chAttr = SCE_H_ATTRIBUTEUNKNOWN; char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
@@ -48,7 +48,7 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
char s[100]; char s[100];
s[0] = '\0'; s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
if (keywords.InList(s)) if (keywords.InList(s))
@@ -58,14 +58,14 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
} }
static int classifyTagHTML(unsigned int start, unsigned int end, static int classifyTagHTML(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
// Copy after the '<' // Copy after the '<'
unsigned int i = 0; unsigned int i = 0;
for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) {
char ch = styler[cPos]; char ch = styler[cPos];
if (ch != '<') if (ch != '<')
s[i++] = tolower(ch); s[i++] = static_cast<char>(tolower(ch));
} }
s[i] = '\0'; s[i] = '\0';
char chAttr = SCE_H_TAGUNKNOWN; char chAttr = SCE_H_TAGUNKNOWN;
@@ -86,7 +86,7 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
} }
static void classifyWordHTJS(unsigned int start, unsigned int end, static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -104,7 +104,7 @@ static void classifyWordHTJS(unsigned int start, unsigned int end,
} }
static void classifyWordHTJSA(unsigned int start, unsigned int end, static void classifyWordHTJSA(unsigned int start, unsigned int end,
WordList &keywords, StylingContext &styler) { WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -121,11 +121,11 @@ static void classifyWordHTJSA(unsigned int start, unsigned int end,
styler.ColourTo(end, chAttr); styler.ColourTo(end, chAttr);
} }
static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_HB_IDENTIFIER; char chAttr = SCE_HB_IDENTIFIER;
@@ -145,11 +145,11 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT; return SCE_HB_DEFAULT;
} }
static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_HBA_IDENTIFIER; char chAttr = SCE_HBA_IDENTIFIER;
@@ -169,7 +169,7 @@ static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &key
return SCE_HBA_DEFAULT; return SCE_HBA_DEFAULT;
} }
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -189,7 +189,7 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
strcpy(prevWord, s); strcpy(prevWord, s);
} }
static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -226,7 +226,7 @@ static bool isLineEnd(char ch) {
} }
static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
StylingContext &styler) { Accessor &styler) {
WordList &keywords=*keywordlists[0]; WordList &keywords=*keywordlists[0];
WordList &keywords2=*keywordlists[1]; WordList &keywords2=*keywordlists[1];
@@ -261,7 +261,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
char chPrev2 = ' '; char chPrev2 = ' ';
styler.StartSegment(startPos); styler.StartSegment(startPos);
int lengthDoc = startPos + length; int lengthDoc = startPos + length;
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
char ch = styler[i]; char ch = styler[i];
char chNext = styler.SafeGetCharAt(i + 1); char chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &styler) { static void ColouriseBatchLine(char *lineBuffer, int endLine, Accessor &styler) {
if (0 == strncmp(lineBuffer, "REM", 3)) { if (0 == strncmp(lineBuffer, "REM", 3)) {
styler.ColourTo(endLine, 1); styler.ColourTo(endLine, 1);
} else if (0 == strncmp(lineBuffer, "rem", 3)) { } else if (0 == strncmp(lineBuffer, "rem", 3)) {
@@ -33,7 +33,7 @@ static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &st
} }
} }
static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -49,7 +49,7 @@ static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *
ColouriseBatchLine(lineBuffer, startPos + length, styler); ColouriseBatchLine(lineBuffer, startPos + length, styler);
} }
static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, StylingContext &styler) { static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, Accessor &styler) {
int i = 0; int i = 0;
while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces
i++; i++;
@@ -75,7 +75,7 @@ static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine,
} }
} }
static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -96,7 +96,7 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler); ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler);
} }
static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) {
int i = 0; int i = 0;
while (isspace(lineBuffer[i]) && (i < lengthLine)) while (isspace(lineBuffer[i]) && (i < lengthLine))
i++; i++;
@@ -107,7 +107,7 @@ static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, Styl
} }
} }
static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
@@ -123,7 +123,7 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler); ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler);
} }
static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) {
if (lineBuffer[0] == '>') { if (lineBuffer[0] == '>') {
// Command or return status // Command or return status
styler.ColourTo(endPos, 4); styler.ColourTo(endPos, 4);
@@ -158,7 +158,6 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
state = 14; state = 14;
} else if (state == 11 && lineBuffer[i] == ')') { } else if (state == 11 && lineBuffer[i] == ')') {
state = 12; state = 12;
break;
} else if (state == 12 && lineBuffer[i] == ':') { } else if (state == 12 && lineBuffer[i] == ':') {
state = 13; state = 13;
} else if (state == 14 && lineBuffer[i] == ')') { } else if (state == 14 && lineBuffer[i] == ')') {
@@ -170,7 +169,7 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
} }
if (state == 3) { if (state == 3) {
styler.ColourTo(endPos, 2); styler.ColourTo(endPos, 2);
} else if ((state == 14) || (state == 15)) { } else if ((state == 13) || (state == 14) || (state == 15)) {
styler.ColourTo(endPos, 3); styler.ColourTo(endPos, 3);
} else { } else {
styler.ColourTo(endPos, 0); styler.ColourTo(endPos, 0);
@@ -178,7 +177,7 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos,
} }
} }
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024]; char lineBuffer[1024];
styler.StartAt(startPos); styler.StartAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);

View File

@@ -31,7 +31,7 @@ inline bool isPerlOperator(char ch) {
return false; return false;
} }
static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -54,7 +54,7 @@ static bool isEndVar(char ch) {
ch != '_' && ch != '\''; ch != '_' && ch != '\'';
} }
static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) { if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
return false; return false;
} }
@@ -67,16 +67,6 @@ static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *
return true; return true;
} }
static bool isOKQuote(char ch) {
if (isalnum(ch))
return false;
if (isspace(ch))
return false;
if (iscntrl(ch))
return false;
return true;
}
static char opposite(char ch) { static char opposite(char ch) {
if (ch == '(') if (ch == '(')
return ')'; return ')';
@@ -90,7 +80,7 @@ static char opposite(char ch) {
} }
static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
// Lexer for perl often has to backtrack to start of current style to determine // Lexer for perl often has to backtrack to start of current style to determine
// which characters are being used as quotes, how deeply nested is the // which characters are being used as quotes, how deeply nested is the
@@ -120,7 +110,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);

View File

@@ -17,7 +17,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { static void ClassifyWordPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]); bool wordIsNumber = isdigit(styler[start]);
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
@@ -37,56 +37,70 @@ static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywo
strcpy(prevWord, s); strcpy(prevWord, s);
} }
static bool IsPyComment(StylingContext &styler, int pos, int len) { static bool IsPyComment(Accessor &styler, int pos, int len) {
return len>0 && styler[pos]=='#'; return len>0 && styler[pos]=='#';
} }
static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
int lengthDoc = startPos + length;
// Backtrack to previous line in case need to fix its fold status or tab whinging
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
// Python uses a different mask because bad indentation is marked by oring with 32 // Python uses a different mask because bad indentation is marked by oring with 32
styler.StartAt(startPos, 127); styler.StartAt(startPos, 127);
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
//Platform::DebugPrintf("Python coloured\n"); bool fold = styler.GetPropertyInt("fold");
bool fold = styler.GetPropSet().GetInt("fold"); int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level");
char prevWord[200]; char prevWord[200];
prevWord[0] = '\0'; prevWord[0] = '\0';
if (length == 0) if (length == 0)
return ; return ;
int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0; int spaceFlags = 0;
// TODO: Need to check previous line for indentation for both folding and bad indentation
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
int state = initStyle & 31; int state = initStyle & 31;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
indentCurrent |= SC_FOLDLEVELWHITEFLAG;
char chPrev = ' '; char chPrev = ' ';
char chPrev2 = ' '; char chPrev2 = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
char chNext2 = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
int lengthDoc = startPos + length;
bool atStartLine = true; bool atStartLine = true;
for (int i = startPos; i <= lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
if (atStartLine) { if (atStartLine) {
char chBad = static_cast<char>(64);
char chGood = static_cast<char>(0);
char chFlags = chGood;
if (whingeLevel == 1) { if (whingeLevel == 1) {
styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
} else if (whingeLevel == 2) { } else if (whingeLevel == 2) {
styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
} else if (whingeLevel == 3) { } else if (whingeLevel == 3) {
styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
} else if (whingeLevel == 4) { } else if (whingeLevel == 4) {
styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); chFlags = (spaceFlags & wsTab) ? chBad : chGood;
} }
styler.SetFlags(chFlags, static_cast<char>(state));
atStartLine = false; atStartLine = false;
} }
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
chNext2 = styler.SafeGetCharAt(i + 2); char chNext2 = styler.SafeGetCharAt(i + 2);
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
@@ -97,6 +111,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
int lev = indentCurrent; int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment); int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment);
if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
indentNext |= SC_FOLDLEVELWHITEFLAG;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers // Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
@@ -167,7 +183,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
} }
} else if (state == SCE_P_WORD) { } else if (state == SCE_P_WORD) {
if (!iswordchar(ch)) { if (!iswordchar(ch)) {
classifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); ClassifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
state = SCE_P_DEFAULT; state = SCE_P_DEFAULT;
if (ch == '#') { if (ch == '#') {
state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
@@ -245,7 +261,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
chPrev = ch; chPrev = ch;
} }
if (state == SCE_P_WORD) { if (state == SCE_P_WORD) {
classifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord); ClassifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord);
} else { } else {
styler.ColourTo(lengthDoc, state); styler.ColourTo(lengthDoc, state);
} }

View File

@@ -17,11 +17,11 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = toupper(styler[start + i]); s[i] = static_cast<char>(toupper(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_C_IDENTIFIER; char chAttr = SCE_C_IDENTIFIER;
@@ -35,29 +35,27 @@ static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keyw
} }
static void ColouriseSQLDoc(unsigned int startPos, int length, static void ColouriseSQLDoc(unsigned int startPos, int length,
int initStyle, WordList *keywordlists[], StylingContext &styler) { int initStyle, WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
styler.StartAt(startPos); styler.StartAt(startPos);
bool fold = styler.GetPropSet().GetInt("fold"); bool fold = styler.GetPropertyInt("fold");
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0; int spaceFlags = 0;
int indentCurrent = 0;
int state = initStyle; int state = initStyle;
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
styler.StartSegment(startPos); styler.StartSegment(startPos);
unsigned int lengthDoc = startPos + length; unsigned int lengthDoc = startPos + length;
bool prevCr = false; for (unsigned int i = startPos; i < lengthDoc; i++) {
for (unsigned int i = startPos; i <= lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
int lev = indentCurrent; int lev = indentCurrent;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers // Only non whitespace lines can be headers

View File

@@ -17,12 +17,12 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100]; char s[100];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = tolower(styler[start + i]); s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0'; s[i + 1] = '\0';
} }
char chAttr = SCE_C_DEFAULT; char chAttr = SCE_C_DEFAULT;
@@ -43,7 +43,7 @@ static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywor
} }
static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], StylingContext &styler) { WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];

View File

@@ -51,20 +51,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {
} else if (markType == SC_MARK_PLUS) { } else if (markType == SC_MARK_PLUS) {
int armSize = dimOn2-2; int armSize = dimOn2-2;
Point xpts[] = {
Point(centreX - armSize, centreY),
Point(centreX, centreY),
Point(centreX, centreY - armSize),
Point(centreX, centreY - armSize),
Point(centreX, centreY),
Point(centreX + armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX, centreY),
Point(centreX, centreY + armSize),
Point(centreX, centreY + armSize),
Point(centreX, centreY),
Point(centreX - armSize, centreY),
};
Point pts[] = { Point pts[] = {
Point(centreX - armSize, centreY - 1), Point(centreX - armSize, centreY - 1),
Point(centreX - 1, centreY - 1), Point(centreX - 1, centreY - 1),
@@ -90,12 +76,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {
Point(centreX + armSize, centreY +1), Point(centreX + armSize, centreY +1),
Point(centreX - armSize, centreY + 1), Point(centreX - armSize, centreY + 1),
}; };
Point xpts[] = {
Point(centreX - armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX + armSize, centreY),
Point(centreX - armSize, centreY),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
fore.allocated, back.allocated); fore.allocated, back.allocated);

View File

@@ -39,7 +39,7 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
fpc++; fpc++;
lenData--; lenData--;
} }
*s++ = '\0'; *s = '\0';
return true; return true;
} }
} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) { } else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
@@ -122,7 +122,7 @@ SString PropSet::Get(const char *key) {
int PropSet::GetInt(const char *key, int defaultValue) { int PropSet::GetInt(const char *key, int defaultValue) {
SString val = Get(key); SString val = Get(key);
if (val.length()) if (val.length())
return Get(key).value(); return val.value();
else else
return defaultValue; return defaultValue;
} }
@@ -376,7 +376,7 @@ bool WordList::InList(const char *s) {
for (int i = 0; words[i][0]; i++) for (int i = 0; words[i][0]; i++)
len++; len++;
SortWordList(words, len); SortWordList(words, len);
for (int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1; starts[k] = -1;
for (int l = len - 1; l >= 0; l--) { for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0]; unsigned char indexChar = words[l][0];

View File

@@ -15,6 +15,8 @@
#include "SciLexer.h" #include "SciLexer.h"
#include "PropSet.h" #include "PropSet.h"
#include "Accessor.h" #include "Accessor.h"
#include "WindowAccessor.h"
#include "DocumentAccessor.h"
#include "KeyWords.h" #include "KeyWords.h"
#endif #endif
#include "ContractionState.h" #include "ContractionState.h"
@@ -50,11 +52,11 @@ void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) {
ct.RefreshColourPalette(pal, want); ct.RefreshColourPalette(pal, want);
} }
void ScintillaBase::AddChar(char ch) { void ScintillaBase::AddCharUTF(char *s, unsigned int len) {
bool acActiveBeforeCharAdded = ac.Active(); bool acActiveBeforeCharAdded = ac.Active();
Editor::AddChar(ch); Editor::AddCharUTF(s, len);
if (acActiveBeforeCharAdded) if (acActiveBeforeCharAdded)
AutoCompleteChanged(ch); AutoCompleteChanged(s[0]);
} }
void ScintillaBase::Command(int cmdId) { void ScintillaBase::Command(int cmdId) {
@@ -276,7 +278,8 @@ void ScintillaBase::Colourise(int start, int end) {
end = lengthDoc; end = lengthDoc;
int len = end - start; int len = end - start;
StylingContext styler(wMain.GetID(), props); //WindowAccessor styler(wMain.GetID(), props);
DocumentAccessor styler(pdoc, props);
int styleStart = 0; int styleStart = 0;
if (start > 0) if (start > 0)
@@ -288,7 +291,7 @@ void ScintillaBase::Colourise(int start, int end) {
} }
#endif #endif
void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded) { void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
#ifdef SCI_LEXER #ifdef SCI_LEXER
if (lexLanguage != SCLEX_CONTAINER) { if (lexLanguage != SCLEX_CONTAINER) {
int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0); int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0);
@@ -298,7 +301,7 @@ void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded) {
return; return;
} }
#endif #endif
Editor::NotifyStyleNeeded(endStyleNeeded); Editor::NotifyStyleToNeeded(endStyleNeeded);
} }
LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
@@ -321,10 +324,21 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
AutoCompleteCompleted(); AutoCompleteCompleted();
break; break;
case SCI_AUTOCSETSEPARATOR:
ac.SetSeparator(wParam);
break;
case SCI_AUTOCGETSEPARATOR:
return ac.GetSeparator();
case SCI_AUTOCSTOPS: case SCI_AUTOCSTOPS:
ac.SetStopChars(reinterpret_cast<char *>(lParam)); ac.SetStopChars(reinterpret_cast<char *>(lParam));
break; break;
case SCI_AUTOCSELECT:
ac.Select(reinterpret_cast<char *>(lParam));
break;
case SCI_CALLTIPSHOW: { case SCI_CALLTIPSHOW: {
AutoCompleteCancel(); AutoCompleteCancel();
if (!ct.wCallTip.Created()) { if (!ct.wCallTip.Created()) {
@@ -384,7 +398,7 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break; break;
case SCI_SETKEYWORDS: case SCI_SETKEYWORDS:
if ((wParam >= 0) && (wParam < numWordLists)) { if (wParam < numWordLists) {
keyWordLists[wParam]->Clear(); keyWordLists[wParam]->Clear();
keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam)); keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
} }

View File

@@ -7,6 +7,9 @@
#define SCINTILLABASE_H #define SCINTILLABASE_H
class ScintillaBase : public Editor { class ScintillaBase : public Editor {
// Private so ScintillaBase objects can not be copied
ScintillaBase(const ScintillaBase &) : Editor() {}
ScintillaBase &operator=(const ScintillaBase &) { return *this; }
protected: protected:
// Enumeration of commands and child windows // Enumeration of commands and child windows
enum { enum {
@@ -42,7 +45,7 @@ protected:
virtual void RefreshColourPalette(Palette &pal, bool want); virtual void RefreshColourPalette(Palette &pal, bool want);
virtual void AddChar(char ch); virtual void AddCharUTF(char *s, unsigned int len);
void Command(int cmdId); void Command(int cmdId);
virtual int KeyCommand(UINT iMessage); virtual int KeyCommand(UINT iMessage);
@@ -59,7 +62,7 @@ protected:
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
virtual void NotifyStyleNeeded(int endStyleNeeded); virtual void NotifyStyleToNeeded(int endStyleNeeded);
public: public:
// Public so scintilla_send_message can use it // Public so scintilla_send_message can use it
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);

View File

@@ -16,6 +16,18 @@ Style::Style() {
false, false, false); false, false, false);
} }
Style::Style(const Style &source) {
Clear(Colour(0,0,0), Colour(0xff,0xff,0xff),
0, 0,
false, false, false);
fore.desired = source.fore.desired;
back.desired = source.back.desired;
bold = source.bold;
italic = source.italic;
size = source.size;
eolFilled = source.eolFilled;
}
Style::~Style() { Style::~Style() {
if (aliasOfDefaultFont) if (aliasOfDefaultFont)
font.SetID(0); font.SetID(0);
@@ -78,7 +90,7 @@ void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) {
font.SetID(0); font.SetID(0);
else else
font.Release(); font.Release();
int deviceHeight = (sizeZoomed * surface.LogPixelsY()) / 72; int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle && aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName); (EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) { if (aliasOfDefaultFont) {
@@ -99,5 +111,3 @@ void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) {
aveCharWidth = surface.AverageCharWidth(font); aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' '); spaceWidth = surface.WidthChar(font, ' ');
} }

View File

@@ -26,6 +26,7 @@ public:
unsigned int spaceWidth; unsigned int spaceWidth;
Style(); Style();
Style(const Style &source);
~Style(); ~Style();
Style &operator=(const Style &source); Style &operator=(const Style &source);
void Clear(Colour fore_, Colour back_, void Clear(Colour fore_, Colour back_,

View File

@@ -0,0 +1,77 @@
// UniConversion.h - functions to handle UFT-8 and UCS-2 strings
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include "UniConversion.h"
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) {
unsigned int len = 0;
for (unsigned int i = 0; i < tlen && uptr[i]; i++) {
unsigned int uch = uptr[i];
if (uch < 0x80)
len++;
else if (uch < 0x800)
len+=2;
else
len +=3;
}
return len;
}
void UTF8FromUCS2(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) {
int k = 0;
for (unsigned int i = 0; i < tlen && uptr[i]; i++) {
unsigned int uch = uptr[i];
if (uch < 0x80) {
putf[k++] = static_cast<char>(uch);
} else if (uch < 0x800) {
putf[k++] = static_cast<char>(0xC0 | (uch >> 6));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
} else {
putf[k++] = static_cast<char>(0xE0 | (uch >> 12));
putf[k++] = static_cast<char>(0x80 | ((uch >> 6) & 0x3f));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
}
}
putf[len] = '\0';
}
unsigned int UCS2Length(const char *s, unsigned int len) {
unsigned int ulen = 0;
for (unsigned int i=0;i<len;i++) {
unsigned char ch = static_cast<unsigned char>(s[i]);
if ((ch < 0x80) || (ch > (0x80 + 0x40)))
ulen++;
}
return ulen;
}
unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen) {
#ifdef USE_API
return ::MultiByteToWideChar(CP_UTF8, 0, s, len, tbuf, tlen);
#else
unsigned int ui=0;
const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
unsigned int i=0;
while ((i<len) && (ui<tlen)) {
unsigned char ch = us[i++];
if (ch < 0x80) {
tbuf[ui] = ch;
} else if (ch < 0x80 + 0x40 + 0x20) {
tbuf[ui] = static_cast<wchar_t>((ch & 0x1F) << 6);
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F));
} else {
tbuf[ui] = static_cast<wchar_t>((ch & 0xF) << 12);
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + ((ch & 0x7F) << 6));
ch = us[i++];
tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F));
}
ui++;
}
return ui;
#endif
}

View File

@@ -0,0 +1,9 @@
// UniConversion.h - functions to handle UFT-8 and UCS-2 strings
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen);
void UTF8FromUCS2(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len);
unsigned int UCS2Length(const char *s, unsigned int len);
unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen);

View File

@@ -225,5 +225,3 @@ void ViewStyle::ClearStyles() {
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
styles[styleIndex].fontName = fontNames.Save(name); styles[styleIndex].fontName = fontNames.Save(name);
} }

View File

@@ -11,20 +11,29 @@
#include "PropSet.h" #include "PropSet.h"
#include "Accessor.h" #include "Accessor.h"
#include "WindowAccessor.h"
#include "Scintilla.h" #include "Scintilla.h"
bool Accessor::InternalIsLeadByte(char ch) { WindowAccessor::~WindowAccessor() {
}
bool WindowAccessor::InternalIsLeadByte(char ch) {
#if PLAT_GTK #if PLAT_GTK
// TODO: support DBCS under GTK+ // TODO: support DBCS under GTK+
return false; return false;
#elif PLAT_WIN #elif PLAT_WIN
if (SC_CP_UTF8 == codePage)
// For lexing, all characters >= 0x80 are treated the
// same so none is considered a lead byte.
return false;
else
return IsDBCSLeadByteEx(codePage, ch); return IsDBCSLeadByteEx(codePage, ch);
#elif PLAT_WX #elif PLAT_WX
return false; return false;
#endif #endif
} }
void Accessor::Fill(int position) { void WindowAccessor::Fill(int position) {
if (lenDoc == -1) if (lenDoc == -1)
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
startPos = position - slopSize; startPos = position - slopSize;
@@ -40,46 +49,46 @@ void Accessor::Fill(int position) {
Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)); Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr));
} }
char Accessor::StyleAt(int position) { char WindowAccessor::StyleAt(int position) {
return static_cast<char>(Platform::SendScintilla( return static_cast<char>(Platform::SendScintilla(
id, SCI_GETSTYLEAT, position, 0)); id, SCI_GETSTYLEAT, position, 0));
} }
int Accessor::GetLine(int position) { int WindowAccessor::GetLine(int position) {
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
} }
int Accessor::LineStart(int line) { int WindowAccessor::LineStart(int line) {
return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); return Platform::SendScintilla(id, EM_LINEINDEX, line, 0);
} }
int Accessor::LevelAt(int line) { int WindowAccessor::LevelAt(int line) {
return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
} }
int Accessor::Length() { int WindowAccessor::Length() {
if (lenDoc == -1) if (lenDoc == -1)
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
return lenDoc; return lenDoc;
} }
int Accessor::GetLineState(int line) { int WindowAccessor::GetLineState(int line) {
return Platform::SendScintilla(id, SCI_GETLINESTATE, line); return Platform::SendScintilla(id, SCI_GETLINESTATE, line);
} }
int Accessor::SetLineState(int line, int state) { int WindowAccessor::SetLineState(int line, int state) {
return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state); return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state);
} }
void StylingContext::StartAt(unsigned int start, char chMask) { void WindowAccessor::StartAt(unsigned int start, char chMask) {
Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask); Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask);
} }
void StylingContext::StartSegment(unsigned int pos) { void WindowAccessor::StartSegment(unsigned int pos) {
startSeg = pos; startSeg = pos;
} }
void StylingContext::ColourTo(unsigned int pos, int chAttr) { void WindowAccessor::ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range // Only perform styling if non empty range
if (pos != startSeg - 1) { if (pos != startSeg - 1) {
if (pos < startSeg) { if (pos < startSeg) {
@@ -96,22 +105,20 @@ void StylingContext::ColourTo(unsigned int pos, int chAttr) {
chFlags = 0; chFlags = 0;
chAttr |= chFlags; chAttr |= chFlags;
for (unsigned int i = startSeg; i <= pos; i++) { for (unsigned int i = startSeg; i <= pos; i++) {
styleBuf[validLen++] = chAttr; styleBuf[validLen++] = static_cast<char>(chAttr);
} }
} }
} }
startSeg = pos+1; startSeg = pos+1;
} }
int StylingContext::GetLine(int position) { void WindowAccessor::SetLevel(int line, int level) {
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
}
void StylingContext::SetLevel(int line, int level) {
Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level); Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level);
} }
void StylingContext::Flush() { void WindowAccessor::Flush() {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) { if (validLen > 0) {
Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen,
reinterpret_cast<LPARAM>(styleBuf)); reinterpret_cast<LPARAM>(styleBuf));
@@ -119,7 +126,7 @@ void StylingContext::Flush() {
} }
} }
int StylingContext::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
int end = Length(); int end = Length();
int spaceFlags = 0; int spaceFlags = 0;

View File

@@ -116,7 +116,7 @@ wxStyledTextCtrl::~wxStyledTextCtrl() {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) { long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) {
return m_swx->WndProc(msg, wp, lp); return m_swx->WndProc(msg, wp, lp);
} }
@@ -146,8 +146,9 @@ wxString wxStyledTextCtrl::GetLine(int line) {
int len = GetLineLength(line); int len = GetLineLength(line);
char* buff = text.GetWriteBuf(len+1); char* buff = text.GetWriteBuf(len+1);
*((WORD*)buff) = len+1; *((WORD*)buff) = len;
SendMsg(EM_GETLINE, line, (long)buff); SendMsg(EM_GETLINE, line, (long)buff);
buff[len] = 0;
text.UngetWriteBuf(); text.UngetWriteBuf();
return text; return text;
} }
@@ -426,16 +427,16 @@ int wxStyledTextCtrl::GetCurrentLine() {
} }
wxString wxStyledTextCtrl::GetCurrentLineText(/*int* linePos*/) { wxString wxStyledTextCtrl::GetCurrentLineText(int* linePos) {
wxString text; wxString text;
int len = GetLineLength(GetCurrentLine()); int len = GetLineLength(GetCurrentLine());
char* buff = text.GetWriteBuf(len+1); char* buff = text.GetWriteBuf(len+1);
int pos = SendMsg(SCI_GETCURLINE, len+1, (long)buff); int pos = SendMsg(SCI_GETCURLINE, len, (long)buff);
text.UngetWriteBuf(); text.UngetWriteBuf();
/* if (linePos) if (linePos)
*linePos = pos; */ *linePos = pos;
return text; return text;
} }
@@ -457,7 +458,7 @@ int wxStyledTextCtrl::LineFromPoint(wxPoint pt) {
wxPoint wxStyledTextCtrl::PointFromPosition(int pos) { wxPoint wxStyledTextCtrl::PointFromPosition(int pos) {
Point pt; Point pt;
SendMsg(EM_POSFROMCHAR, pos, (long)&pt); SendMsg(EM_POSFROMCHAR, (long)&pt, pos);
return wxPoint(pt.x, pt.y); return wxPoint(pt.x, pt.y);
} }
@@ -538,6 +539,27 @@ int wxStyledTextCtrl::GetSelectionType() {
} }
int wxStyledTextCtrl::GetLinesOnScreen() {
return SendMsg(SCI_LINESONSCREEN);
}
bool wxStyledTextCtrl::IsSelectionRectangle() {
return SendMsg(SCI_SELECTIONISRECTANGLE) != 0;
}
void wxStyledTextCtrl::SetUseHorizontalScrollBar(bool use) {
SendMsg(SCI_SETHSCROLLBAR, use);
}
bool wxStyledTextCtrl::GetUseHorizontalScrollBar() {
return SendMsg(SCI_GETHSCROLLBAR) != 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@@ -645,6 +667,16 @@ void wxStyledTextCtrl::SetStyleBytes(int length, char* styleBytes) {
} }
void wxStyledTextCtrl::SetLineState(int line, int value) {
SendMsg(SCI_SETLINESTATE, line, value);
}
int wxStyledTextCtrl::GetLineState(int line) {
return SendMsg(SCI_GETLINESTATE, line);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Style Definition // Style Definition
@@ -905,11 +937,41 @@ void wxStyledTextCtrl::SetTabWidth(int numChars) {
} }
void wxStyledTextCtrl::SetIndent(int numChars) {
SendMsg(SCI_SETINDENT, numChars);
}
void wxStyledTextCtrl::SetUseTabs(bool usetabs) {
SendMsg(SCI_SETUSETABS, usetabs);
}
void wxStyledTextCtrl::SetLineIndentation(int line, int indentation) {
SendMsg(SCI_SETLINEINDENTATION, line, indentation);
}
int wxStyledTextCtrl:: GetLineIndentation(int line) {
return SendMsg(SCI_GETLINEINDENTATION, line);
}
int wxStyledTextCtrl::GetLineIndentationPos(int line) {
return SendMsg(SCI_GETLINEINDENTPOSITION, line);
}
void wxStyledTextCtrl::SetWordChars(const wxString& wordChars) { void wxStyledTextCtrl::SetWordChars(const wxString& wordChars) {
SendMsg(SCI_SETTABWIDTH, 0, (long)wordChars.c_str()); SendMsg(SCI_SETTABWIDTH, 0, (long)wordChars.c_str());
} }
void wxStyledTextCtrl::SetUsePop(bool usepopup) {
SendMsg(SCI_USEPOPUP, usepopup);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Brace highlighting // Brace highlighting
@@ -1053,6 +1115,21 @@ void wxStyledTextCtrl::AutoCompStopChars(const wxString& stopChars) {
} }
void wxStyledTextCtrl::AutoCompSetSeparator(char separator) {
SendMsg(SCI_AUTOCSETSEPARATOR, separator);
}
char wxStyledTextCtrl::AutoCompGetSeparator() {
return SendMsg(SCI_AUTOCGETSEPARATOR);
}
void wxStyledTextCtrl::AutoCompSelect(const wxString& stringtoselect) {
SendMsg(SCI_AUTOCSELECT, (long)stringtoselect.c_str());
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Call tips // Call tips