[UPDATE] Update Scintilla to v2.21.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@662 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2010-09-05 22:56:27 +00:00
parent 247375f6cf
commit 059f9977ef
38 changed files with 3923 additions and 731 deletions

View File

@ -18,14 +18,14 @@ SCI_LEXERS=LexAPDL.o LexASY.o LexAU3.o LexAVE.o LexAbaqus.o LexAda.o \
LexPython.o LexR.o LexRebol.o LexRuby.o LexSML.o LexSQL.o LexScriptol.o \ LexPython.o LexR.o LexRebol.o LexRuby.o LexSML.o LexSQL.o LexScriptol.o \
LexSmalltalk.o LexSorcus.o LexSpecman.o LexSpice.o LexTACL.o LexTADS3.o \ LexSmalltalk.o LexSorcus.o LexSpecman.o LexSpice.o LexTACL.o LexTADS3.o \
LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVHDL.o LexVerilog.o LexYAML.o \ LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVHDL.o LexVerilog.o LexYAML.o \
LexerBase.o LexerModule.o LexerSimple.o Accessor.o LexTxt2tags.o LexerBase.o LexerModule.o LexerSimple.o Accessor.o
SCI_OBJ=AutoComplete.o CallTip.o CellBuffer.o CharClassify.o \ SCI_OBJ=AutoComplete.o CallTip.o CellBuffer.o CharClassify.o \
ContractionState.o Decoration.o Document.o Editor.o \ ContractionState.o Decoration.o Document.o Editor.o \
ExternalLexer.o Indicator.o KeyMap.o LineMarker.o PerLine.o \ ExternalLexer.o Indicator.o KeyMap.o LineMarker.o PerLine.o \
PositionCache.o PropSetSimple.o RESearch.o RunStyles.o ScintillaBase.o Style.o \ PositionCache.o PropSetSimple.o RESearch.o RunStyles.o ScintillaBase.o Style.o \
StyleContext.o UniConversion.o ViewStyle.o XPM.o WordList.o \ StyleContext.o UniConversion.o ViewStyle.o XPM.o WordList.o \
Selection.o CharacterSet.o Catalogue.o $(SCI_LEXERS) Selection.o CharacterSet.o Catalogue.o $(SCI_LEXERS)
WAH_OBJ=DocumentAccessor.o KeyWords.o WindowAccessor.o WAH_OBJ=DocumentAccessor.o KeyWords.o WindowAccessor.o

View File

@ -3038,28 +3038,10 @@ struct Sci_TextToFind {
horizontal space, such as Thai, will mostly work but there are some issues where the characters horizontal space, such as Thai, will mostly work but there are some issues where the characters
are drawn separately leading to visual glitches. Bi-directional text is not supported. </p> are drawn separately leading to visual glitches. Bi-directional text is not supported. </p>
<p>On Windows, code page can be set to 932 (Japanese Shift-JIS), 936 (Simplified Chinese GBK), <p>Code page can be set to 932 (Japanese Shift-JIS), 936 (Simplified Chinese GBK),
949 (Korean Unified Hangul Code), 950 (Traditional Chinese Big5), or 1361 (Korean Johab) 949 (Korean Unified Hangul Code), 950 (Traditional Chinese Big5), or 1361 (Korean Johab)
although these may require installation of language specific support.</p> although these may require installation of language specific support.</p>
<p>On GTK+, code page can be set to 932 (Japanese Shift-JIS), 936 (Simplified Chinese GBK),
or 950 (Traditional Chinese Big5).
The code page may also be set to <code>SC_CP_DBCS</code> (1)
which uses the current locale to handle multi byte characters which may work for otherwise unsupported
code pages.</p>
<p>For GTK+ 1.x, the locale should be set to a Unicode locale with a call similar to
<code>setlocale(LC_CTYPE, "en_US.UTF-8")</code>. Fonts with an <code>"iso10646"</code> registry
should be used in a font set. Font sets are a comma separated list of partial font
specifications where each partial font specification can be in the form:
<code>foundry-fontface-charsetregistry-encoding</code> or
<code>fontface-charsetregistry-encoding</code> or <code>foundry-fontface</code> or
<code>fontface</code>. An example is <code>"misc-fixed-iso10646-1,*"</code>.
On GTK+ 2.x, Pango fonts should be used rather than font sets.</p>
<p>Setting <code>codePage</code> to a non-zero value that is not <code>SC_CP_UTF8</code> is
operating system dependent.</p>
<p><b id="SCI_SETKEYSUNICODE">SCI_SETKEYSUNICODE(bool keysUnicode)</b><br /> <p><b id="SCI_SETKEYSUNICODE">SCI_SETKEYSUNICODE(bool keysUnicode)</b><br />
<b id="SCI_GETKEYSUNICODE">SCI_GETKEYSUNICODE</b><br /> <b id="SCI_GETKEYSUNICODE">SCI_GETKEYSUNICODE</b><br />
On Windows, character keys are normally handled differently depending on whether Scintilla is a wide On Windows, character keys are normally handled differently depending on whether Scintilla is a wide

View File

@ -25,9 +25,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0"> <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr> <tr>
<td> <td>
<font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla220.zip?download"> <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla221.zip?download">
Windows</a>&nbsp;&nbsp; Windows</a>&nbsp;&nbsp;
<a href="http://prdownloads.sourceforge.net/scintilla/scintilla220.tgz?download"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla221.tgz?download">
GTK+/Linux</a>&nbsp;&nbsp; GTK+/Linux</a>&nbsp;&nbsp;
</font> </font>
</td> </td>
@ -41,7 +41,7 @@
containing very few restrictions. containing very few restrictions.
</p> </p>
<h3> <h3>
Release 2.20 Release 2.21
</h3> </h3>
<h4> <h4>
Source Code Source Code
@ -49,8 +49,8 @@
The source code package contains all of the source code for Scintilla but no binary The source code package contains all of the source code for Scintilla but no binary
executable code and is available in executable code and is available in
<ul> <ul>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla220.zip?download">zip format</a> (1160K) commonly used on Windows</li> <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla221.zip?download">zip format</a> (1160K) commonly used on Windows</li>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla220.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li> <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla221.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li>
</ul> </ul>
Instructions for building on both Windows and Linux are included in the readme file. Instructions for building on both Windows and Linux are included in the readme file.
<h4> <h4>

View File

@ -349,6 +349,7 @@
<td>Xavi</td> <td>Xavi</td>
<td>Toby Inkster</td> <td>Toby Inkster</td>
<td>Eric Forgeot</td> <td>Eric Forgeot</td>
<td>Colomban Wendling</td>
</tr> </tr>
</table> </table>
<p> <p>
@ -360,6 +361,104 @@
Icons</a> Copyright(C) 1998 by Dean S. Jones<br /> Icons</a> Copyright(C) 1998 by Dean S. Jones<br />
</li> </li>
</ul> </ul>
<h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite221.zip?download">Release 2.21</a>
</h3>
<ul>
<li>
Released 1 September 2010.
</li>
<li>
Asian Double Byte Character Set (DBCS) support improved.
Case insensitive search works and other operations are much faster.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2999125&group_id=2439">Bug #2999125,</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2774616&group_id=2439">Bug #2774616,</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2991942&group_id=2439">Bug #2991942,</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3005688&group_id=2439">Bug #3005688.</a>
</li>
<li>
Scintilla on GTK+ uses only non-deprecated APIs (for GTK+ 2.20) except for GdkFont and GdkFont use can be disabled
with the preprocessor symbol DISABLE_GDK_FONT.
</li>
<li>
IDocument interface used by lexers adds BufferPointer and GetLineIndentation methods.
</li>
<li>
On Windows, clicking sets focus before processing the click or sending notifications.
</li>
<li>
Bug on OS X (macosx platform) fixed where drag/drop overwrote clipboard.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3039732&group_id=2439">Bug #3039732.</a>
</li>
<li>
GTK+ drawing bug when the view was horizontally scrolled more than 32000 pixels fixed.
</li>
<li>
SciTE bug fixed with invoking Complete Symbol from output pane.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3050957&group_id=2439">Bug #3050957.</a>
</li>
<li>
Bug fixed where it was not possible to disable folding.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040649&group_id=2439">Bug #3040649.</a>
</li>
<li>
Bug fixed with pressing Enter on a folded fold header line not opening the fold.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3043419&group_id=2439">Bug #3043419.</a>
</li>
<li>
SciTE 'Match case' option in find and replace user interfaces changed to 'Case sensitive' to allow use of 'v'
rather than 'c' as the mnemonic.
</li>
<li>
SciTE displays stack trace for Lua when error occurs..
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3051397&group_id=2439">Bug #3051397.</a>
</li>
<li>
SciTE on Windows fixes bug where double clicking on error message left focus in output pane.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1264835&group_id=2439">Bug #1264835.</a>
</li>
<li>
SciTE on Windows uses SetDllDirectory to avoid a security problem.
</li>
<li>
C++ lexer crash fixed with preprocessor expression that looked like division by 0.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3056825&group_id=2439">Bug #3056825.</a>
</li>
<li>
Haskell lexer improved.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3039490&group_id=2439">Feature #3039490.</a>
</li>
<li>
HTML lexing fixed around Django {% %} tags.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3034853&group_id=2439">Bug #3034853.</a>
</li>
<li>
HTML JavaScript lexing fixed when line end escaped.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3038381&group_id=2439">Bug #3038381.</a>
</li>
<li>
HTML lexer stores line state produced by a line on that line rather than on the next line.
</li>
<li>
Markdown lexer fixes infinite loop.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3045386&group_id=2439">Bug #3045386.</a>
</li>
<li>
MySQL folding bugs with END statements fixed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3031742&group_id=2439">Bug #3031742.</a>
</li>
<li>
PowerShell lexer allows '_' as a word character.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3042228&group_id=2439">Feature #3042228.</a>
</li>
<li>
SciTE on GTK+ abandons processing of subsequent commands if a command.go.needs command fails.
</li>
<li>
When SciTE is closed, all buffers now receive an OnClose call.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3033857&group_id=2439">Bug #3033857.</a>
</li>
</ul>
<h3> <h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite220.zip?download">Release 2.20</a> <a href="http://prdownloads.sourceforge.net/scintilla/scite220.zip?download">Release 2.20</a>
</h3> </h3>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description" <meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20100730" /> <meta name="Date.Modified" content="20100901" />
<style type="text/css"> <style type="text/css">
#versionlist { #versionlist {
margin: 0; margin: 0;
@ -55,8 +55,8 @@
GTK+</font> GTK+</font>
</td> </td>
<td width="40%" align="right"> <td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 2.20<br /> <font color="#FFCC99" size="3"> Release version 2.21<br />
Site last modified July 30 2010</font> Site last modified September 1 2010</font>
</td> </td>
<td width="20%"> <td width="20%">
&nbsp; &nbsp;
@ -71,6 +71,7 @@
</tr> </tr>
</table> </table>
<ul id="versionlist"> <ul id="versionlist">
<li>Version 2.21 performs much faster for Asian Double Byte Character Sets.</li>
<li>Version 2.20 implements lexers as objects so they may retain additional state. <li>Version 2.20 implements lexers as objects so they may retain additional state.
The C++ lexer understands the preprocessor enough to grey-out code that is inactive due to conditional compilation.</li> The C++ lexer understands the preprocessor enough to grey-out code that is inactive due to conditional compilation.</li>
<li>Version 2.12 improves drawing speed and fixes bugs.</li> <li>Version 2.12 improves drawing speed and fixes bugs.</li>

View File

@ -33,6 +33,12 @@
#include "Converter.h" #include "Converter.h"
#if GTK_CHECK_VERSION(2,20,0)
#define IS_WIDGET_FOCUSSED(w) (gtk_widget_has_focus(GTK_WIDGET(w)))
#else
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
// Ignore unreferenced local functions in GTK+ headers // Ignore unreferenced local functions in GTK+ headers
#pragma warning(disable: 4505) #pragma warning(disable: 4505)
@ -121,8 +127,10 @@ public:
ResetWidths(et); ResetWidths(et);
} }
~FontHandle() { ~FontHandle() {
#ifndef DISABLE_GDK_FONT
if (pfont) if (pfont)
gdk_font_unref(pfont); gdk_font_unref(pfont);
#endif
pfont = 0; pfont = 0;
if (pfd) if (pfd)
pango_font_description_free(pfd); pango_font_description_free(pfd);
@ -267,6 +275,8 @@ void Palette::Allocate(Window &w) {
delete []successPalette; delete []successPalette;
} }
#ifndef DISABLE_GDK_FONT
static const char *CharacterSetName(int characterSet) { static const char *CharacterSetName(int characterSet) {
switch (characterSet) { switch (characterSet) {
case SC_CHARSET_ANSI: case SC_CHARSET_ANSI:
@ -374,6 +384,8 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
} }
} }
#endif
static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, int size, bool bold, bool italic) { static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, int size, bool bold, bool italic) {
memset(&lf, 0, sizeof(lf)); memset(&lf, 0, sizeof(lf));
lf.size = size; lf.size = size;
@ -481,6 +493,7 @@ void FontCached::ReleaseId(FontID fid_) {
FontMutexUnlock(); FontMutexUnlock();
} }
#ifndef DISABLE_GDK_FONT
static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) { static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
if (IsDBCSCharacterSet(characterSet)) { if (IsDBCSCharacterSet(characterSet)) {
return gdk_fontset_load(fontspec); return gdk_fontset_load(fontspec);
@ -488,20 +501,10 @@ static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
return gdk_font_load(fontspec); return gdk_font_load(fontspec);
} }
} }
#endif
FontID FontCached::CreateNewFont(const char *fontName, int characterSet, FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
int size, bool bold, bool italic) { int size, bool bold, bool italic) {
char fontset[1024];
char fontspec[300];
char foundary[50];
char faceName[100];
char charset[50];
fontset[0] = '\0';
fontspec[0] = '\0';
foundary[0] = '\0';
faceName[0] = '\0';
charset[0] = '\0';
if (fontName[0] == '!') { if (fontName[0] == '!') {
PangoFontDescription *pfd = pango_font_description_new(); PangoFontDescription *pfd = pango_font_description_new();
if (pfd) { if (pfd) {
@ -513,6 +516,18 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
} }
} }
#ifndef DISABLE_GDK_FONT
char fontset[1024];
char fontspec[300];
char foundary[50];
char faceName[100];
char charset[50];
fontset[0] = '\0';
fontspec[0] = '\0';
foundary[0] = '\0';
faceName[0] = '\0';
charset[0] = '\0';
GdkFont *newid = 0; GdkFont *newid = 0;
// If name of the font begins with a '-', assume, that it is // If name of the font begins with a '-', assume, that it is
// a full fontspec. // a full fontspec.
@ -598,7 +613,6 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
newid = gdk_fontset_load(fontset); newid = gdk_fontset_load(fontset);
if (newid) if (newid)
return new FontHandle(newid); return new FontHandle(newid);
// if fontset load failed, fall through, we'll use // if fontset load failed, fall through, we'll use
// the last font entry and continue to try and // the last font entry and continue to try and
// get something that matches // get something that matches
@ -647,6 +661,9 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
characterSet); characterSet);
} }
return new FontHandle(newid); return new FontHandle(newid);
#else
return new FontHandle(0);
#endif
} }
Font::Font() : fid(0) {} Font::Font() : fid(0) {}
@ -746,11 +763,11 @@ const char *CharacterSetID(int characterSet) {
case SC_CHARSET_EASTEUROPE: case SC_CHARSET_EASTEUROPE:
return "ISO-8859-2"; return "ISO-8859-2";
case SC_CHARSET_GB2312: case SC_CHARSET_GB2312:
return "GB2312"; return "CP936";
case SC_CHARSET_GREEK: case SC_CHARSET_GREEK:
return "ISO-8859-7"; return "ISO-8859-7";
case SC_CHARSET_HANGUL: case SC_CHARSET_HANGUL:
return ""; return "CP949";
case SC_CHARSET_MAC: case SC_CHARSET_MAC:
return "MACINTOSH"; return "MACINTOSH";
case SC_CHARSET_OEM: case SC_CHARSET_OEM:
@ -766,7 +783,7 @@ const char *CharacterSetID(int characterSet) {
case SC_CHARSET_TURKISH: case SC_CHARSET_TURKISH:
return "ISO-8859-9"; return "ISO-8859-9";
case SC_CHARSET_JOHAB: case SC_CHARSET_JOHAB:
return "JOHAB"; return "CP1361";
case SC_CHARSET_HEBREW: case SC_CHARSET_HEBREW:
return "ISO-8859-8"; return "ISO-8859-8";
case SC_CHARSET_ARABIC: case SC_CHARSET_ARABIC:
@ -803,11 +820,11 @@ void SurfaceImpl::Release() {
drawable = 0; drawable = 0;
if (createdGC) { if (createdGC) {
createdGC = false; createdGC = false;
gdk_gc_unref(gc); g_object_unref(gc);
} }
gc = 0; gc = 0;
if (ppixmap) if (ppixmap)
gdk_pixmap_unref(ppixmap); g_object_unref(ppixmap);
ppixmap = 0; ppixmap = 0;
if (layout) if (layout)
g_object_unref(layout); g_object_unref(layout);
@ -954,7 +971,7 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat;
gdk_draw_pixmap(drawable, gdk_draw_drawable(drawable,
gc, gc,
static_cast<SurfaceImpl &>(surfacePattern).drawable, static_cast<SurfaceImpl &>(surfacePattern).drawable,
0, 0, 0, 0,
@ -1080,7 +1097,7 @@ void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated b
void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
if (static_cast<SurfaceImpl &>(surfaceSource).drawable) { if (static_cast<SurfaceImpl &>(surfaceSource).drawable) {
gdk_draw_pixmap(drawable, gdk_draw_drawable(drawable,
gc, gc,
static_cast<SurfaceImpl &>(surfaceSource).drawable, static_cast<SurfaceImpl &>(surfaceSource).drawable,
from.x, from.y, from.x, from.y,
@ -1089,6 +1106,7 @@ void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
} }
} }
#ifndef DISABLE_GDK_FONT
static size_t UTF8Len(char ch) { static size_t UTF8Len(char ch) {
unsigned char uch = static_cast<unsigned char>(ch); unsigned char uch = static_cast<unsigned char>(ch);
if (uch < 0x80) if (uch < 0x80)
@ -1098,6 +1116,7 @@ static size_t UTF8Len(char ch) {
else else
return 3; return 3;
} }
#endif
char *UTF8FromLatin1(const char *s, int &len) { char *UTF8FromLatin1(const char *s, int &len) {
char *utfForm = new char[len*2+1]; char *utfForm = new char[len*2+1];
@ -1151,6 +1170,7 @@ static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t
return 1; return 1;
} }
#ifndef DISABLE_GDK_FONT
static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) { static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
char *utfForm = new char[wclen*3+1]; // Maximum of 3 UTF-8 bytes per character char *utfForm = new char[wclen*3+1]; // Maximum of 3 UTF-8 bytes per character
size_t lenU = 0; size_t lenU = 0;
@ -1170,8 +1190,10 @@ static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
utfForm[lenU] = '\0'; utfForm[lenU] = '\0';
return utfForm; return utfForm;
} }
#endif
static char *UTF8FromDBCS(const char *s, int &len) { static char *UTF8FromDBCS(const char *s, int &len) {
#ifndef DISABLE_GDK_FONT
GdkWChar *wctext = new GdkWChar[len + 1]; GdkWChar *wctext = new GdkWChar[len + 1];
GdkWChar *wcp = wctext; GdkWChar *wcp = wctext;
int wclen = gdk_mbstowcs(wcp, s, len); int wclen = gdk_mbstowcs(wcp, s, len);
@ -1186,6 +1208,9 @@ static char *UTF8FromDBCS(const char *s, int &len) {
delete []wctext; delete []wctext;
len = strlen(utfForm); len = strlen(utfForm);
return utfForm; return utfForm;
#else
return 0;
#endif
} }
static size_t UTF8CharLength(const char *s) { static size_t UTF8CharLength(const char *s) {
@ -1244,6 +1269,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
} }
return; return;
} }
#ifndef DISABLE_GDK_FONT
// Draw text as a series of segments to avoid limitations in X servers // Draw text as a series of segments to avoid limitations in X servers
const int segmentLength = 1000; const int segmentLength = 1000;
bool draw8bit = true; bool draw8bit = true;
@ -1291,6 +1317,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
s += lenDraw; s += lenDraw;
} }
} }
#endif
} }
} }
@ -1354,7 +1381,6 @@ public:
void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) {
if (font_.GetID()) { if (font_.GetID()) {
int totalWidth = 0;
const int lenPositions = len; const int lenPositions = len;
if (PFont(font_)->pfd) { if (PFont(font_)->pfd) {
if (len == 1) { if (len == 1) {
@ -1453,6 +1479,8 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
} }
return; return;
} }
#ifndef DISABLE_GDK_FONT
int totalWidth = 0;
GdkFont *gf = PFont(font_)->pfont; GdkFont *gf = PFont(font_)->pfont;
bool measure8bit = true; bool measure8bit = true;
if (et != singleByte) { if (et != singleByte) {
@ -1503,6 +1531,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
positions[i] = totalWidth; positions[i] = totalWidth;
} }
} }
#endif
} else { } else {
// No font so return an ascending range of values // No font so return an ascending range of values
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
@ -1547,6 +1576,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
} }
return PANGO_PIXELS(pos.width); return PANGO_PIXELS(pos.width);
} }
#ifndef DISABLE_GDK_FONT
if (et == UTF8) { if (et == UTF8) {
GdkWChar wctext[maxLengthTextRun]; GdkWChar wctext[maxLengthTextRun];
size_t wclen = UTF16FromUTF8(s, len, static_cast<wchar_t *>(static_cast<void *>(wctext)), size_t wclen = UTF16FromUTF8(s, len, static_cast<wchar_t *>(static_cast<void *>(wctext)),
@ -1556,6 +1586,9 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
} else { } else {
return gdk_text_width(PFont(font_)->pfont, s, len); return gdk_text_width(PFont(font_)->pfont, s, len);
} }
#else
return 1;
#endif
} else { } else {
return 1; return 1;
} }
@ -1566,7 +1599,11 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) {
if (PFont(font_)->pfd) { if (PFont(font_)->pfd) {
return WidthText(font_, &ch, 1); return WidthText(font_, &ch, 1);
} }
#ifndef DISABLE_GDK_FONT
return gdk_char_width(PFont(font_)->pfont, ch); return gdk_char_width(PFont(font_)->pfont, ch);
#else
return 1;
#endif
} else { } else {
return 1; return 1;
} }
@ -1603,9 +1640,11 @@ int SurfaceImpl::Ascent(Font &font_) {
pango_font_metrics_unref(metrics); pango_font_metrics_unref(metrics);
ascent = PFont(font_)->ascent; ascent = PFont(font_)->ascent;
} }
#ifndef DISABLE_GDK_FONT
if ((ascent == 0) && (PFont(font_)->pfont)) { if ((ascent == 0) && (PFont(font_)->pfont)) {
ascent = PFont(font_)->pfont->ascent; ascent = PFont(font_)->pfont->ascent;
} }
#endif
if (ascent == 0) { if (ascent == 0) {
ascent = 1; ascent = 1;
} }
@ -1637,7 +1676,11 @@ int SurfaceImpl::Descent(Font &font_) {
pango_font_metrics_unref(metrics); pango_font_metrics_unref(metrics);
return descent; return descent;
} }
#ifndef DISABLE_GDK_FONT
return PFont(font_)->pfont->descent; return PFont(font_)->pfont->descent;
#else
return 0;
#endif
#else #else
gint lbearing; gint lbearing;
@ -1704,7 +1747,7 @@ void Window::Destroy() {
} }
bool Window::HasFocus() { bool Window::HasFocus() {
return GTK_WIDGET_HAS_FOCUS(wid); return IS_WIDGET_FOCUSSED(wid);
} }
PRectangle Window::GetPosition() { PRectangle Window::GetPosition() {
@ -1755,7 +1798,7 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
gtk_window_move(GTK_WINDOW(PWidget(wid)), ox, oy); gtk_window_move(GTK_WINDOW(PWidget(wid)), ox, oy);
gtk_widget_set_usize(PWidget(wid), sizex, sizey); gtk_widget_set_size_request(PWidget(wid), sizex, sizey);
} }
PRectangle Window::GetClientPosition() { PRectangle Window::GetClientPosition() {
@ -1821,7 +1864,7 @@ void Window::SetCursor(Cursor curs) {
if (PWidget(wid)->window) if (PWidget(wid)->window)
gdk_window_set_cursor(PWidget(wid)->window, gdkCurs); gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
gdk_cursor_destroy(gdkCurs); gdk_cursor_unref(gdkCurs);
} }
void Window::SetTitle(const char *s) { void Window::SetTitle(const char *s) {
@ -1864,7 +1907,7 @@ struct ListImage {
static void list_image_free(gpointer, gpointer value, gpointer) { static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value; ListImage *list_image = (ListImage *) value;
if (list_image->pixbuf) if (list_image->pixbuf)
gdk_pixbuf_unref (list_image->pixbuf); g_object_unref (list_image->pixbuf);
g_free(list_image); g_free(list_image);
} }
@ -2070,14 +2113,14 @@ PRectangle ListBoxX::GetDesiredRect() {
height = (rows * row_height height = (rows * row_height
+ 2 * (ythickness + 2 * (ythickness
+ GTK_CONTAINER(PWidget(list))->border_width + 1)); + GTK_CONTAINER(PWidget(list))->border_width + 1));
gtk_widget_set_usize(GTK_WIDGET(PWidget(list)), -1, height); gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window // Get the size of the scroller because we set usize on the window
gtk_widget_size_request(GTK_WIDGET(scroller), &req); gtk_widget_size_request(GTK_WIDGET(scroller), &req);
rc.right = req.width; rc.right = req.width;
rc.bottom = req.height; rc.bottom = req.height;
gtk_widget_set_usize(GTK_WIDGET(list), -1, -1); gtk_widget_set_size_request(GTK_WIDGET(list), -1, -1);
int width = maxItemCharacters; int width = maxItemCharacters;
if (width < 12) if (width < 12)
width = 12; width = 12;
@ -2117,7 +2160,7 @@ static void init_pixmap(ListImage *list_image) {
// Drop any existing pixmap/bitmap as data may have changed // Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf) if (list_image->pixbuf)
gdk_pixbuf_unref(list_image->pixbuf); g_object_unref(list_image->pixbuf);
list_image->pixbuf = list_image->pixbuf =
gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform); gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
delete []xpm_lineformfromtext; delete []xpm_lineformfromtext;
@ -2293,7 +2336,7 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
if (list_image) { if (list_image) {
// Drop icon already registered // Drop icon already registered
if (list_image->pixbuf) if (list_image->pixbuf)
gdk_pixbuf_unref(list_image->pixbuf); g_object_unref(list_image->pixbuf);
list_image->pixbuf = NULL; list_image->pixbuf = NULL;
list_image->xpm_data = xpm_data; list_image->xpm_data = xpm_data;
} else { } else {
@ -2342,7 +2385,13 @@ Menu::Menu() : mid(0) {}
void Menu::CreatePopUp() { void Menu::CreatePopUp() {
Destroy(); Destroy();
mid = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL); mid = gtk_menu_new();
#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink(G_OBJECT(mid));
#else
g_object_ref(G_OBJECT(mid));
gtk_object_sink(GTK_OBJECT(G_OBJECT(mid)));
#endif
} }
void Menu::Destroy() { void Menu::Destroy() {
@ -2351,21 +2400,27 @@ void Menu::Destroy() {
mid = 0; mid = 0;
} }
static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData);
*x = intFromPointer & 0xffff;
*y = intFromPointer >> 16;
}
void Menu::Show(Point pt, Window &) { void Menu::Show(Point pt, Window &) {
int screenHeight = gdk_screen_height(); int screenHeight = gdk_screen_height();
int screenWidth = gdk_screen_width(); int screenWidth = gdk_screen_width();
GtkItemFactory *factory = reinterpret_cast<GtkItemFactory *>(mid); GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
GtkWidget *widget = gtk_item_factory_get_widget(factory, "<main>"); gtk_widget_show_all(GTK_WIDGET(widget));
gtk_widget_show_all(widget);
GtkRequisition requisition; GtkRequisition requisition;
gtk_widget_size_request(widget, &requisition); gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
if ((pt.x + requisition.width) > screenWidth) { if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width; pt.x = screenWidth - requisition.width;
} }
if ((pt.y + requisition.height) > screenHeight) { if ((pt.y + requisition.height) > screenHeight) {
pt.y = screenHeight - requisition.height; pt.y = screenHeight - requisition.height;
} }
gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3, gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
reinterpret_cast<void *>((pt.y << 16) | pt.x), 0,
gtk_get_current_event_time()); gtk_get_current_event_time());
} }

View File

@ -65,6 +65,16 @@
#include "Converter.h" #include "Converter.h"
#if GTK_CHECK_VERSION(2,20,0)
#define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w)))
#define IS_WIDGET_MAPPED(w) (gtk_widget_get_mapped(GTK_WIDGET(w)))
#define IS_WIDGET_VISIBLE(w) (gtk_widget_get_visible(GTK_WIDGET(w)))
#else
#define IS_WIDGET_REALIZED(w) (GTK_WIDGET_REALIZED(w))
#define IS_WIDGET_MAPPED(w) (GTK_WIDGET_MAPPED(w))
#define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
// Constant conditional expressions are because of GTK+ headers // Constant conditional expressions are because of GTK+ headers
#pragma warning(disable: 4127) #pragma warning(disable: 4127)
@ -204,7 +214,6 @@ private:
static void Map(GtkWidget *widget); static void Map(GtkWidget *widget);
void UnMapThis(); void UnMapThis();
static void UnMap(GtkWidget *widget); static void UnMap(GtkWidget *widget);
static gint CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis);
gint FocusInThis(GtkWidget *widget); gint FocusInThis(GtkWidget *widget);
static gint FocusIn(GtkWidget *widget, GdkEventFocus *event); static gint FocusIn(GtkWidget *widget, GdkEventFocus *event);
gint FocusOutThis(GtkWidget *widget); gint FocusOutThis(GtkWidget *widget);
@ -258,7 +267,7 @@ private:
static gboolean IdleCallback(ScintillaGTK *sciThis); static gboolean IdleCallback(ScintillaGTK *sciThis);
static gboolean StyleIdle(ScintillaGTK *sciThis); static gboolean StyleIdle(ScintillaGTK *sciThis);
virtual void QueueStyling(int upTo); virtual void QueueStyling(int upTo);
static void PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *widget); static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
gint ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose); gint ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
static gint ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis); static gint ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
@ -376,7 +385,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
gdk_window_set_user_data(widget->window, widget); gdk_window_set_user_data(widget->window, widget);
gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]); gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]);
gdk_window_show(widget->window); gdk_window_show(widget->window);
gdk_cursor_destroy(cursor); gdk_cursor_unref(cursor);
widget->style = gtk_style_attach(widget->style, widget->window); widget->style = gtk_style_attach(widget->style, widget->window);
wPreedit = gtk_window_new(GTK_WINDOW_POPUP); wPreedit = gtk_window_new(GTK_WINDOW_POPUP);
wPreeditDraw = gtk_drawing_area_new(); wPreeditDraw = gtk_drawing_area_new();
@ -411,7 +420,7 @@ void ScintillaGTK::Realize(GtkWidget *widget) {
void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
try { try {
if (GTK_WIDGET_MAPPED(widget)) { if (IS_WIDGET_MAPPED(widget)) {
gtk_widget_unmap(widget); gtk_widget_unmap(widget);
} }
GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED); GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
@ -438,8 +447,8 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) {
static void MapWidget(GtkWidget *widget) { static void MapWidget(GtkWidget *widget) {
if (widget && if (widget &&
GTK_WIDGET_VISIBLE(widget) && IS_WIDGET_VISIBLE(widget) &&
!GTK_WIDGET_MAPPED(widget)) { !IS_WIDGET_MAPPED(widget)) {
gtk_widget_map(widget); gtk_widget_map(widget);
} }
} }
@ -503,16 +512,6 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
} }
} }
gint ScintillaGTK::CursorMoved(GtkWidget *, int xoffset, int yoffset, ScintillaGTK *sciThis) {
GdkRectangle area;
area.x = xoffset;
area.y = yoffset;
area.width = 1;
area.height = 1;
gtk_im_context_set_cursor_location(sciThis->im_context, &area);
return FALSE;
}
gint ScintillaGTK::FocusInThis(GtkWidget *widget) { gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
try { try {
GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
@ -578,7 +577,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget); ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try { try {
widget->allocation = *allocation; widget->allocation = *allocation;
if (GTK_WIDGET_REALIZED(widget)) if (IS_WIDGET_REALIZED(widget))
gdk_window_move_resize(widget->window, gdk_window_move_resize(widget->window,
widget->allocation.x, widget->allocation.x,
widget->allocation.y, widget->allocation.y,
@ -595,7 +594,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
void ScintillaGTK::Initialise() { void ScintillaGTK::Initialise() {
//Platform::DebugPrintf("ScintillaGTK::Initialise\n"); //Platform::DebugPrintf("ScintillaGTK::Initialise\n");
parentClass = reinterpret_cast<GtkWidgetClass *>( parentClass = reinterpret_cast<GtkWidgetClass *>(
gtk_type_class(gtk_container_get_type())); g_type_class_ref(gtk_container_get_type()));
GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_CAN_FOCUS);
GTK_WIDGET_SET_FLAGS(GTK_WIDGET(PWidget(wMain)), GTK_SENSITIVE); GTK_WIDGET_SET_FLAGS(GTK_WIDGET(PWidget(wMain)), GTK_SENSITIVE);
@ -620,8 +619,7 @@ void ScintillaGTK::Initialise() {
gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK); gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK);
// Avoid background drawing flash // Avoid background drawing flash
gtk_widget_set_double_buffered(widtxt, FALSE); gtk_widget_set_double_buffered(widtxt, FALSE);
gtk_drawing_area_size(GTK_DRAWING_AREA(widtxt), gtk_widget_set_size_request(widtxt, 100, 100);
100,100);
adjustmentv = gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0); adjustmentv = gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0);
scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv)); scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv));
GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
@ -716,7 +714,7 @@ static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSe
size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
if (conversions == ((size_t)(-1))) { if (conversions == ((size_t)(-1))) {
if (!silent) if (!silent)
fprintf(stderr, "iconv %s->%s failed for %s\n", fprintf(stderr, "iconv %s->%s failed for %s\n",
charSetSource, charSetDest, static_cast<char *>(s)); charSetSource, charSetDest, static_cast<char *>(s));
delete []destForm; delete []destForm;
destForm = 0; destForm = 0;
@ -809,8 +807,9 @@ bool ScintillaGTK::ValidCodePage(int codePage) const {
|| codePage == SC_CP_UTF8 || codePage == SC_CP_UTF8
|| codePage == 932 || codePage == 932
|| codePage == 936 || codePage == 936
|| codePage == 949
|| codePage == 950 || codePage == 950
|| codePage == SC_CP_DBCS; || codePage == 1361;
} }
sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
@ -865,9 +864,9 @@ void ScintillaGTK::SetTicking(bool on) {
if (timer.ticking != on) { if (timer.ticking != on) {
timer.ticking = on; timer.ticking = on;
if (timer.ticking) { if (timer.ticking) {
timer.tickerID = reinterpret_cast<TickerID>(gtk_timeout_add(timer.tickSize, (GtkFunction)TimeOut, this)); timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, (GtkFunction)TimeOut, this));
} else { } else {
gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID)); g_source_remove(GPOINTER_TO_UINT(timer.tickerID));
} }
} }
timer.ticksToWait = caret.period; timer.ticksToWait = caret.period;
@ -879,7 +878,7 @@ bool ScintillaGTK::SetIdle(bool on) {
if (!idler.state) { if (!idler.state) {
idler.state = true; idler.state = true;
idler.idlerID = reinterpret_cast<IdlerID>( idler.idlerID = reinterpret_cast<IdlerID>(
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL)); reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL));
} }
} else { } else {
@ -1088,38 +1087,77 @@ public:
} }
}; };
class CaseFolderDBCS : public CaseFolderTable {
const char *charSet;
public:
CaseFolderDBCS(const char *charSet_) : charSet(charSet_) {
StandardASCII();
}
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
if ((lenMixed == 1) && (sizeFolded > 0)) {
folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
return 1;
} else if (*charSet) {
int convertedLength = lenMixed;
char *sUTF8 = ConvertText(&convertedLength, const_cast<char *>(mixed), lenMixed,
"UTF-8", charSet, false);
if (sUTF8) {
gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
size_t lenMapped = strlen(mapped);
if (lenMapped < sizeFolded) {
memcpy(folded, mapped, lenMapped);
} else {
folded[0] = '\0';
lenMapped = 1;
}
g_free(mapped);
delete []sUTF8;
return lenMapped;
}
}
// Something failed so return a single NUL byte
folded[0] = '\0';
return 1;
}
};
CaseFolder *ScintillaGTK::CaseFolderForEncoding() { CaseFolder *ScintillaGTK::CaseFolderForEncoding() {
if (pdoc->dbcsCodePage == SC_CP_UTF8) { if (pdoc->dbcsCodePage == SC_CP_UTF8) {
return new CaseFolderUTF8(); return new CaseFolderUTF8();
} else { } else {
CaseFolderTable *pcf = new CaseFolderTable();
const char *charSetBuffer = CharacterSetID(); const char *charSetBuffer = CharacterSetID();
if ((pdoc->dbcsCodePage == 0) && charSetBuffer) { if (charSetBuffer) {
pcf->StandardASCII(); if (pdoc->dbcsCodePage == 0) {
// Only for single byte encodings CaseFolderTable *pcf = new CaseFolderTable();
for (int i=0x80; i<0x100; i++) { pcf->StandardASCII();
char sCharacter[2] = "A"; // Only for single byte encodings
sCharacter[0] = i; for (int i=0x80; i<0x100; i++) {
int convertedLength = 1; char sCharacter[2] = "A";
const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1, sCharacter[0] = i;
"UTF-8", charSetBuffer, false); int convertedLength = 1;
if (sUTF8) { const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1,
gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8)); "UTF-8", charSetBuffer, false);
if (mapped) { if (sUTF8) {
int mappedLength = strlen(mapped); gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
const char *mappedBack = ConvertText(&mappedLength, mapped, if (mapped) {
mappedLength, charSetBuffer, "UTF-8", false, true); int mappedLength = strlen(mapped);
if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) { const char *mappedBack = ConvertText(&mappedLength, mapped,
pcf->SetTranslation(sCharacter[0], mappedBack[0]); mappedLength, charSetBuffer, "UTF-8", false, true);
if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) {
pcf->SetTranslation(sCharacter[0], mappedBack[0]);
}
delete []mappedBack;
g_free(mapped);
} }
delete []mappedBack;
g_free(mapped);
} }
delete []sUTF8;
} }
delete []sUTF8; return pcf;
} else {
return new CaseFolderDBCS(charSetBuffer);
} }
} }
return pcf; return 0;
} }
} }
@ -1241,8 +1279,7 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
gtk_widget_set_events(widcdrw, gtk_widget_set_events(widcdrw,
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
} }
gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)), gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height());
rc.Width(), rc.Height());
ct.wDraw.Show(); ct.wDraw.Show();
if (PWidget(ct.wCallTip)->window) { if (PWidget(ct.wCallTip)->window) {
gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height()); gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height());
@ -1250,24 +1287,18 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
} }
void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) { void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) {
char fulllabel[200]; GtkWidget *menuItem;
strcpy(fulllabel, "/"); if (label[0])
strcat(fulllabel, label); menuItem = gtk_menu_item_new_with_label(label);
GtkItemFactoryCallback menuSig = GtkItemFactoryCallback(PopUpCB); else
GtkItemFactoryEntry itemEntry = { menuItem = gtk_separator_menu_item_new();
fulllabel, NULL, gtk_menu_shell_append(GTK_MENU_SHELL(popup.GetID()), menuItem);
menuSig, g_object_set_data(G_OBJECT(menuItem), "CmdNum", reinterpret_cast<void *>(cmd));
cmd, g_signal_connect(G_OBJECT(menuItem),"activate", G_CALLBACK(PopUpCB), this);
const_cast<gchar *>(label[0] ? "<Item>" : "<Separator>"),
NULL
};
gtk_item_factory_create_item(GTK_ITEM_FACTORY(popup.GetID()),
&itemEntry, this, 1);
if (cmd) { if (cmd) {
GtkWidget *item = gtk_item_factory_get_widget_by_action( if (menuItem)
reinterpret_cast<GtkItemFactory *>(popup.GetID()), cmd); gtk_widget_set_sensitive(menuItem, enabled);
if (item)
gtk_widget_set_sensitive(item, enabled);
} }
} }
@ -1280,7 +1311,7 @@ bool ScintillaGTK::OwnPrimarySelection() {
void ScintillaGTK::ClaimSelection() { void ScintillaGTK::ClaimSelection() {
// X Windows has a 'primary selection' as well as the clipboard. // X Windows has a 'primary selection' as well as the clipboard.
// Whenever the user selects some text, we become the primary selection // Whenever the user selects some text, we become the primary selection
if (!sel.Empty() && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) { if (!sel.Empty() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
primarySelection = true; primarySelection = true;
gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)), gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
@ -1539,7 +1570,7 @@ void ScintillaGTK::Resize(int width, int height) {
} else { } else {
gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv))); gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv)));
} }
if (GTK_WIDGET_MAPPED(PWidget(wMain))) { if (IS_WIDGET_MAPPED(PWidget(wMain))) {
ChangeSize(); ChangeSize();
} }
@ -1926,8 +1957,8 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000}, GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000},
{0, 0xffff, 0xffff, 0xffff} {0, 0xffff, 0xffff, 0xffff}
}; };
gdk_color_alloc(gdk_colormap_get_system(), color); gdk_colormap_alloc_color(gdk_colormap_get_system(), color, FALSE, TRUE);
gdk_color_alloc(gdk_colormap_get_system(), color + 1); gdk_colormap_alloc_color(gdk_colormap_get_system(), color + 1, FALSE, TRUE);
gdk_gc_set_foreground(gc, color + 1); gdk_gc_set_foreground(gc, color + 1);
gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y, gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
@ -1937,7 +1968,7 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
gdk_gc_set_background(gc, color + 1); gdk_gc_set_background(gc, color + 1);
gdk_draw_layout(widget->window, gc, 0, 0, layout); gdk_draw_layout(widget->window, gc, 0, 0, layout);
gdk_gc_unref(gc); g_object_unref(gc);
g_free(str); g_free(str);
pango_attr_list_unref(attrs); pango_attr_list_unref(attrs);
g_object_unref(layout); g_object_unref(layout);
@ -2057,36 +2088,6 @@ void ScintillaGTK::Destroy(GObject *object) {
} }
} }
static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
GdkRectangle areaIntersect;
if (widget &&
GTK_WIDGET_DRAWABLE(widget) &&
gtk_widget_intersect(widget, area, &areaIntersect)) {
gtk_widget_draw(widget, &areaIntersect);
}
}
void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
//Platform::DebugPrintf("Draw %p %0d,%0d %0d,%0d\n", widget, area->x, area->y, area->width, area->height);
PRectangle rcPaint(area->x, area->y, area->x + area->width, area->y + area->height);
sciThis->SyncPaint(rcPaint);
if (GTK_WIDGET_DRAWABLE(PWidget(sciThis->wMain))) {
DrawChild(PWidget(sciThis->scrollbarh), area);
DrawChild(PWidget(sciThis->scrollbarv), area);
}
Point pt = sciThis->PointMainCaret();
pt.y += sciThis->vs.lineHeight - 2;
if (pt.x < 0) pt.x = 0;
if (pt.y < 0) pt.y = 0;
CursorMoved(widget, pt.x, pt.y, sciThis);
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
}
gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) { gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
try { try {
paintState = painting; paintState = painting;
@ -2200,7 +2201,10 @@ gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selectio
ScintillaGTK *sciThis = ScintillaFromWidget(widget); ScintillaGTK *sciThis = ScintillaFromWidget(widget);
//Platform::DebugPrintf("Selection clear\n"); //Platform::DebugPrintf("Selection clear\n");
sciThis->UnclaimSelection(selection_event); sciThis->UnclaimSelection(selection_event);
return gtk_selection_clear(widget, selection_event); if (GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event) {
return GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event(widget, selection_event);
}
return TRUE;
} }
void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) { void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) {
@ -2341,12 +2345,13 @@ void ScintillaGTK::QueueStyling(int upTo) {
if (!styleNeeded.active) { if (!styleNeeded.active) {
// Only allow one style needed to be queued // Only allow one style needed to be queued
styleNeeded.active = true; styleNeeded.active = true;
g_idle_add_full(G_PRIORITY_HIGH_IDLE, g_idle_add_full(G_PRIORITY_HIGH_IDLE,
reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL); reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
} }
} }
void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) { void ScintillaGTK::PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis) {
guint action = (sptr_t)(g_object_get_data(G_OBJECT(menuItem), "CmdNum"));
if (action) { if (action) {
sciThis->Command(action); sciThis->Command(action);
} }

View File

@ -2,25 +2,23 @@ PlatGTK.o: PlatGTK.cxx \
../include/Scintilla.h ../include/ScintillaWidget.h \ ../include/Scintilla.h ../include/ScintillaWidget.h \
../src/UniConversion.h ../src/XPM.h Converter.h ../src/UniConversion.h ../src/XPM.h Converter.h
ScintillaGTK.o: ScintillaGTK.cxx \ ScintillaGTK.o: ScintillaGTK.cxx \
../include/Scintilla.h ../include/ScintillaWidget.h \ ../include/ILexer.h ../include/Scintilla.h ../include/ScintillaWidget.h \
../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/Accessor.h \ ../include/SciLexer.h ../src/SVector.h ../src/SplitVector.h \
../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \
../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \
../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \
../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \
../src/ViewStyle.h ../src/Decoration.h ../src/CharClassify.h \ ../src/ViewStyle.h ../src/Decoration.h ../src/CharClassify.h \
../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/Document.h ../src/Selection.h ../src/PositionCache.h \
../src/Editor.h ../src/ScintillaBase.h ../src/UniConversion.h \ ../src/Editor.h ../src/ScintillaBase.h ../src/UniConversion.h \
scintilla-marshal.h ../src/ExternalLexer.h Converter.h scintilla-marshal.h ../lexlib/LexerModule.h ../src/ExternalLexer.h \
Converter.h
AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \ AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \
../lexlib/CharacterSet.h ../src/AutoComplete.h ../lexlib/CharacterSet.h ../src/AutoComplete.h
CallTip.o: ../src/CallTip.cxx ../include/Platform.h \ CallTip.o: ../src/CallTip.cxx ../include/Platform.h \
../include/Scintilla.h ../src/CallTip.h ../include/Scintilla.h ../src/CallTip.h
Catalogue.o: ../src/Catalogue.cxx ../include/ILexer.h \ Catalogue.o: ../src/Catalogue.cxx ../include/ILexer.h \
../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/LexerModule.h \
../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../src/Catalogue.h
../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
../lexlib/LexerModule.h ../src/Catalogue.h
CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \ CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \
../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \
../src/CellBuffer.h ../src/CellBuffer.h
@ -41,17 +39,13 @@ Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/ILexer.h \
../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \
../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \
../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \
../src/Decoration.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../src/Decoration.h ../src/Document.h ../src/Selection.h \
../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/PositionCache.h ../src/Editor.h
../src/Editor.h
ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \ ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \
../include/ILexer.h ../include/Scintilla.h ../include/SciLexer.h \ ../include/ILexer.h ../include/Scintilla.h ../include/SciLexer.h \
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/WordList.h \
../lexlib/LexerModule.h ../src/Catalogue.h ../src/ExternalLexer.h ../lexlib/LexerModule.h ../src/Catalogue.h ../src/ExternalLexer.h
Indicator.o: ../src/Indicator.cxx ../include/Platform.h \ Indicator.o: ../src/Indicator.cxx ../include/Platform.h \
../include/Scintilla.h ../src/Indicator.h ../include/Scintilla.h ../src/Indicator.h
KW.o: ../src/KW.cxx ../include/Platform.h ../lexlib/PropSetSimple.h \
../lexlib/Accessor.h ../include/Scintilla.h ../include/SciLexer.h
KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \
../src/KeyMap.h ../src/KeyMap.h
LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \ LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \
@ -72,14 +66,14 @@ RunStyles.o: ../src/RunStyles.cxx ../include/Platform.h \
../src/RunStyles.h ../src/RunStyles.h
ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \ ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \
../include/ILexer.h ../include/Scintilla.h ../lexlib/PropSetSimple.h \ ../include/ILexer.h ../include/Scintilla.h ../lexlib/PropSetSimple.h \
../include/SciLexer.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../include/SciLexer.h ../lexlib/LexerModule.h ../src/Catalogue.h \
../lexlib/LexerModule.h ../src/Catalogue.h ../src/SplitVector.h \ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \
../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ ../src/ContractionState.h ../src/CellBuffer.h ../src/CallTip.h \
../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \
../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ ../src/Style.h ../src/ViewStyle.h ../src/AutoComplete.h \
../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \
../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/Selection.h ../src/PositionCache.h ../src/Editor.h \
../src/Editor.h ../src/ScintillaBase.h ../src/ScintillaBase.h
Selection.o: ../src/Selection.cxx ../include/Platform.h \ Selection.o: ../src/Selection.cxx ../include/Platform.h \
../include/Scintilla.h ../src/Selection.h ../include/Scintilla.h ../src/Selection.h
Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \

View File

@ -29,7 +29,8 @@ vpath %.h ../src ../include ../lexlib
vpath %.cxx ../src ../lexlib ../lexers vpath %.cxx ../src ../lexlib ../lexers
INCLUDEDIRS=-I ../include -I ../src -I ../lexlib INCLUDEDIRS=-I ../include -I ../src -I ../lexlib
CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -Wno-long-long -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) #~ DEPRECATED=-DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DDISABLE_GDK_FONT
CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -Wno-long-long -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) $(DEPRECATED)
ifdef NOTHREADS ifdef NOTHREADS
THREADFLAGS=-DG_THREADS_IMPL_NONE THREADFLAGS=-DG_THREADS_IMPL_NONE

View File

@ -41,6 +41,8 @@ public:
virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0; virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0;
virtual int SCI_METHOD CodePage() const = 0; virtual int SCI_METHOD CodePage() const = 0;
virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0; virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0;
virtual const char * SCI_METHOD BufferPointer() = 0;
virtual int SCI_METHOD GetLineIndentation(int line) = 0;
}; };
enum { lvOriginal=0 }; enum { lvOriginal=0 };

View File

@ -112,14 +112,10 @@
#define SCLEX_SML 97 #define SCLEX_SML 97
#define SCLEX_MARKDOWN 98 #define SCLEX_MARKDOWN 98
#define SCLEX_TXT2TAGS 99 #define SCLEX_TXT2TAGS 99
#define SCLEX_SEARCHRESULT 150 #define SCLEX_SEARCHRESULT 150
#define SCLEX_OBJC 151 #define SCLEX_OBJC 151
#define SCLEX_USER 152 #define SCLEX_USER 152
#define SCLEX_AUTOMATIC 1000 #define SCLEX_AUTOMATIC 1000
//For All lexer //For All lexer
#define SCE_UNIVERSAL_FOUND_STYLE 31 #define SCE_UNIVERSAL_FOUND_STYLE 31
#define SCE_UNIVERSAL_FOUND_STYLE_SMART 29 #define SCE_UNIVERSAL_FOUND_STYLE_SMART 29
@ -131,7 +127,6 @@
#define SCE_UNIVERSAL_FOUND_STYLE_EXT3 23 #define SCE_UNIVERSAL_FOUND_STYLE_EXT3 23
#define SCE_UNIVERSAL_FOUND_STYLE_EXT4 22 #define SCE_UNIVERSAL_FOUND_STYLE_EXT4 22
#define SCE_UNIVERSAL_FOUND_STYLE_EXT5 21 #define SCE_UNIVERSAL_FOUND_STYLE_EXT5 21
#define SCE_P_DEFAULT 0 #define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1 #define SCE_P_COMMENTLINE 1
#define SCE_P_NUMBER 2 #define SCE_P_NUMBER 2
@ -191,7 +186,6 @@
#define SCE_D_WORD5 20 #define SCE_D_WORD5 20
#define SCE_D_WORD6 21 #define SCE_D_WORD6 21
#define SCE_D_WORD7 22 #define SCE_D_WORD7 22
#define SCE_SEARCHRESULT_DEFAULT 0 #define SCE_SEARCHRESULT_DEFAULT 0
#define SCE_SEARCHRESULT_SEARCH_HEADER 1 #define SCE_SEARCHRESULT_SEARCH_HEADER 1
#define SCE_SEARCHRESULT_FILE_HEADER 2 #define SCE_SEARCHRESULT_FILE_HEADER 2
@ -199,10 +193,8 @@
#define SCE_SEARCHRESULT_WORD2SEARCH 4 #define SCE_SEARCHRESULT_WORD2SEARCH 4
#define SCE_SEARCHRESULT_HIGHLIGHT_LINE 5 #define SCE_SEARCHRESULT_HIGHLIGHT_LINE 5
#define SCE_SEARCHRESULT_CURRENT_LINE 6 #define SCE_SEARCHRESULT_CURRENT_LINE 6
#define SCE_OBJC_DIRECTIVE 20 #define SCE_OBJC_DIRECTIVE 20
#define SCE_OBJC_QUALIFIER 21 #define SCE_OBJC_QUALIFIER 21
#define SCE_USER_DEFAULT 0 #define SCE_USER_DEFAULT 0
#define SCE_USER_COMMENT 1 #define SCE_USER_COMMENT 1
#define SCE_USER_COMMENTLINE 2 #define SCE_USER_COMMENTLINE 2
@ -218,7 +210,6 @@
#define SCE_USER_DELIMITER1 14 #define SCE_USER_DELIMITER1 14
#define SCE_USER_DELIMITER2 15 #define SCE_USER_DELIMITER2 15
#define SCE_USER_DELIMITER3 16 #define SCE_USER_DELIMITER3 16
#define SCE_TCL_DEFAULT 0 #define SCE_TCL_DEFAULT 0
#define SCE_TCL_COMMENT 1 #define SCE_TCL_COMMENT 1
#define SCE_TCL_COMMENTLINE 2 #define SCE_TCL_COMMENTLINE 2

View File

@ -91,7 +91,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETTABWIDTH 2036 #define SCI_SETTABWIDTH 2036
#define SCI_GETTABWIDTH 2121 #define SCI_GETTABWIDTH 2121
#define SC_CP_UTF8 65001 #define SC_CP_UTF8 65001
#define SC_CP_DBCS 1
#define SCI_SETCODEPAGE 2037 #define SCI_SETCODEPAGE 2037
#define SCI_SETUSEPALETTE 2039 #define SCI_SETUSEPALETTE 2039
#define MARKER_MAX 31 #define MARKER_MAX 31
@ -256,10 +255,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_INDICGETFORE 2083 #define SCI_INDICGETFORE 2083
#define SCI_INDICSETUNDER 2510 #define SCI_INDICSETUNDER 2510
#define SCI_INDICGETUNDER 2511 #define SCI_INDICGETUNDER 2511
#define SCI_GETCARETLINEVISIBLEALWAYS 3095 #define SCI_GETCARETLINEVISIBLEALWAYS 3095
#define SCI_SETCARETLINEVISIBLEALWAYS 3096 #define SCI_SETCARETLINEVISIBLEALWAYS 3096
#define SCI_SETWHITESPACEFORE 2084 #define SCI_SETWHITESPACEFORE 2084
#define SCI_SETWHITESPACEBACK 2085 #define SCI_SETWHITESPACEBACK 2085
#define SCI_SETWHITESPACESIZE 2086 #define SCI_SETWHITESPACESIZE 2086
@ -835,9 +832,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MOD_CONTAINER 0x40000 #define SC_MOD_CONTAINER 0x40000
#define SC_MOD_LEXERSTATE 0x80000 #define SC_MOD_LEXERSTATE 0x80000
#define SC_MODEVENTMASKALL 0xFFFFF #define SC_MODEVENTMASKALL 0xFFFFF
#define SC_SEARCHRESULT_LINEBUFFERMAXLENGTH 1024 #define SC_SEARCHRESULT_LINEBUFFERMAXLENGTH 1024
#define SCEN_CHANGE 768 #define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512 #define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256 #define SCEN_KILLFOCUS 256
@ -892,7 +887,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_INDICATORRELEASE 2024 #define SCN_INDICATORRELEASE 2024
#define SCN_AUTOCCANCELLED 2025 #define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026 #define SCN_AUTOCCHARDELETED 2026
#define SCN_SCROLLED 2080 #define SCN_SCROLLED 2080
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
@ -994,4 +988,10 @@ struct SearchResultMarkings {
} }
#endif #endif
#ifdef INCLUDE_DEPRECATED_FEATURES
#define SC_CP_DBCS 1
#endif
#endif #endif

View File

@ -224,9 +224,6 @@ get int GetTabWidth=2121(,)
# This is the same value as CP_UTF8 in Windows # This is the same value as CP_UTF8 in Windows
val SC_CP_UTF8=65001 val SC_CP_UTF8=65001
# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
val SC_CP_DBCS=1
# Set the code page used to interpret the bytes of the document as characters. # Set the code page used to interpret the bytes of the document as characters.
# The SC_CP_UTF8 value can be used to enter Unicode mode. # The SC_CP_UTF8 value can be used to enter Unicode mode.
set void SetCodePage=2037(int codePage,) set void SetCodePage=2037(int codePage,)
@ -3844,3 +3841,9 @@ evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position) evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void) evt void AutoCCancelled=2025(void)
evt void AutoCCharDeleted=2026(void) evt void AutoCCharDeleted=2026(void)
cat Deprecated
# Deprecated in 2.21
# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
val SC_CP_DBCS=1

View File

@ -15,7 +15,7 @@
extern "C" { extern "C" {
#endif #endif
#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) #define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) #define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) #define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ())

View File

@ -188,6 +188,7 @@ struct OptionsCPP {
bool identifiersAllowDollars; bool identifiersAllowDollars;
bool trackPreprocessor; bool trackPreprocessor;
bool updatePreprocessor; bool updatePreprocessor;
bool fold;
bool foldComment; bool foldComment;
bool foldCommentExplicit; bool foldCommentExplicit;
bool foldPreprocessor; bool foldPreprocessor;
@ -198,6 +199,7 @@ struct OptionsCPP {
identifiersAllowDollars = true; identifiersAllowDollars = true;
trackPreprocessor = true; trackPreprocessor = true;
updatePreprocessor = true; updatePreprocessor = true;
fold = false;
foldComment = false; foldComment = false;
foldCommentExplicit = true; foldCommentExplicit = true;
foldPreprocessor = false; foldPreprocessor = false;
@ -231,6 +233,8 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor, DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
"Set to 1 to update preprocessor definitions when #define found."); "Set to 1 to update preprocessor definitions when #define found.");
DefineProperty("fold", &OptionsCPP::fold);
DefineProperty("fold.comment", &OptionsCPP::foldComment, DefineProperty("fold.comment", &OptionsCPP::foldComment,
"This option enables folding multi-line comments and explicit fold points when using the C++ lexer. " "This option enables folding multi-line comments and explicit fold points when using the C++ lexer. "
"Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} " "Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} "
@ -500,6 +504,8 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
} }
const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate. // Determine if the current state should terminate.
switch (sc.state & maskActivity) { switch (sc.state & maskActivity) {
case SCE_C_OPERATOR: case SCE_C_OPERATOR:
@ -657,6 +663,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
} }
if (sc.atLineEnd && !atLineEndBeforeSwitch) {
// State exit processing consumed characters up to end of line.
lineCurrent++;
vlls.Add(lineCurrent, preproc);
}
// Determine if a new state should be entered. // Determine if a new state should be entered.
if ((sc.state & maskActivity) == SCE_C_DEFAULT) { if ((sc.state & maskActivity) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) { if (sc.Match('@', '\"')) {
@ -800,6 +812,9 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
if (!options.fold)
return;
LexAccessor styler(pAccess); LexAccessor styler(pAccess);
unsigned int endPos = startPos + length; unsigned int endPos = startPos + length;
@ -962,9 +977,9 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens) {
else if (tokens[k+1] == "*") else if (tokens[k+1] == "*")
result = valA * valB; result = valA * valB;
else if (tokens[k+1] == "/") else if (tokens[k+1] == "/")
result = valA / valB; result = valA / (valB ? valB : 1);
else if (tokens[k+1] == "%") else if (tokens[k+1] == "%")
result = valA % valB; result = valA % (valB ? valB : 1);
else if (tokens[k+1] == "<") else if (tokens[k+1] == "<")
result = valA < valB; result = valA < valB;
else if (tokens[k+1] == "<=") else if (tokens[k+1] == "<=")

View File

@ -85,10 +85,8 @@ static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start,
char s[100]; char s[100];
GetTextSegment(styler, start, end, s, sizeof(s)); GetTextSegment(styler, start, end, s, sizeof(s));
//Platform::DebugPrintf("Scripting indicator [%s]\n", s); //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
//Don
//if (strstr(s, "src")) // External script //if (strstr(s, "src")) // External script
//return eScriptNone; //return eScriptNone;
//nod
if (strstr(s, "vbs")) if (strstr(s, "vbs"))
return eScriptVBS; return eScriptVBS;
if (strstr(s, "pyth")) if (strstr(s, "pyth"))
@ -420,16 +418,9 @@ static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler)
static int StateForScript(script_type scriptLanguage) { static int StateForScript(script_type scriptLanguage) {
int Result; int Result;
switch (scriptLanguage) { switch (scriptLanguage) {
// Modif by Don
/*
case eScriptVBS:
Result = SCE_HB_START;
break;
*/
case eScriptJS: case eScriptJS:
Result = SCE_HJ_START; Result = SCE_HJ_START;
break; break;
// Fidom by Don
case eScriptPython: case eScriptPython:
Result = SCE_HP_START; Result = SCE_HP_START;
break; break;
@ -446,10 +437,7 @@ static int StateForScript(script_type scriptLanguage) {
Result = SCE_H_COMMENT; Result = SCE_H_COMMENT;
break; break;
default : default :
// Modif by Don Result = SCE_HJ_START;
//Result = SCE_HJ_START;
Result = SCE_HB_START;
// Fidom by Don
break; break;
} }
return Result; return Result;
@ -627,7 +615,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int lineState; int lineState;
if (lineCurrent > 0) { if (lineCurrent > 0) {
lineState = styler.GetLineState(lineCurrent); lineState = styler.GetLineState(lineCurrent-1);
} else { } else {
// Default client and ASP scripting language is JavaScript // Default client and ASP scripting language is JavaScript
lineState = eScriptJS << 8; lineState = eScriptJS << 8;
@ -635,10 +623,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// property asp.default.language // property asp.default.language
// Script in ASP code is initially assumed to be in JavaScript. // Script in ASP code is initially assumed to be in JavaScript.
// To change this to VBScript set asp.default.language to 2. Python is 3. // To change this to VBScript set asp.default.language to 2. Python is 3.
// Don
//lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
lineState |= styler.GetPropertyInt("asp.default.language", eScriptVBS) << 4; lineState |= styler.GetPropertyInt("asp.default.language", eScriptVBS) << 4;
//nod
} }
script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
@ -813,8 +798,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
visibleChars = 0; visibleChars = 0;
levelPrev = levelCurrent; levelPrev = levelCurrent;
} }
lineCurrent++;
lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent, styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) | ((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) | ((tagOpened & 0x01) << 2) |
@ -822,6 +805,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
((aspScript & 0x0F) << 4) | ((aspScript & 0x0F) << 4) |
((clientScript & 0x0F) << 8) | ((clientScript & 0x0F) << 8) |
((beforePreProc & 0xFF) << 12)); ((beforePreProc & 0xFF) << 12));
lineCurrent++;
lineStartVisibleChars = 0;
} }
// Allow falling through to mako handling code if newline is going to end a block // Allow falling through to mako handling code if newline is going to end a block
@ -979,8 +964,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
beforeLanguage = scriptLanguage; beforeLanguage = scriptLanguage;
scriptLanguage = eScriptPython; scriptLanguage = eScriptPython;
styler.ColourTo(i, SCE_H_ASP); styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && chNext == '%')
levelCurrent++;
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue; continue;
@ -1107,9 +1090,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript; inScriptType = eNonHtmlScript;
else else
inScriptType = eHtml; inScriptType = eHtml;
if (foldHTMLPreprocessor) {
levelCurrent--;
}
scriptLanguage = beforeLanguage; scriptLanguage = beforeLanguage;
continue; continue;
} }
@ -1648,7 +1628,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i += 2; i += 2;
} else if (isLineEnd(ch)) { } else if (isLineEnd(ch)) {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_STRINGEOL; if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) {
state = SCE_HJ_STRINGEOL;
}
} }
break; break;
case SCE_HJ_STRINGEOL: case SCE_HJ_STRINGEOL:

View File

@ -7,6 +7,7 @@
* *
* Written by Tobias Engvall - tumm at dtek dot chalmers dot se * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
* *
* Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
* *
* TODO: * TODO:
* * Implement a folder :) * * Implement a folder :)
@ -48,11 +49,13 @@ using namespace Scintilla;
#endif #endif
// Max level of nested comments #define HA_MODE_DEFAULT 0
#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3 #define HA_MODE_IMPORT1 1
#define HA_MODE_IMPORT2 2
#define HA_MODE_IMPORT3 3
enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType}; #define HA_MODE_MODULE 4
#define HA_MODE_FFI 5
#define HA_MODE_TYPE 6
static inline bool IsNewline(const int ch) { static inline bool IsNewline(const int ch) {
return (ch == '\n' || ch == '\r'); return (ch == '\n' || ch == '\r');
@ -76,146 +79,234 @@ static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) { WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
WordList &ffi = *keywordlists[1];
int kwLast = kwOther;
StyleContext sc(startPos, length, initStyle, styler); StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) { int lineCurrent = styler.GetLine(startPos);
int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
: HA_MODE_DEFAULT;
int mode = state & 0xF;
int xmode = state >> 4;
while (sc.More()) {
// Check for state end // Check for state end
// Operator // Operator
if (sc.state == SCE_HA_OPERATOR) { if (sc.state == SCE_HA_OPERATOR) {
kwLast = kwOther; if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HA_DEFAULT); sc.Forward();
} else {
styler.ColourTo(sc.currentPos - 1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
}
} }
// String // String
else if (sc.state == SCE_HA_STRING) { else if (sc.state == SCE_HA_STRING) {
if (sc.ch == '\"') { if (sc.ch == '\"') {
sc.ForwardSetState(SCE_HA_DEFAULT); sc.Forward();
styler.ColourTo(sc.currentPos-1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') { } else if (sc.ch == '\\') {
sc.Forward(); sc.Forward(2);
} } else if (sc.atLineEnd) {
styler.ColourTo(sc.currentPos-1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} else {
sc.Forward();
}
} }
// Char // Char
else if (sc.state == SCE_HA_CHARACTER) { else if (sc.state == SCE_HA_CHARACTER) {
if (sc.ch == '\'') { if (sc.ch == '\'') {
sc.ForwardSetState(SCE_HA_DEFAULT); sc.Forward();
styler.ColourTo(sc.currentPos-1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') { } else if (sc.ch == '\\') {
sc.Forward(); sc.Forward(2);
} } else if (sc.atLineEnd) {
styler.ColourTo(sc.currentPos-1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} else {
sc.Forward();
}
} }
// Number // Number
else if (sc.state == SCE_HA_NUMBER) { else if (sc.state == SCE_HA_NUMBER) {
if (!IsADigit(sc.ch)) { if (IsADigit(sc.ch, xmode)) {
sc.SetState(SCE_HA_DEFAULT); sc.Forward();
} } else if ((xmode == 10) &&
} (sc.ch == 'e' || sc.ch == 'E') &&
// Types, constructors, etc. (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
else if (sc.state == SCE_HA_CAPITAL) { sc.Forward();
if (!IsAWordChar(sc.ch) || sc.ch == '.') { if (sc.ch == '+' || sc.ch == '-')
sc.SetState(SCE_HA_DEFAULT); sc.Forward();
} else {
styler.ColourTo(sc.currentPos - 1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} }
} }
// Identifier // Identifier
else if (sc.state == SCE_HA_IDENTIFIER) { else if (sc.state == SCE_HA_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) { if (IsAWordChar(sc.ch)) {
sc.Forward();
} else {
char s[100]; char s[100];
sc.GetCurrent(s, sizeof(s)); sc.GetCurrent(s, sizeof(s));
int style = SCE_HA_IDENTIFIER; int style = sc.state;
if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) { int new_mode = 0;
style = SCE_HA_IMPORT; if (keywords.InList(s)) {
} else if (keywords.InList(s)) {
style = SCE_HA_KEYWORD; style = SCE_HA_KEYWORD;
} else if (kwLast == kwData) {
style = SCE_HA_DATA;
} else if (kwLast == kwClass) {
style = SCE_HA_CLASS;
} else if (kwLast == kwModule) {
style = SCE_HA_MODULE;
} else if (isupper(s[0])) { } else if (isupper(s[0])) {
style = SCE_HA_CAPITAL; if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
} style = SCE_HA_MODULE;
sc.ChangeState(style); new_mode = HA_MODE_IMPORT2;
sc.SetState(SCE_HA_DEFAULT); } else if (mode == HA_MODE_MODULE)
if (style == SCE_HA_KEYWORD) { style = SCE_HA_MODULE;
if (0 == strcmp(s, "class"))
kwLast = kwClass;
else if (0 == strcmp(s, "data"))
kwLast = kwData;
else if (0 == strcmp(s, "instance"))
kwLast = kwInstance;
else if (0 == strcmp(s, "import"))
kwLast = kwImport;
else if (0 == strcmp(s, "module"))
kwLast = kwModule;
else else
kwLast = kwOther; style = SCE_HA_CAPITAL;
} else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT || } else if (mode == HA_MODE_IMPORT1 &&
style == SCE_HA_MODULE || style == SCE_HA_CAPITAL || strcmp(s,"qualified") == 0) {
style == SCE_HA_DATA || style == SCE_HA_INSTANCE) { style = SCE_HA_KEYWORD;
kwLast = kwOther; new_mode = HA_MODE_IMPORT1;
} else if (mode == HA_MODE_IMPORT2) {
if (strcmp(s,"as") == 0) {
style = SCE_HA_KEYWORD;
new_mode = HA_MODE_IMPORT3;
} else if (strcmp(s,"hiding") == 0) {
style = SCE_HA_KEYWORD;
}
} else if (mode == HA_MODE_FFI) {
if (ffi.InList(s)) {
style = SCE_HA_KEYWORD;
new_mode = HA_MODE_FFI;
}
} }
else if (mode == HA_MODE_TYPE) {
if (strcmp(s,"family") == 0)
style = SCE_HA_KEYWORD;
}
styler.ColourTo(sc.currentPos - 1, style);
if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
new_mode = HA_MODE_IMPORT1;
else if (strcmp(s,"module") == 0)
new_mode = HA_MODE_MODULE;
else if (strcmp(s,"foreign") == 0)
new_mode = HA_MODE_FFI;
else if (strcmp(s,"type") == 0)
new_mode = HA_MODE_TYPE;
sc.ChangeState(SCE_HA_DEFAULT);
mode = new_mode;
} }
} }
// Comments // Comments
// Oneliner // Oneliner
else if (sc.state == SCE_HA_COMMENTLINE) { else if (sc.state == SCE_HA_COMMENTLINE) {
if (IsNewline(sc.ch)) if (sc.atLineEnd) {
sc.SetState(SCE_HA_DEFAULT); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
} else {
sc.Forward();
}
} }
// Nested // Nested
else if (sc.state >= SCE_HA_COMMENTBLOCK) { else if (sc.state == SCE_HA_COMMENTBLOCK) {
if (sc.Match("{-")) { if (sc.Match("{-")) {
if (sc.state < SCE_HA_COMMENTMAX) sc.Forward(2);
sc.SetState(sc.state + 1); xmode++;
} }
else if (sc.Match("-}")) { else if (sc.Match("-}")) {
sc.Forward(2);
xmode--;
if (xmode == 0) {
styler.ColourTo(sc.currentPos - 1, sc.state);
sc.ChangeState(SCE_HA_DEFAULT);
}
} else {
if (sc.atLineEnd) {
// Remember the line state for future incremental lexing
styler.SetLineState(lineCurrent, (xmode << 4) | mode);
lineCurrent++;
}
sc.Forward(); sc.Forward();
if (sc.state == SCE_HA_COMMENTBLOCK)
sc.ForwardSetState(SCE_HA_DEFAULT);
else
sc.ForwardSetState(sc.state - 1);
} }
} }
// New state? // New state?
if (sc.state == SCE_HA_DEFAULT) { if (sc.state == SCE_HA_DEFAULT) {
// Digit // Digit
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (IsADigit(sc.ch) ||
sc.SetState(SCE_HA_NUMBER); (sc.ch == '.' && IsADigit(sc.chNext)) ||
if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too (sc.ch == '-' && IsADigit(sc.chNext))) {
sc.Forward(1); styler.ColourTo(sc.currentPos - 1, sc.state);
} sc.ChangeState(SCE_HA_NUMBER);
if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
// Match anything starting with "0x" or "0X", too
sc.Forward(2);
xmode = 16;
} else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
// Match anything starting with "0x" or "0X", too
sc.Forward(2);
xmode = 8;
} else {
sc.Forward();
xmode = 10;
}
mode = HA_MODE_DEFAULT;
} }
// Comment line // Comment line
else if (sc.Match("--")) { else if (sc.Match("--")) {
sc.SetState(SCE_HA_COMMENTLINE); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward(2);
sc.ChangeState(SCE_HA_COMMENTLINE);
// Comment block // Comment block
} }
else if (sc.Match("{-")) { else if (sc.Match("{-")) {
sc.SetState(SCE_HA_COMMENTBLOCK); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward(2);
sc.ChangeState(SCE_HA_COMMENTBLOCK);
xmode = 1;
} }
// String // String
else if (sc.Match('\"')) { else if (sc.Match('\"')) {
sc.SetState(SCE_HA_STRING); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward();
sc.ChangeState(SCE_HA_STRING);
} }
// Character // Character
else if (sc.Match('\'')) { else if (sc.Match('\'')) {
sc.SetState(SCE_HA_CHARACTER); styler.ColourTo(sc.currentPos - 1, sc.state);
} sc.Forward();
// Stringstart sc.ChangeState(SCE_HA_CHARACTER);
else if (sc.Match('\"')) {
sc.SetState(SCE_HA_STRING);
} }
else if (sc.ch == '(' || sc.ch == ')' ||
sc.ch == '{' || sc.ch == '}' ||
sc.ch == '[' || sc.ch == ']') {
styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward();
styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
mode = HA_MODE_DEFAULT;
}
// Operator // Operator
else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) { else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HA_OPERATOR); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward();
sc.ChangeState(SCE_HA_OPERATOR);
mode = HA_MODE_DEFAULT;
} }
// Keyword // Keyword
else if (IsAWordStart(sc.ch)) { else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_HA_IDENTIFIER); styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward();
sc.ChangeState(SCE_HA_IDENTIFIER);
} else {
if (sc.atLineEnd) {
// Remember the line state for future incremental lexing
styler.SetLineState(lineCurrent, (xmode << 4) | mode);
lineCurrent++;
}
sc.Forward();
} }
} }
} }
sc.Complete(); sc.Complete();
@ -275,4 +366,3 @@ void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
#endif #endif
LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell"); LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");

View File

@ -103,9 +103,9 @@ static void SetStateAndZoom(const int state, const int length, const int token,
static bool HasPrevLineContent(StyleContext &sc) { static bool HasPrevLineContent(StyleContext &sc) {
int i = 0; int i = 0;
// Go back to the previous newline // Go back to the previous newline
while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
; ;
while (--i + sc.currentPos) { while ((--i + (int)sc.currentPos) >= 0) {
if (IsNewline(sc.GetRelative(i))) if (IsNewline(sc.GetRelative(i)))
break; break;
if (!IsASpaceOrTab(sc.GetRelative(i))) if (!IsASpaceOrTab(sc.GetRelative(i)))

View File

@ -324,10 +324,10 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
int styleNext = styler.StyleAt(startPos); int styleNext = styler.StyleAt(startPos);
int style = initStyle; int style = initStyle;
bool endFound = false; bool endPending = false;
bool whenFound = false; bool whenPending = false;
bool elseFound = false; bool elseIfPending = false;
char nextChar = styler.SafeGetCharAt(startPos); char nextChar = styler.SafeGetCharAt(startPos);
for (unsigned int i = startPos; length > 0; i++, length--) for (unsigned int i = startPos; length > 0; i++, length--)
@ -335,11 +335,11 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
int stylePrev = style; int stylePrev = style;
style = styleNext; style = styleNext;
styleNext = styler.StyleAt(i + 1); styleNext = styler.StyleAt(i + 1);
char currentChar = nextChar; char currentChar = nextChar;
nextChar = styler.SafeGetCharAt(i + 1); nextChar = styler.SafeGetCharAt(i + 1);
bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n'); bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
switch (style) switch (style)
{ {
case SCE_MYSQL_COMMENT: case SCE_MYSQL_COMMENT:
@ -361,7 +361,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
break; break;
case SCE_MYSQL_COMMENTLINE: case SCE_MYSQL_COMMENTLINE:
if (foldComment) if (foldComment)
{ {
// Not really a standard, but we add support for single line comments // Not really a standard, but we add support for single line comments
// with special curly braces syntax as foldable comments too. // with special curly braces syntax as foldable comments too.
// MySQL needs -- comments to be followed by space or control char // MySQL needs -- comments to be followed by space or control char
@ -378,18 +378,42 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
} }
break; break;
case SCE_MYSQL_HIDDENCOMMAND: case SCE_MYSQL_HIDDENCOMMAND:
if (endPending)
{
// A conditional command is not a white space so it should end the current block
// before opening a new one.
endPending = false;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
if (style != stylePrev) if (style != stylePrev)
levelNext++; levelNext++;
else else
if (style != styleNext) if (style != styleNext)
{
levelNext--; levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
break; break;
case SCE_MYSQL_OPERATOR: case SCE_MYSQL_OPERATOR:
if (endPending)
{
endPending = false;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
if (currentChar == '(') if (currentChar == '(')
levelNext++; levelNext++;
else else
if (currentChar == ')') if (currentChar == ')')
{
levelNext--; levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
break; break;
case SCE_MYSQL_MAJORKEYWORD: case SCE_MYSQL_MAJORKEYWORD:
case SCE_MYSQL_KEYWORD: case SCE_MYSQL_KEYWORD:
@ -398,110 +422,98 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
// Reserved and other keywords. // Reserved and other keywords.
if (style != stylePrev) if (style != stylePrev)
{ {
bool beginFound = MatchIgnoreCase(styler, i, "begin"); // END decreases the folding level, regardless which keyword follows.
bool ifFound = MatchIgnoreCase(styler, i, "if"); bool endFound = MatchIgnoreCase(styler, i, "end");
bool thenFound = MatchIgnoreCase(styler, i, "then"); if (endPending)
bool whileFound = MatchIgnoreCase(styler, i, "while");
bool loopFound = MatchIgnoreCase(styler, i, "loop");
bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
{ {
endFound = false;
levelNext--; levelNext--;
if (levelNext < SC_FOLDLEVELBASE) if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE; levelNext = SC_FOLDLEVELBASE;
// Note that "else" is special here. It may or may not be followed by an "if .. then",
// but in any case the level stays the same. When followed by an "if .. then" the level
// will be increased later, if not, then at eol.
} }
else else
if (!foldOnlyBegin && MatchIgnoreCase(styler, i, "else")) if (!endFound)
{ {
levelNext--; if (MatchIgnoreCase(styler, i, "begin"))
elseFound = true; levelNext++;
}
else
if (!foldOnlyBegin && thenFound)
{
if (whenFound)
whenFound = false;
else
levelNext++;
}
else else
if (ifFound) {
elseFound = false; if (!foldOnlyBegin)
else {
if (MatchIgnoreCase(styler, i, "when")) bool whileFound = MatchIgnoreCase(styler, i, "while");
whenFound = true; bool loopFound = MatchIgnoreCase(styler, i, "loop");
bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
bool caseFound = MatchIgnoreCase(styler, i, "case");
if (whileFound || loopFound || repeatFound || caseFound)
levelNext++;
else else
{ {
if (beginFound) // IF alone does not increase the fold level as it is also used in non-block'ed
levelNext++; // code like DROP PROCEDURE blah IF EXISTS.
else // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch).
if (!foldOnlyBegin && (loopFound || repeatFound || whileFound)) if (MatchIgnoreCase(styler, i, "then"))
{ {
if (endFound) if (!elseIfPending && !whenPending)
endFound = false; levelNext++;
else
levelNext++;
}
else else
if (MatchIgnoreCase(styler, i, "end")) {
{ elseIfPending = false;
// Multiple "end" in a row are counted multiple times! whenPending = false;
if (endFound) }
{ }
levelNext--; else
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE; // Neither of if/then/while/loop/repeat/case, so check for
} // sub parts of IF and CASE.
endFound = true; if (MatchIgnoreCase(styler, i, "elseif"))
whenFound = false; elseIfPending = true;
} if (MatchIgnoreCase(styler, i, "when"))
whenPending = true;
}
} }
}
}
}
// Keep the current end state for the next round.
endPending = endFound;
}
break;
default:
if (!isspace(currentChar) && endPending)
{
// END followed by a non-whitespace character (not covered by other cases like identifiers)
// also should end a folding block. Typical case: END followed by self defined delimiter.
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
} }
break; break;
} }
// Handle the case of a trailing end without an if / while etc, as in the case of a begin. if (atEOL)
if (endFound)
{ {
endFound = false; // Apply the new folding level to this line.
levelNext--; // Leave pending states as they are otherwise a line break will de-sync
if (levelNext < SC_FOLDLEVELBASE) // code folding and valid syntax.
levelNext = SC_FOLDLEVELBASE; int levelUse = levelCurrent;
} int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
if (atEOL) lev |= SC_FOLDLEVELWHITEFLAG;
{ if (levelUse < levelNext)
if (elseFound) lev |= SC_FOLDLEVELHEADERFLAG;
{ if (lev != styler.LevelAt(lineCurrent))
levelNext++; styler.SetLevel(lineCurrent, lev);
elseFound = false;
} lineCurrent++;
levelCurrent = levelNext;
int levelUse = levelCurrent; visibleChars = 0;
int lev = levelUse | levelNext << 16; }
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
levelCurrent = levelNext;
visibleChars = 0;
endFound = false;
whenFound = false;
}
if (!isspacechar(currentChar)) if (!isspacechar(currentChar))
visibleChars++; visibleChars++;
} }
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -12,23 +12,23 @@
// 2008-10-25 - Initial release // 2008-10-25 - Initial release
// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that // 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that
// local isFunction = "" and local functions = "" don't get falsely highlighted // local isFunction = "" and local functions = "" don't get falsely highlighted
// 2008-12-14 - Added bounds checking for szKeyword and szDo // 2008-12-14 - Added bounds checking for szFirstWord and szDo
// - Replaced SetOfCharacters with CharacterSet // - Replaced SetOfCharacters with CharacterSet
// - Made sure that CharacterSet::Contains is passed only positive values // - Made sure that CharacterSet::Contains is passed only positive values
// - Made sure that the return value of Accessor::SafeGetCharAt is positive before // - Made sure that the return value of Accessor::SafeGetCharAt is positive before
// passsing to functions that require positive values like isspacechar() // passing to functions that require positive values like isspacechar()
// - Removed unused visibleChars processing from ColourisePowerProDoc() // - Removed unused visibleChars processing from ColourisePowerProDoc()
// - Fixed bug with folding logic where line continuations didn't end where // - Fixed bug with folding logic where line continuations didn't end where
// they were supposed to // they were supposed to
// - Moved all helper functions to the top of the file // - Moved all helper functions to the top of the file
// // 2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented
// - Modified HasFunction function to be a bit more robust
// - Renamed HasFunction function to IsFunction
// - Cleanup
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// 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.
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
@ -36,7 +36,6 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h" #include "WordList.h"
#include "LexAccessor.h" #include "LexAccessor.h"
#include "Accessor.h" #include "Accessor.h"
@ -52,65 +51,81 @@ static inline bool IsStreamCommentStyle(int style) {
return style == SCE_POWERPRO_COMMENTBLOCK; return style == SCE_POWERPRO_COMMENTBLOCK;
} }
static inline bool IsLineEndChar(unsigned char ch) {
return ch == 0x0a //LF
|| ch == 0x0c //FF
|| ch == 0x0d; //CR
}
static bool IsContinuationLine(unsigned int szLine, Accessor &styler) static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{ {
int nsPos = styler.LineStart(szLine); int startPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine + 1) - 2; int endPos = styler.LineStart(szLine + 1) - 2;
while (nsPos < nePos) while (startPos < endPos)
{ {
int stylech = styler.StyleAt(nsPos); char stylech = styler.StyleAt(startPos);
if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) { if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
char ch = styler.SafeGetCharAt(nePos); char ch = styler.SafeGetCharAt(endPos);
char chPrev = styler.SafeGetCharAt(nePos-1); char chPrev = styler.SafeGetCharAt(endPos - 1);
char chPrevPrev = styler.SafeGetCharAt(nePos-2); char chPrevPrev = styler.SafeGetCharAt(endPos - 2);
if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) { if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) )
if (chPrevPrev == ';' && chPrev == ';' && ch == '+') return (chPrevPrev == ';' && chPrev == ';' && ch == '+');
return true;
else
return false;
} }
} endPos--; // skip to next char
nePos--; // skip to next char
} }
return false; return false;
} }
// Routine to find first none space on the current line and return its Style // Routine to find first none space on the current line and return its Style
// needed for comment lines not starting on pos 1 // needed for comment lines not starting on pos 1
static int GetStyleFirstWord(unsigned int szLine, Accessor &styler) static int GetStyleFirstWord(int szLine, Accessor &styler)
{ {
int nsPos = styler.LineStart(szLine); int startPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine+1) - 1; int endPos = styler.LineStart(szLine + 1) - 1;
char ch = styler.SafeGetCharAt(nsPos); char ch = styler.SafeGetCharAt(startPos);
while (ch > 0 && isspacechar(ch) && nsPos < nePos) while (ch > 0 && isspacechar(ch) && startPos < endPos)
{ {
nsPos++; // skip to next char startPos++; // skip to next char
ch = styler.SafeGetCharAt(nsPos); ch = styler.SafeGetCharAt(startPos);
} }
return styler.StyleAt(nsPos); return styler.StyleAt(startPos);
} }
//returns true if there is a function to highlight //returns true if there is a function to highlight
//used to highlight <name> in 'function <name>' //used to highlight <name> in 'function <name>'
static bool HasFunction(Accessor &styler, unsigned int currentPos) { //note:
// sample line (without quotes): "\tfunction asdf()
// currentPos will be the position of 'a'
static bool IsFunction(Accessor &styler, unsigned int currentPos) {
//check for presence of 'function ' const char function[10] = "function "; //10 includes \0
return (styler.SafeGetCharAt(currentPos) == ' ' unsigned int numberOfCharacters = sizeof(function) - 1;
&& tolower(styler.SafeGetCharAt(currentPos-1)) == 'n' unsigned int position = currentPos - numberOfCharacters;
&& tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
&& tolower(styler.SafeGetCharAt(currentPos-3)) == 'i' //compare each character with the letters in the function array
&& tolower(styler.SafeGetCharAt(currentPos-4)) == 't' //return false if ALL don't match
&& tolower(styler.SafeGetCharAt(currentPos-5)) == 'c' for (unsigned int i = 0; i < numberOfCharacters; i++) {
&& tolower(styler.SafeGetCharAt(currentPos-6)) == 'n' char c = styler.SafeGetCharAt(position++);
&& tolower(styler.SafeGetCharAt(currentPos-7)) == 'u' if (c != function[i])
&& tolower(styler.SafeGetCharAt(currentPos-8)) == 'f' return false;
//only allow 'function ' to appear at the beginning of a line }
&& (styler.SafeGetCharAt(currentPos-9) == '\n'
|| styler.SafeGetCharAt(currentPos-9) == '\r' //make sure that there are only spaces (or tabs) between the beginning
|| (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line //of the line and the function declaration
); position = currentPos - numberOfCharacters - 1; //-1 to move to char before 'function'
for (unsigned int j = 0; j < 16; j++) { //check up to 16 preceeding characters
char c = styler.SafeGetCharAt(position--, '\0'); //if can't read char, return NUL (past beginning of document)
if (c <= 0) //reached beginning of document
return true;
if (c > 0 && IsLineEndChar(c))
return true;
else if (c > 0 && !IsASpaceOrTab(c))
return false;
}
//fall-through
return false;
} }
static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@ -128,9 +143,11 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
StyleContext sc(startPos, length, initStyle, styler); StyleContext sc(startPos, length, initStyle, styler);
char s_save[100]; //for last line highlighting char s_save[100]; //for last line highlighting
//are there only spaces between the first letter of the line and the beginning of the line
bool onlySpaces = true;
for (; sc.More(); sc.Forward()) { for (; sc.More(); sc.Forward()) {
// **********************************************
// save the total current word for eof processing // save the total current word for eof processing
char s[100]; char s[100];
sc.GetCurrentLowered(s, sizeof(s)); sc.GetCurrentLowered(s, sizeof(s));
@ -144,8 +161,6 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
s_save[tp+1] = '\0'; s_save[tp+1] = '\0';
} }
} }
// **********************************************
//
if (sc.atLineStart) { if (sc.atLineStart) {
if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) { if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
@ -177,6 +192,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
} else { } else {
sc.GetCurrentLowered(s, sizeof(s)); sc.GetCurrentLowered(s, sizeof(s));
} }
if (keywords.InList(s)) { if (keywords.InList(s)) {
sc.ChangeState(SCE_POWERPRO_WORD); sc.ChangeState(SCE_POWERPRO_WORD);
} else if (keywords2.InList(s)) { } else if (keywords2.InList(s)) {
@ -262,7 +278,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
break; break;
case SCE_POWERPRO_FUNCTION: case SCE_POWERPRO_FUNCTION:
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') { if (isspacechar(sc.ch) || sc.ch == '(') {
sc.SetState(SCE_POWERPRO_DEFAULT); sc.SetState(SCE_POWERPRO_DEFAULT);
} }
break; break;
@ -280,9 +296,9 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.SetState(SCE_POWERPRO_ALTQUOTE); sc.SetState(SCE_POWERPRO_ALTQUOTE);
sc.Forward(); sc.Forward();
} }
} else if (HasFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>' } else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
sc.SetState(SCE_POWERPRO_FUNCTION); sc.SetState(SCE_POWERPRO_FUNCTION);
} else if (sc.ch == '@' && sc.atLineStart) { //alternate function definition [label] } else if (onlySpaces && sc.ch == '@') { //alternate function definition [label]
sc.SetState(SCE_POWERPRO_FUNCTION); sc.SetState(SCE_POWERPRO_FUNCTION);
} else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) { } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
sc.SetState(SCE_POWERPRO_IDENTIFIER); sc.SetState(SCE_POWERPRO_IDENTIFIER);
@ -293,7 +309,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.Forward(); // Eat the * so it isn't used for the end of the comment sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) { } else if (sc.Match('/', '/')) {
sc.SetState(SCE_POWERPRO_COMMENTLINE); sc.SetState(SCE_POWERPRO_COMMENTLINE);
} else if (sc.atLineStart && sc.ch == ';') { //legacy comment that can only appear at the beginning of a line } else if (onlySpaces && sc.ch == ';') { //legacy comment that can only have blank space in front of it
sc.SetState(SCE_POWERPRO_COMMENTLINE); sc.SetState(SCE_POWERPRO_COMMENTLINE);
} else if (sc.Match(";;")) { } else if (sc.Match(";;")) {
sc.SetState(SCE_POWERPRO_COMMENTLINE); sc.SetState(SCE_POWERPRO_COMMENTLINE);
@ -305,6 +321,15 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.SetState(SCE_POWERPRO_OPERATOR); sc.SetState(SCE_POWERPRO_OPERATOR);
} }
} }
//maintain a record of whether or not all the preceding characters on
//a line are space characters
if (onlySpaces && !IsASpaceOrTab(sc.ch))
onlySpaces = false;
//reset when starting a new line
if (sc.atLineEnd)
onlySpaces = true;
} }
//************************************* //*************************************
@ -341,7 +366,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function) //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
bool isFoldingAll = true;
int endPos = startPos + length; int endPos = startPos + length;
int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
@ -364,31 +391,32 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
int stylePrev = 0; int stylePrev = 0;
// find the first previous line without continuation character at the end // find the first previous line without continuation character at the end
while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) || while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler))
(lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) { || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) {
lineCurrent--; lineCurrent--;
startPos = styler.LineStart(lineCurrent); startPos = styler.LineStart(lineCurrent);
} }
if (lineCurrent > 0) { if (lineCurrent > 0) {
stylePrev = GetStyleFirstWord(lineCurrent-1,styler); stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
} }
// vars for getting first word to check for keywords
bool FirstWordStart = false;
bool FirstWordEnd = false;
const unsigned int KEYWORD_MAX = 10; // vars for getting first word to check for keywords
char szKeyword[KEYWORD_MAX]=""; bool isFirstWordStarted = false;
unsigned int szKeywordlen = 0; bool isFirstWordEnded = false;
const unsigned int FIRST_WORD_MAX_LEN = 10;
char szFirstWord[FIRST_WORD_MAX_LEN] = "";
unsigned int firstWordLen = 0;
char szDo[3]=""; char szDo[3]="";
int szDolen = 0; int szDolen = 0;
bool DoFoundLast = false; bool isDoLastWord = false;
// var for indentlevel // var for indentlevel
int levelCurrent = SC_FOLDLEVELBASE; int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) { if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
}
int levelNext = levelCurrent; int levelNext = levelCurrent;
int visibleChars = 0; int visibleChars = 0;
@ -404,52 +432,52 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if ((ch > 0) && setWord.Contains(ch)) { if ((ch > 0) && setWord.Contains(ch))
visibleChars++; visibleChars++;
}
// get the syle for the current character neede to check in comment // get the syle for the current character neede to check in comment
int stylech = styler.StyleAt(i); int stylech = styler.StyleAt(i);
// get first word for the line for indent check max 9 characters // start the capture of the first word
if (FirstWordStart && (!(FirstWordEnd))) { if (!isFirstWordStarted && (ch > 0)) {
if ((ch > 0) && !setWord.Contains(ch)) { if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') {
FirstWordEnd = true; isFirstWordStarted = true;
if (firstWordLen < FIRST_WORD_MAX_LEN - 1) {
szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
szFirstWord[firstWordLen] = '\0';
}
} }
else if (szKeywordlen < KEYWORD_MAX - 1) { } // continue capture of the first word on the line
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch)); else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) {
szKeyword[szKeywordlen] = '\0'; if (!setWord.Contains(ch)) {
isFirstWordEnded = true;
}
else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) {
szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
szFirstWord[firstWordLen] = '\0';
} }
} }
// start the capture of the first word
if (!(FirstWordStart)) {
if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
FirstWordStart = true;
if (szKeywordlen < KEYWORD_MAX - 1) {
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
szKeyword[szKeywordlen] = '\0';
}
}
}
// only process this logic when not in comment section
if (stylech != SCE_POWERPRO_COMMENTLINE) { if (stylech != SCE_POWERPRO_COMMENTLINE) {
if (DoFoundLast) {
if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) { //reset isDoLastWord if we find a character(ignoring spaces) after 'do'
DoFoundLast = false; if (isDoLastWord && (ch > 0) && setWord.Contains(ch))
} isDoLastWord = false;
}
// find out if the word "do" is the last on a "if" line // --find out if the word "do" is the last on a "if" line--
if (FirstWordEnd && strcmp(szKeyword,"if") == 0) { // collect each letter and put it into a buffer 2 chars long
// if we end up with "do" in the buffer when we reach the end of
// the line, "do" was the last word on the line
if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) {
if (szDolen == 2) { if (szDolen == 2) {
szDo[0] = szDo[1]; szDo[0] = szDo[1];
szDo[1] = static_cast<char>(tolower(ch)); szDo[1] = static_cast<char>(tolower(ch));
szDo[2] = '\0'; szDo[2] = '\0';
if (strcmp(szDo,"do") == 0 ) {
DoFoundLast = true; if (strcmp(szDo, "do") == 0)
} isDoLastWord = true;
}
else if (szDolen < 2) { } else if (szDolen < 2) {
szDo[szDolen++] = static_cast<char>(tolower(ch)); szDo[szDolen++] = static_cast<char>(tolower(ch));
szDo[szDolen] = '\0'; szDo[szDolen] = '\0';
} }
@ -457,7 +485,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
} }
// End of Line found so process the information // End of Line found so process the information
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { if ((ch == '\r' && chNext != '\n') // \r\n
|| ch == '\n' // \n
|| i == endPos) { // end of selection
// ************************** // **************************
// Folding logic for Keywords // Folding logic for Keywords
@ -465,24 +495,23 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
// if a keyword is found on the current line and the line doesn't end with ;;+ (continuation) // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
// and we are not inside a commentblock. // and we are not inside a commentblock.
if (szKeywordlen > 0 && if (firstWordLen > 0
(!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) && && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';'
((!(IsStreamCommentStyle(style)) || foldInComment)) ) { && (!IsStreamCommentStyle(style) || foldInComment) ) {
// only fold "if" last keyword is "then" (else its a one line if) // only fold "if" last keyword is "then" (else its a one line if)
if (strcmp(szKeyword,"if") == 0 && DoFoundLast) { if (strcmp(szFirstWord, "if") == 0 && isDoLastWord)
levelNext++; levelNext++;
}
// create new fold for these words // create new fold for these words
if (strcmp(szKeyword,"for") == 0) { if (strcmp(szFirstWord, "for") == 0)
levelNext++; levelNext++;
}
//handle folding for functions/labels //handle folding for functions/labels
//Note: Functions and labels don't have an explicit end like [end function] //Note: Functions and labels don't have an explicit end like [end function]
// 1. functions/labels end at the start of another function // 1. functions/labels end at the start of another function
// 2. functions/labels end at the end of the file // 2. functions/labels end at the end of the file
if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) { if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) {
if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script) if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
if (functionCount > 0) { if (functionCount > 0) {
@ -498,14 +527,15 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
} }
// end the fold for these words before the current line // end the fold for these words before the current line
if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) { if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) {
levelNext--; levelNext--;
levelCurrent--; levelCurrent--;
} }
// end the fold for these words before the current line and Start new fold // end the fold for these words before the current line and Start new fold
if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) { if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 )
levelCurrent--; levelCurrent--;
}
} }
// Preprocessor and Comment folding // Preprocessor and Comment folding
int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
@ -514,20 +544,19 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
// Folding logic for Comment blocks // Folding logic for Comment blocks
// ********************************* // *********************************
if (foldComment && IsStreamCommentStyle(style)) { if (foldComment && IsStreamCommentStyle(style)) {
// Start of a comment block // Start of a comment block
if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) { if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) {
levelNext++; levelNext++;
} } // fold till the last line for normal comment lines
// fold till the last line for normal comment lines
else if (IsStreamCommentStyle(stylePrev) else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_POWERPRO_COMMENTLINE) && styleNext != SCE_POWERPRO_COMMENTLINE
&& stylePrev == SCE_POWERPRO_COMMENTLINE && stylePrev == SCE_POWERPRO_COMMENTLINE
&& style == SCE_POWERPRO_COMMENTLINE) { && style == SCE_POWERPRO_COMMENTLINE) {
levelNext--; levelNext--;
} } // fold till the one but last line for Blockcomment lines
// fold till the one but last line for Blockcomment lines
else if (IsStreamCommentStyle(stylePrev) else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_POWERPRO_COMMENTBLOCK) && styleNext != SCE_POWERPRO_COMMENTBLOCK
&& style == SCE_POWERPRO_COMMENTBLOCK) { && style == SCE_POWERPRO_COMMENTBLOCK) {
levelNext--; levelNext--;
levelCurrent--; levelCurrent--;
@ -538,12 +567,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
int lev = levelUse | levelNext << 16; int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact) if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext) { if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG; lev |= SC_FOLDLEVELHEADERFLAG;
} if (lev != styler.LevelAt(lineCurrent))
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev); styler.SetLevel(lineCurrent, lev);
}
// reset values for the next line // reset values for the next line
lineCurrent++; lineCurrent++;
@ -553,18 +580,16 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
visibleChars = 0; visibleChars = 0;
// if the last characters are ;;+ then don't reset since the line continues on the next line. // if the last characters are ;;+ then don't reset since the line continues on the next line.
if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') { if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {
//do nothing firstWordLen = 0;
} else {
szKeywordlen = 0;
szDolen = 0; szDolen = 0;
FirstWordStart = false; isFirstWordStarted = false;
FirstWordEnd = false; isFirstWordEnded = false;
DoFoundLast = false; isDoLastWord = false;
//blank out keyword
for (unsigned int i = 0; i < KEYWORD_MAX; i++) { //blank out first word
szKeyword[i] = '\0'; for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++)
} szFirstWord[i] = '\0';
} }
} }
@ -573,7 +598,6 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
chPrevPrevPrev = chPrevPrev; chPrevPrevPrev = chPrevPrev;
chPrevPrev = chPrev; chPrevPrev = chPrev;
chPrev = ch; chPrev = ch;
visibleChars++;
} }
} }
@ -602,3 +626,5 @@ static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int i
} }
LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists); LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);

View File

@ -30,7 +30,7 @@ using namespace Scintilla;
// Extended to accept accented characters // Extended to accept accented characters
static inline bool IsAWordChar(int ch) { static inline bool IsAWordChar(int ch) {
return ch >= 0x80 || isalnum(ch) || ch == '-'; return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
} }
static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle, static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,

View File

@ -49,7 +49,9 @@ void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initS
} }
void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) { void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
Accessor astyler(pAccess, &props); if (props.GetInt("fold")) {
module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler); Accessor astyler(pAccess, &props);
astyler.Flush(); module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
astyler.Flush();
}
} }

View File

@ -74,6 +74,7 @@ public:
} }
void Complete() { void Complete() {
styler.ColourTo(currentPos - 1, state); styler.ColourTo(currentPos - 1, state);
styler.Flush();
} }
bool More() const { bool More() const {
return currentPos < endPos; return currentPos < endPos;

View File

@ -26,7 +26,7 @@ extern "C" HIViewRef scintilla_calltip_new(void);
// required for paste/dragdrop, see comment in paste function below // required for paste/dragdrop, see comment in paste function below
static int BOMlen(unsigned char *cstr) { static int BOMlen(unsigned char *cstr) {
switch(cstr[0]) { switch(cstr[0]) {
case 0xEF: // BOM_UTF8 case 0xEF: // BOM_UTF8
if (cstr[1] == 0xBB && cstr[2] == 0xBF) { if (cstr[1] == 0xBB && cstr[2] == 0xBF) {
return 3; return 3;
@ -201,7 +201,7 @@ ScintillaMacOSX::ScintillaMacOSX( void* windowid ) :
err = SetControlProperty( hScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr ); err = SetControlProperty( hScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr );
assert( err == noErr ); assert( err == noErr );
// set this into our parent control so we can be retrieved easily at a later time // set this into our parent control so we can be retrieved easily at a later time
// (see scintilla_send below) // (see scintilla_send below)
err = SetControlProperty( reinterpret_cast<HIViewRef>( windowid ), scintillaMacOSType, 0, sizeof( this ), &objectPtr ); err = SetControlProperty( reinterpret_cast<HIViewRef>( windowid ), scintillaMacOSType, 0, sizeof( this ), &objectPtr );
assert( err == noErr ); assert( err == noErr );
@ -217,14 +217,14 @@ ScintillaMacOSX::ScintillaMacOSX( void* windowid ) :
{ kEventClassCommand, kEventCommandUpdateStatus }, { kEventClassCommand, kEventCommandUpdateStatus },
}; };
err = InstallEventHandler( GetControlEventTarget( reinterpret_cast<HIViewRef>( windowid ) ), err = InstallEventHandler( GetControlEventTarget( reinterpret_cast<HIViewRef>( windowid ) ),
CommandEventHandler, CommandEventHandler,
GetEventTypeCount( commandEventInfo ), GetEventTypeCount( commandEventInfo ),
commandEventInfo, commandEventInfo,
this, NULL); this, NULL);
#ifdef EXT_INPUT #ifdef EXT_INPUT
ExtInput::attach (GetViewRef()); ExtInput::attach (GetViewRef());
for (int i = 0; macMapDefault[i].key; i++) for (int i = 0; macMapDefault[i].key; i++)
{ {
this->kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); this->kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg);
} }
@ -267,46 +267,46 @@ Boolean IsDropInFinderTrash(AEDesc *dropLocation)
CInfoPBRec thePB; CInfoPBRec thePB;
short trashVRefNum; short trashVRefNum;
long trashDirID; long trashDirID;
// Coerce the dropLocation descriptor into an FSSpec. If there's no dropLocation or // Coerce the dropLocation descriptor into an FSSpec. If there's no dropLocation or
// it can't be coerced into an FSSpec, then it couldn't have been the Trash. // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
if ((dropLocation->descriptorType != typeNull) && if ((dropLocation->descriptorType != typeNull) &&
(AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr)) (AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr))
{ {
unsigned char flags = HGetState((Handle)dropSpec.dataHandle); unsigned char flags = HGetState((Handle)dropSpec.dataHandle);
HLock((Handle)dropSpec.dataHandle); HLock((Handle)dropSpec.dataHandle);
theSpec = (FSSpec *) *dropSpec.dataHandle; theSpec = (FSSpec *) *dropSpec.dataHandle;
// Get the directory ID of the given dropLocation object. // Get the directory ID of the given dropLocation object.
thePB.dirInfo.ioCompletion = 0L; thePB.dirInfo.ioCompletion = 0L;
thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name; thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
thePB.dirInfo.ioVRefNum = theSpec->vRefNum; thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
thePB.dirInfo.ioFDirIndex = 0; thePB.dirInfo.ioFDirIndex = 0;
thePB.dirInfo.ioDrDirID = theSpec->parID; thePB.dirInfo.ioDrDirID = theSpec->parID;
result = PBGetCatInfoSync(&thePB); result = PBGetCatInfoSync(&thePB);
HSetState((Handle)dropSpec.dataHandle, flags); HSetState((Handle)dropSpec.dataHandle, flags);
AEDisposeDesc(&dropSpec); AEDisposeDesc(&dropSpec);
if (result != noErr) if (result != noErr)
return false; return false;
// If the result is not a directory, it must not be the Trash. // If the result is not a directory, it must not be the Trash.
if (!(thePB.dirInfo.ioFlAttrib & (1 << 4))) if (!(thePB.dirInfo.ioFlAttrib & (1 << 4)))
return false; return false;
// Get information about the Trash folder. // Get information about the Trash folder.
FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID); FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID);
// If the directory ID of the dropLocation object is the same as the directory ID // If the directory ID of the dropLocation object is the same as the directory ID
// returned by FindFolder, then the drop must have occurred into the Trash. // returned by FindFolder, then the drop must have occurred into the Trash.
if (thePB.dirInfo.ioDrDirID == trashDirID) if (thePB.dirInfo.ioDrDirID == trashDirID)
return true; return true;
} }
@ -325,7 +325,7 @@ HIPoint ScintillaMacOSX::GetLocalPoint(::Point pt)
HIViewRef parent = HIViewGetSuperview(GetViewRef()); HIViewRef parent = HIViewGetSuperview(GetViewRef());
Rect pbounds; Rect pbounds;
GetControlBounds(parent, &pbounds); GetControlBounds(parent, &pbounds);
bounds.left += pbounds.left + hbounds.left; bounds.left += pbounds.left + hbounds.left;
bounds.top += pbounds.top + hbounds.top; bounds.top += pbounds.top + hbounds.top;
@ -353,11 +353,11 @@ void ScintillaMacOSX::StartDrag() {
// step back a position if we're counting the newline // step back a position if we're counting the newline
ep = WndProc(SCI_GETLINEENDPOSITION, l, 0); ep = WndProc(SCI_GETLINEENDPOSITION, l, 0);
if (endPos > ep) endPos = ep; if (endPos > ep) endPos = ep;
pt = LocationFromPosition(startPos); // top left of line selection pt = LocationFromPosition(startPos); // top left of line selection
if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x; if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x;
if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y; if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y;
pt = LocationFromPosition(endPos); // top right of line selection pt = LocationFromPosition(endPos); // top right of line selection
pt.y += vs.lineHeight; // get to the bottom of the line pt.y += vs.lineHeight; // get to the bottom of the line
if (pt.x > rcSel.right || rcSel.right < 0) { if (pt.x > rcSel.right || rcSel.right < 0) {
@ -384,7 +384,7 @@ void ScintillaMacOSX::StartDrag() {
offset.y = (imageRect.top * 1.0) - offset.y; offset.y = (imageRect.top * 1.0) - offset.y;
offset.x = (imageRect.left * 1.0) - offset.x; offset.x = (imageRect.left * 1.0) - offset.x;
// to get a bitmap of the text we're dragging, we just use Paint on a // to get a bitmap of the text we're dragging, we just use Paint on a
// pixmap surface. // pixmap surface.
SurfaceImpl *sw = new SurfaceImpl(); SurfaceImpl *sw = new SurfaceImpl();
SurfaceImpl *pixmap = NULL; SurfaceImpl *pixmap = NULL;
@ -398,17 +398,17 @@ void ScintillaMacOSX::StartDrag() {
paintingAllText = true; paintingAllText = true;
Paint(sw, imageRect); Paint(sw, imageRect);
paintState = notPainting; paintState = notPainting;
pixmap->InitPixMap( imageRect.Width(), imageRect.Height(), NULL, NULL ); pixmap->InitPixMap( imageRect.Width(), imageRect.Height(), NULL, NULL );
CGContextRef gc = pixmap->GetContext(); CGContextRef gc = pixmap->GetContext();
// to make Paint() work on a bitmap, we have to flip our coordinates // to make Paint() work on a bitmap, we have to flip our coordinates
// and translate the origin // and translate the origin
//fprintf(stderr, "translate to %d\n", client.Height() ); //fprintf(stderr, "translate to %d\n", client.Height() );
CGContextTranslateCTM(gc, 0, imageRect.Height()); CGContextTranslateCTM(gc, 0, imageRect.Height());
CGContextScaleCTM(gc, 1.0, -1.0); CGContextScaleCTM(gc, 1.0, -1.0);
pixmap->CopyImageRectangle( *sw, imageRect, PRectangle( 0, 0, imageRect.Width(), imageRect.Height() )); pixmap->CopyImageRectangle( *sw, imageRect, PRectangle( 0, 0, imageRect.Width(), imageRect.Height() ));
// XXX TODO: overwrite any part of the image that is not part of the // XXX TODO: overwrite any part of the image that is not part of the
// selection to make it transparent. right now we just use // selection to make it transparent. right now we just use
@ -434,7 +434,7 @@ void ScintillaMacOSX::StartDrag() {
SelectionText selectedText; SelectionText selectedText;
CopySelectionRange(&selectedText); CopySelectionRange(&selectedText);
PasteboardRef theClipboard; PasteboardRef theClipboard;
SetPasteboardData(theClipboard, selectedText); SetPasteboardData(theClipboard, selectedText, true);
NewDragWithPasteboard( theClipboard, &inDrag); NewDragWithPasteboard( theClipboard, &inDrag);
CFRelease( theClipboard ); CFRelease( theClipboard );
@ -468,16 +468,16 @@ void ScintillaMacOSX::StartDrag() {
if (!(attributes & kDragInsideSenderApplication)) if (!(attributes & kDragInsideSenderApplication))
{ {
GetDropLocation(inDrag, &dropLocation); GetDropLocation(inDrag, &dropLocation);
GetDragModifiers(inDrag, 0L, &mouseDownModifiers, &mouseUpModifiers); GetDragModifiers(inDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey; copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey;
if ((!copyText) && (IsDropInFinderTrash(&dropLocation))) if ((!copyText) && (IsDropInFinderTrash(&dropLocation)))
{ {
// delete the selected text from the buffer // delete the selected text from the buffer
ClearSelection(); ClearSelection();
} }
AEDisposeDesc(&dropLocation); AEDisposeDesc(&dropLocation);
} }
} }
@ -496,7 +496,7 @@ void ScintillaMacOSX::StartDrag() {
void ScintillaMacOSX::SetDragCursor(DragRef inDrag) void ScintillaMacOSX::SetDragCursor(DragRef inDrag)
{ {
DragAttributes attributes; DragAttributes attributes;
SInt16 modifiers = 0; SInt16 modifiers = 0;
ThemeCursor cursor = kThemeCopyArrowCursor; ThemeCursor cursor = kThemeCopyArrowCursor;
GetDragAttributes( inDrag, &attributes ); GetDragAttributes( inDrag, &attributes );
@ -507,7 +507,7 @@ void ScintillaMacOSX::SetDragCursor(DragRef inDrag)
case optionKey: case optionKey:
// it's a copy, leave it as a copy arrow // it's a copy, leave it as a copy arrow
break; break;
case cmdKey: case cmdKey:
case cmdKey | optionKey: case cmdKey | optionKey:
default: default:
@ -526,24 +526,24 @@ bool ScintillaMacOSX::DragEnter(DragRef inDrag )
DragAttributes attributes; DragAttributes attributes;
GetDragAttributes( inDrag, &attributes ); GetDragAttributes( inDrag, &attributes );
// only show the drag hilight if the drag has left the sender window per HI spec // only show the drag hilight if the drag has left the sender window per HI spec
if( attributes & kDragHasLeftSenderWindow ) if( attributes & kDragHasLeftSenderWindow )
{ {
HIRect textFrame; HIRect textFrame;
RgnHandle hiliteRgn = NewRgn(); RgnHandle hiliteRgn = NewRgn();
// get the text view's frame ... // get the text view's frame ...
HIViewGetFrame( GetViewRef(), &textFrame ); HIViewGetFrame( GetViewRef(), &textFrame );
// ... and convert it into a region for ShowDragHilite // ... and convert it into a region for ShowDragHilite
HIShapeRef textShape = HIShapeCreateWithRect( &textFrame ); HIShapeRef textShape = HIShapeCreateWithRect( &textFrame );
HIShapeGetAsQDRgn( textShape, hiliteRgn ); HIShapeGetAsQDRgn( textShape, hiliteRgn );
CFRelease( textShape ); CFRelease( textShape );
// add the drag hilight to the inside of the text view // add the drag hilight to the inside of the text view
ShowDragHilite( inDrag, hiliteRgn, true ); ShowDragHilite( inDrag, hiliteRgn, true );
DisposeRgn( hiliteRgn ); DisposeRgn( hiliteRgn );
} }
SetDragCursor(inDrag); SetDragCursor(inDrag);
@ -639,7 +639,7 @@ bool ScintillaMacOSX::GetDragData(DragRef inDrag, PasteboardRef &pasteBoard,
return GetPasteboardData(pasteBoard, selectedText, isFileURL); return GetPasteboardData(pasteBoard, selectedText, isFileURL);
} }
void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const SelectionText &selectedText) void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const SelectionText &selectedText, bool inDragDropSession)
{ {
if (selectedText.len == 0) if (selectedText.len == 0)
return; return;
@ -649,7 +649,9 @@ void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const Selec
// Create a CFString from the ASCII/UTF8 data, convert it to UTF16 // Create a CFString from the ASCII/UTF8 data, convert it to UTF16
CFStringRef string = CFStringCreateWithBytes( NULL, reinterpret_cast<UInt8*>( selectedText.s ), selectedText.len - 1, encoding, false ); CFStringRef string = CFStringCreateWithBytes( NULL, reinterpret_cast<UInt8*>( selectedText.s ), selectedText.len - 1, encoding, false );
PasteboardCreate( kPasteboardClipboard, &theClipboard ); PasteboardCreate((inDragDropSession
? kPasteboardUniqueName
: kPasteboardClipboard), &theClipboard );
PasteboardClear( theClipboard ); PasteboardClear( theClipboard );
CFDataRef data = NULL; CFDataRef data = NULL;
@ -658,7 +660,7 @@ void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const Selec
// around the document // around the document
data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 ); data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 );
if (data) { if (data) {
PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1,
CFSTR("com.scintilla.utf16-plain-text.rectangular"), CFSTR("com.scintilla.utf16-plain-text.rectangular"),
data, 0 ); data, 0 );
CFRelease(data); CFRelease(data);
@ -666,7 +668,7 @@ void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const Selec
} }
data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 ); data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 );
if (data) { if (data) {
PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1,
CFSTR("public.utf16-plain-text"), CFSTR("public.utf16-plain-text"),
data, 0 ); data, 0 );
CFRelease(data); CFRelease(data);
@ -674,7 +676,7 @@ void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const Selec
} }
data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingMacRoman, 0 ); data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingMacRoman, 0 );
if (data) { if (data) {
PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1,
CFSTR("com.apple.traditional-mac-plain-text"), CFSTR("com.apple.traditional-mac-plain-text"),
data, 0 ); data, 0 );
CFRelease(data); CFRelease(data);
@ -724,7 +726,7 @@ bool ScintillaMacOSX::GetPasteboardData(PasteboardRef &pasteBoard,
{ {
CFDataRef flavorData; CFDataRef flavorData;
CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, j); CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, j);
if (flavorType != NULL) if (flavorType != NULL)
{ {
int format = kFormatBad; int format = kFormatBad;
if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) {
@ -746,7 +748,7 @@ bool ScintillaMacOSX::GetPasteboardData(PasteboardRef &pasteBoard,
} }
if (format == kFormatBad) if (format == kFormatBad)
continue; continue;
// if we got a flavor match, and we have no textString, we just want // if we got a flavor match, and we have no textString, we just want
// to know that we can accept this data, so jump out now // to know that we can accept this data, so jump out now
if (selectedText == NULL) { if (selectedText == NULL) {
@ -845,10 +847,10 @@ OSStatus ScintillaMacOSX::DragReceive(DragRef inDrag )
} else { } else {
// figure out if this is a move or a paste // figure out if this is a move or a paste
DragAttributes attributes; DragAttributes attributes;
SInt16 modifiers = 0; SInt16 modifiers = 0;
GetDragAttributes( inDrag, &attributes ); GetDragAttributes( inDrag, &attributes );
bool moving = true; bool moving = true;
SelectionPosition position = SPositionFromLocation(GetDragPoint(inDrag)); SelectionPosition position = SPositionFromLocation(GetDragPoint(inDrag));
if ( attributes & kDragInsideSenderWindow ) { if ( attributes & kDragInsideSenderWindow ) {
GetDragModifiers(inDrag, NULL, NULL, &modifiers); GetDragModifiers(inDrag, NULL, NULL, &modifiers);
@ -893,11 +895,11 @@ sptr_t ScintillaMacOSX::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPa
case SCI_GETDIRECTFUNCTION: case SCI_GETDIRECTFUNCTION:
Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning DirectFunction address.\n" ); Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning DirectFunction address.\n" );
return reinterpret_cast<sptr_t>( DirectFunction ); return reinterpret_cast<sptr_t>( DirectFunction );
case SCI_GETDIRECTPOINTER: case SCI_GETDIRECTPOINTER:
Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning Direct pointer address.\n" ); Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning Direct pointer address.\n" );
return reinterpret_cast<sptr_t>( this ); return reinterpret_cast<sptr_t>( this );
case SCI_GRABFOCUS: case SCI_GRABFOCUS:
Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Got an unhandled message. Ignoring it.\n" ); Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Got an unhandled message. Ignoring it.\n" );
break; break;
@ -962,7 +964,7 @@ bool ScintillaMacOSX::SetIdle(bool on) {
return true; return true;
} }
pascal void ScintillaMacOSX::IdleTimerEventHandler( EventLoopTimerRef inTimer, pascal void ScintillaMacOSX::IdleTimerEventHandler( EventLoopTimerRef inTimer,
EventLoopIdleTimerMessage inState, EventLoopIdleTimerMessage inState,
void *scintilla ) void *scintilla )
{ {
@ -1137,14 +1139,14 @@ void ScintillaMacOSX::Resize(int width, int height) {
RgnHandle rgn = NewRgn(); RgnHandle rgn = NewRgn();
HIRect r; HIRect r;
HIViewGetFrame( reinterpret_cast<HIViewRef>( GetViewRef() ), &r ); HIViewGetFrame( reinterpret_cast<HIViewRef>( GetViewRef() ), &r );
SetRectRgn(rgn, short (r.origin.x), short (r.origin.y), SetRectRgn(rgn, short (r.origin.x), short (r.origin.y),
short (r.origin.x + r.size.width - (verticalScrollBarVisible ? scrollBarFixedSize : 0)), short (r.origin.x + r.size.width - (verticalScrollBarVisible ? scrollBarFixedSize : 0)),
short (r.origin.y + r.size.height - (showSBHorizontal ? scrollBarFixedSize : 0))); short (r.origin.y + r.size.height - (showSBHorizontal ? scrollBarFixedSize : 0)));
if (mouseTrackingRef == NULL) { if (mouseTrackingRef == NULL) {
CreateMouseTrackingRegion(GetOwner(), rgn, NULL, CreateMouseTrackingRegion(GetOwner(), rgn, NULL,
kMouseTrackingOptionsLocalClip, kMouseTrackingOptionsLocalClip,
mouseTrackingID, NULL, mouseTrackingID, NULL,
GetControlEventTarget( GetViewRef() ), GetControlEventTarget( GetViewRef() ),
&mouseTrackingRef); &mouseTrackingRef);
} else { } else {
ChangeMouseTrackingRegion(mouseTrackingRef, rgn, NULL); ChangeMouseTrackingRegion(mouseTrackingRef, rgn, NULL);
@ -1242,7 +1244,7 @@ bool ScintillaMacOSX::ScrollBarHit(HIPoint location) {
if (view) { if (view) {
HIViewPartCode part; HIViewPartCode part;
// make the point local to a scrollbar // make the point local to a scrollbar
PRectangle client = GetClientRectangle(); PRectangle client = GetClientRectangle();
if (view == vScrollBar) { if (view == vScrollBar) {
location.x -= client.Width(); location.x -= client.Width();
@ -1252,9 +1254,9 @@ bool ScintillaMacOSX::ScrollBarHit(HIPoint location) {
fprintf(stderr, "got a subview hit, but not a scrollbar???\n"); fprintf(stderr, "got a subview hit, but not a scrollbar???\n");
return false; return false;
} }
HIViewGetPartHit(view, &location, &part); HIViewGetPartHit(view, &location, &part);
switch (part) switch (part)
{ {
case kControlUpButtonPart: case kControlUpButtonPart:
@ -1293,14 +1295,14 @@ void ScintillaMacOSX::NotifyFocus(bool focus) {
ExtInput::activate (GetViewRef(), focus); ExtInput::activate (GetViewRef(), focus);
#endif #endif
if (NULL != notifyProc) if (NULL != notifyProc)
notifyProc (notifyObj, WM_COMMAND, notifyProc (notifyObj, WM_COMMAND,
(uintptr_t) ((focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS) << 16), (uintptr_t) ((focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS) << 16),
(uintptr_t) GetViewRef()); (uintptr_t) GetViewRef());
} }
void ScintillaMacOSX::NotifyChange() { void ScintillaMacOSX::NotifyChange() {
if (NULL != notifyProc) if (NULL != notifyProc)
notifyProc (notifyObj, WM_COMMAND, notifyProc (notifyObj, WM_COMMAND,
(uintptr_t) (SCEN_CHANGE << 16), (uintptr_t) (SCEN_CHANGE << 16),
(uintptr_t) GetViewRef()); (uintptr_t) GetViewRef());
} }
@ -1310,7 +1312,7 @@ void ScintillaMacOSX::registerNotifyCallback(intptr_t windowid, SciNotifyFunc ca
notifyProc = callback; notifyProc = callback;
} }
void ScintillaMacOSX::NotifyParent(SCNotification scn) { void ScintillaMacOSX::NotifyParent(SCNotification scn) {
if (NULL != notifyProc) { if (NULL != notifyProc) {
scn.nmhdr.hwndFrom = (void*) this; scn.nmhdr.hwndFrom = (void*) this;
scn.nmhdr.idFrom = (unsigned int)wMain.GetID(); scn.nmhdr.idFrom = (unsigned int)wMain.GetID();
@ -1397,8 +1399,8 @@ pascal OSStatus ScintillaMacOSX::CommandEventHandler( EventHandlerCallRef /*inCa
{ kHICommandClear, &ScintillaMacOSX::HasSelection }, { kHICommandClear, &ScintillaMacOSX::HasSelection },
{ kHICommandSelectAll, &ScintillaMacOSX::AlwaysTrue }, { kHICommandSelectAll, &ScintillaMacOSX::AlwaysTrue },
}; };
HICommand command; HICommand command;
OSStatus result = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( command ), NULL, &command ); OSStatus result = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( command ), NULL, &command );
assert( result == noErr ); assert( result == noErr );
@ -1407,7 +1409,7 @@ pascal OSStatus ScintillaMacOSX::CommandEventHandler( EventHandlerCallRef /*inCa
ScintillaMacOSX* scintilla = reinterpret_cast<ScintillaMacOSX*>( data ); ScintillaMacOSX* scintilla = reinterpret_cast<ScintillaMacOSX*>( data );
assert( scintilla != NULL ); assert( scintilla != NULL );
if ( kind == kEventProcessCommand ) if ( kind == kEventProcessCommand )
{ {
#ifdef EXT_INPUT #ifdef EXT_INPUT
@ -1451,7 +1453,7 @@ pascal OSStatus ScintillaMacOSX::CommandEventHandler( EventHandlerCallRef /*inCa
assert( false ); assert( false );
result = eventNotHandledErr; result = eventNotHandledErr;
} }
return result; return result;
} }
@ -1477,7 +1479,7 @@ bool ScintillaMacOSX::AlwaysTrue()
void ScintillaMacOSX::CopyToClipboard(const SelectionText &selectedText) { void ScintillaMacOSX::CopyToClipboard(const SelectionText &selectedText) {
PasteboardRef theClipboard; PasteboardRef theClipboard;
SetPasteboardData(theClipboard, selectedText); SetPasteboardData(theClipboard, selectedText, false); // not in drag/drop
// Done with the CFString // Done with the CFString
CFRelease( theClipboard ); CFRelease( theClipboard );
} }
@ -1486,7 +1488,7 @@ void ScintillaMacOSX::Copy()
{ {
if (!sel.Empty()) { if (!sel.Empty()) {
#ifdef EXT_INPUT #ifdef EXT_INPUT
ExtInput::stop (GetViewRef()); ExtInput::stop (GetViewRef());
#endif #endif
SelectionText selectedText; SelectionText selectedText;
CopySelectionRange(&selectedText); CopySelectionRange(&selectedText);
@ -1502,7 +1504,7 @@ bool ScintillaMacOSX::CanPaste()
PasteboardRef theClipboard; PasteboardRef theClipboard;
bool isFileURL = false; bool isFileURL = false;
PasteboardCreate( kPasteboardClipboard, &theClipboard ); PasteboardCreate( kPasteboardClipboard, &theClipboard );
bool ok = GetPasteboardData(theClipboard, NULL, &isFileURL); bool ok = GetPasteboardData(theClipboard, NULL, &isFileURL);
CFRelease( theClipboard ); CFRelease( theClipboard );
@ -1514,7 +1516,7 @@ void ScintillaMacOSX::Paste()
Paste(false); Paste(false);
} }
// XXX there is no system flag (I can find) to tell us that a paste is rectangular, so // XXX there is no system flag (I can find) to tell us that a paste is rectangular, so
// applications must implement an additional command (eg. option-V like BBEdit) // applications must implement an additional command (eg. option-V like BBEdit)
// in order to provide rectangular paste // in order to provide rectangular paste
void ScintillaMacOSX::Paste(bool forceRectangular) void ScintillaMacOSX::Paste(bool forceRectangular)
@ -1536,7 +1538,7 @@ void ScintillaMacOSX::Paste(bool forceRectangular)
if (selectedText.rectangular) { if (selectedText.rectangular) {
SelectionPosition selStart = sel.RangeMain().Start(); SelectionPosition selStart = sel.RangeMain().Start();
PasteRectangular(selStart, selectedText.s, selectedText.len); PasteRectangular(selStart, selectedText.s, selectedText.len);
} else } else
if ( pdoc->InsertString( sel.RangeMain().caret.Position(), selectedText.s, selectedText.len ) ) { if ( pdoc->InsertString( sel.RangeMain().caret.Position(), selectedText.s, selectedText.len ) ) {
SetEmptySelection( sel.RangeMain().caret.Position() + selectedText.len ); SetEmptySelection( sel.RangeMain().caret.Position() + selectedText.len );
} }
@ -1614,7 +1616,7 @@ void ScintillaMacOSX::CreateCallTipWindow(PRectangle rc) {
} }
} }
void ScintillaMacOSX::CallTipClick() void ScintillaMacOSX::CallTipClick()
{ {
ScintillaBase::CallTipClick(); ScintillaBase::CallTipClick();
} }
@ -1739,7 +1741,7 @@ OSStatus ScintillaMacOSX::SetFocusPart( ControlPartCode desiredFocus, RgnHandle
// We are getting the focus // We are getting the focus
SetFocusState(true); SetFocusState(true);
} }
*outActualFocus = desiredFocus; *outActualFocus = desiredFocus;
return noErr; return noErr;
} }
@ -1870,7 +1872,7 @@ OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
PLATFORM_ASSERT( err == noErr ); PLATFORM_ASSERT( err == noErr );
int modifiers = GetCurrentEventKeyModifiers(); int modifiers = GetCurrentEventKeyModifiers();
// Loop over all characters in sequence // Loop over all characters in sequence
for (int i = 0; i < numUniChars; i++) for (int i = 0; i < numUniChars; i++)
{ {
@ -1917,7 +1919,7 @@ OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
//delete text; //delete text;
text = NULL; text = NULL;
// If we have a single unicode character that is special or // If we have a single unicode character that is special or
// to process a command. Try to do some translation. // to process a command. Try to do some translation.
if ( numUniChars == 1 && ( modifiers & controlKey || scintillaKey != 0 ) ) { if ( numUniChars == 1 && ( modifiers & controlKey || scintillaKey != 0 ) ) {
// If we have a modifier, we need to get the character without modifiers // If we have a modifier, we need to get the character without modifiers
@ -1940,7 +1942,7 @@ OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
scintillaKey = toupper( (char) scintillaKey ); scintillaKey = toupper( (char) scintillaKey );
} }
} }
// Code taken from Editor::KeyDown // Code taken from Editor::KeyDown
// It is copied here because we don't want to feed the key via // It is copied here because we don't want to feed the key via
// KeyDefault if there is no special action // KeyDefault if there is no special action
@ -1970,7 +1972,7 @@ OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
maximumByteLength, &usedBufferLength ); maximumByteLength, &usedBufferLength );
assert( numCharsConverted == numUniChars ); assert( numCharsConverted == numUniChars );
buffer[usedBufferLength] = '\0'; // null terminate buffer[usedBufferLength] = '\0'; // null terminate
// Add all the characters to the document // Add all the characters to the document
// NOTE: OS X doesn't specify that text input events provide only a single character // NOTE: OS X doesn't specify that text input events provide only a single character
// if we get a single character, add it as a character // if we get a single character, add it as a character
@ -1992,8 +1994,8 @@ OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
// Default allocator releases both the CFString and the UniChar buffer (text) // Default allocator releases both the CFString and the UniChar buffer (text)
CFRelease( string ); CFRelease( string );
string = NULL; string = NULL;
return err; return err;
#endif #endif
} }
@ -2026,7 +2028,7 @@ OSStatus ScintillaMacOSX::MouseExited(HIPoint& location, UInt32 modifiers, Event
if (HIViewGetSuperview(GetViewRef()) != NULL) { if (HIViewGetSuperview(GetViewRef()) != NULL) {
if (HaveMouseCapture()) { if (HaveMouseCapture()) {
ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ), ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ), static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
(modifiers & controlKey) != 0 ); (modifiers & controlKey) != 0 );
} }
WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
@ -2047,7 +2049,7 @@ OSStatus ScintillaMacOSX::MouseDown( EventRecord *event )
HIPoint pt = GetLocalPoint(event->where); HIPoint pt = GetLocalPoint(event->where);
int button = kEventMouseButtonPrimary; int button = kEventMouseButtonPrimary;
mouseDownEvent = *event; mouseDownEvent = *event;
if ( event->modifiers & controlKey ) if ( event->modifiers & controlKey )
button = kEventMouseButtonSecondary; button = kEventMouseButtonSecondary;
return MouseDown(pt, event->modifiers, button, 1); return MouseDown(pt, event->modifiers, button, 1);
@ -2063,8 +2065,8 @@ OSStatus ScintillaMacOSX::MouseDown( HIPoint& location, UInt32 modifiers, EventM
} }
ButtonDown( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ), ButtonDown( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ), static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
(modifiers & shiftKey) != 0, (modifiers & shiftKey) != 0,
(modifiers & controlKey) != 0, (modifiers & controlKey) != 0,
(modifiers & cmdKey) ); (modifiers & cmdKey) );
#if !defined(CONTAINER_HANDLES_EVENTS) #if !defined(CONTAINER_HANDLES_EVENTS)
OSStatus err; OSStatus err;
@ -2090,9 +2092,9 @@ OSStatus ScintillaMacOSX::MouseUp( HIPoint& location, UInt32 modifiers, EventMou
// We only deal with the first mouse button // We only deal with the first mouse button
if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ), ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ), static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
(modifiers & controlKey) != 0 ); (modifiers & controlKey) != 0 );
#if !defined(CONTAINER_HANDLES_EVENTS) #if !defined(CONTAINER_HANDLES_EVENTS)
return noErr; return noErr;
#else #else
@ -2134,7 +2136,7 @@ OSStatus ScintillaMacOSX::MouseDragged( HIPoint& location, UInt32 modifiers, Eve
location = GetLocalPoint(theQDPoint); location = GetLocalPoint(theQDPoint);
} }
ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ), ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ), static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
(modifiers & controlKey) != 0 ); (modifiers & controlKey) != 0 );
} else { } else {
if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) { if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) {
@ -2158,7 +2160,7 @@ OSStatus ScintillaMacOSX::MouseDragged( HIPoint& location, UInt32 modifiers, Eve
OSStatus ScintillaMacOSX::MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers ) OSStatus ScintillaMacOSX::MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers )
{ {
if ( axis != 1 ) return eventNotHandledErr; if ( axis != 1 ) return eventNotHandledErr;
if ( modifiers & controlKey ) { if ( modifiers & controlKey ) {
// Zoom! We play with the font sizes in the styles. // Zoom! We play with the font sizes in the styles.
// Number of steps/line is ignored, we just care if sizing up or down // Number of steps/line is ignored, we just care if sizing up or down
@ -2185,7 +2187,7 @@ OSStatus ScintillaMacOSX::ContextualMenuClick( HIPoint& location )
location.x += bounds.left; location.x += bounds.left;
location.y += bounds.top; location.y += bounds.top;
ContextMenu( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) ); ContextMenu( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) );
return noErr; return noErr;
} }
OSStatus ScintillaMacOSX::ActiveStateChanged() OSStatus ScintillaMacOSX::ActiveStateChanged()
@ -2222,7 +2224,7 @@ HIViewRef ScintillaMacOSX::Create()
Platform::DebugPrintf("ScintillaMacOSX::Create control %08X\n",control); Platform::DebugPrintf("ScintillaMacOSX::Create control %08X\n",control);
return control; return control;
} }
return NULL; return NULL;
} }
OSStatus ScintillaMacOSX::Construct( HIViewRef inControl, TView** outView ) OSStatus ScintillaMacOSX::Construct( HIViewRef inControl, TView** outView )

View File

@ -89,8 +89,8 @@ class ScintillaMacOSX : public ScintillaBase, public TView
bool capturedMouse; bool capturedMouse;
// true if scintilla initiated the drag session // true if scintilla initiated the drag session
bool inDragSession() { return inDragDrop == ddDragging; }; bool inDragSession() { return inDragDrop == ddDragging; };
bool isTracking; bool isTracking;
// Private so ScintillaMacOSX objects can not be copied // Private so ScintillaMacOSX objects can not be copied
ScintillaMacOSX(const ScintillaMacOSX &) : ScintillaBase(), TView( NULL ) {} ScintillaMacOSX(const ScintillaMacOSX &) : ScintillaBase(), TView( NULL ) {}
@ -113,12 +113,13 @@ public:
private: private:
virtual void Initialise(); virtual void Initialise();
virtual void Finalise(); virtual void Finalise();
// pasteboard support // pasteboard support
bool GetPasteboardData(PasteboardRef &pasteBoard, bool GetPasteboardData(PasteboardRef &pasteBoard,
SelectionText *selectedText, bool *isFileURL); SelectionText *selectedText, bool *isFileURL);
void SetPasteboardData(PasteboardRef &pasteBoard, void SetPasteboardData(PasteboardRef &pasteBoard,
const SelectionText &selectedText); const SelectionText &selectedText,
bool inDragDropSession);
char *GetStringFromCFString(CFStringRef &textString, int *textLen); char *GetStringFromCFString(CFStringRef &textString, int *textLen);
// Drag and drop // Drag and drop
@ -168,7 +169,7 @@ public: // Public for scintilla_send_message
void Resize(int width, int height); void Resize(int width, int height);
static pascal void LiveScrollHandler( ControlHandle control, SInt16 part ); static pascal void LiveScrollHandler( ControlHandle control, SInt16 part );
bool ScrollBarHit(HIPoint location); bool ScrollBarHit(HIPoint location);
virtual void NotifyChange(); virtual void NotifyChange();
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void NotifyParent(SCNotification scn); virtual void NotifyParent(SCNotification scn);
@ -227,7 +228,7 @@ public:
static HIViewRef Create(); static HIViewRef Create();
private: private:
static OSStatus Construct( HIViewRef inControl, TView** outView ); static OSStatus Construct( HIViewRef inControl, TView** outView );
}; };

View File

@ -29,6 +29,7 @@ static std::vector<LexerModule *> lexerCatalogue;
static int nextLanguage = SCLEX_AUTOMATIC+1; static int nextLanguage = SCLEX_AUTOMATIC+1;
const LexerModule *Catalogue::Find(int language) { const LexerModule *Catalogue::Find(int language) {
Scintilla_LinkLexers();
for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin(); for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
it != lexerCatalogue.end(); ++it) { it != lexerCatalogue.end(); ++it) {
if ((*it)->GetLanguage() == language) { if ((*it)->GetLanguage() == language) {
@ -39,6 +40,7 @@ const LexerModule *Catalogue::Find(int language) {
} }
const LexerModule *Catalogue::Find(const char *languageName) { const LexerModule *Catalogue::Find(const char *languageName) {
Scintilla_LinkLexers();
if (languageName) { if (languageName) {
for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin(); for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
it != lexerCatalogue.end(); ++it) { it != lexerCatalogue.end(); ++it) {
@ -170,8 +172,8 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmTAL); LINK_LEXER(lmTAL);
LINK_LEXER(lmTCL); LINK_LEXER(lmTCL);
LINK_LEXER(lmTeX); LINK_LEXER(lmTeX);
LINK_LEXER(lmUserDefine);
LINK_LEXER(lmTxt2tags); LINK_LEXER(lmTxt2tags);
LINK_LEXER(lmUserDefine);
LINK_LEXER(lmVB); LINK_LEXER(lmVB);
LINK_LEXER(lmVBScript); LINK_LEXER(lmVBScript);
LINK_LEXER(lmVerilog); LINK_LEXER(lmVerilog);

View File

@ -372,8 +372,6 @@ bool Document::IsCrLf(int pos) {
return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
} }
static const int maxBytesInDBCSCharacter=5;
int Document::LenChar(int pos) { int Document::LenChar(int pos) {
if (pos < 0) { if (pos < 0) {
return 1; return 1;
@ -394,13 +392,7 @@ int Document::LenChar(int pos) {
else else
return len; return len;
} else if (dbcsCodePage) { } else if (dbcsCodePage) {
char mbstr[maxBytesInDBCSCharacter+1]; return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
int i;
for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
mbstr[i] = cb.CharAt(pos+i);
}
mbstr[i] = '\0';
return Platform::DBCSCharLength(dbcsCodePage, mbstr);
} else { } else {
return 1; return 1;
} }
@ -476,8 +468,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos - 1; return pos - 1;
} }
// Not between CR and LF
if (dbcsCodePage) { if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos)); unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
@ -493,16 +483,18 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
} else { } 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 posCheck = LineStart(LineFromPosition(pos)); int posStartLine = LineStart(LineFromPosition(pos));
while (posCheck < pos) { if (pos == posStartLine)
char mbstr[maxBytesInDBCSCharacter+1]; return pos;
int i;
for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
mbstr[i] = cb.CharAt(posCheck+i);
}
mbstr[i] = '\0';
int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr); // Step back until a non-lead-byte is found.
int posCheck = pos;
while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1)))
posCheck--;
// Check from known start of character.
while (posCheck < pos) {
int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1;
if (posCheck + mbsize == pos) { if (posCheck + mbsize == pos) {
return pos; return pos;
} else if (posCheck + mbsize > pos) { } else if (posCheck + mbsize > pos) {
@ -520,12 +512,106 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos; return pos;
} }
// NextPosition moves between valid positions - it can not handle a position in the middle of a
// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar.
// A \r\n pair is treated as two characters.
int Document::NextPosition(int pos, int moveDir) {
// If out of range, just return minimum/maximum value.
int increment = (moveDir > 0) ? 1 : -1;
if (pos + increment <= 0)
return 0;
if (pos + increment >= Length())
return Length();
if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
pos += increment;
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
int startUTF = pos;
int endUTF = pos;
if (IsTrailByte(ch) && InGoodUTF8(pos, startUTF, endUTF)) {
// ch is a trail byte within a UTF-8 character
if (moveDir > 0)
pos = endUTF;
else
pos = startUTF;
}
} else {
if (moveDir > 0) {
int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
pos += mbsize;
if (pos > Length())
pos = Length();
} else {
// Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte.
int posStartLine = LineStart(LineFromPosition(pos));
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
if ((pos - 1) <= posStartLine) {
return posStartLine;
} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
// Must actually be trail byte
return pos - 2;
} else {
// Otherwise, step back until a non-lead-byte is found.
int posTemp = pos - 1;
while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp)))
;
// Now posTemp+1 must point to the beginning of a character,
// so figure out whether we went back an even or an odd
// number of bytes and go back 1 or 2 bytes, respectively.
return (pos - 1 - ((pos - posTemp) & 1));
}
}
}
} else {
pos += increment;
}
return pos;
}
bool Document::NextCharacter(int &pos, int moveDir) {
// Returns true if pos changed
int posNext = NextPosition(pos, moveDir);
if (posNext == pos) {
return false;
} else {
pos = posNext;
return true;
}
}
int SCI_METHOD Document::CodePage() const { int SCI_METHOD Document::CodePage() const {
return dbcsCodePage; return dbcsCodePage;
} }
bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const { bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return Platform::IsDBCSLeadByte(dbcsCodePage, ch); // Byte ranges found in Wikipedia articles with relevant search strings in each case
unsigned char uch = static_cast<unsigned char>(ch);
switch (dbcsCodePage) {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);
case 949:
// Korean Wansung KS C-5601-1987
return (uch >= 0x81) && (uch <= 0xFE);
case 950:
// Big5
return (uch >= 0x81) && (uch <= 0xFE);
case 1361:
// Korean Johab KS C-5601-1992
return
((uch >= 0x84) && (uch <= 0xD3)) ||
((uch >= 0xD8) && (uch <= 0xDE)) ||
((uch >= 0xE0) && (uch <= 0xF9));
}
return false;
} }
void Document::ModifiedAt(int pos) { void Document::ModifiedAt(int pos) {
@ -770,7 +856,7 @@ void Document::DelCharBack(int pos) {
} else if (IsCrLf(pos - 2)) { } else if (IsCrLf(pos - 2)) {
DeleteChars(pos - 2, 2); DeleteChars(pos - 2, 2);
} else if (dbcsCodePage) { } else if (dbcsCodePage) {
int startChar = MovePositionOutsideChar(pos - 1, -1, false); int startChar = NextPosition(pos, -1);
DeleteChars(startChar, pos - startChar); DeleteChars(startChar, pos - startChar);
} else { } else {
DeleteChars(pos - 1, 1); DeleteChars(pos - 1, 1);
@ -802,7 +888,7 @@ static void CreateIndentation(char *linebuf, int length, int indent, int tabSize
*linebuf = '\0'; *linebuf = '\0';
} }
int Document::GetLineIndentation(int line) { int SCI_METHOD Document::GetLineIndentation(int line) {
int indent = 0; int indent = 0;
if ((line >= 0) && (line < LinesTotal())) { if ((line >= 0) && (line < LinesTotal())) {
int lineStart = LineStart(line); int lineStart = LineStart(line);
@ -863,7 +949,7 @@ int Document::GetColumn(int pos) {
return column; return column;
} else { } else {
column++; column++;
i = MovePositionOutsideChar(i + 1, 1, false); i = NextPosition(i, 1);
} }
} }
} }
@ -885,7 +971,7 @@ int Document::FindColumn(int line, int column) {
return position; return position;
} else { } else {
columnCurrent++; columnCurrent++;
position = MovePositionOutsideChar(position + 1, 1, false); position = NextPosition(position, 1);
} }
} }
} }
@ -1238,13 +1324,8 @@ long Document::FindText(int minPos, int maxPos, const char *search,
if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
return pos; return pos;
} }
pos += increment; if (!NextCharacter(pos, increment))
if (dbcsCodePage && (pos >= 0)) { break;
// Have to use >= 0 as otherwise next statement would change
// -1 to 0 and make loop infinite.
// Ensure trying to match from start of character
pos = MovePositionOutsideChar(pos, increment, false);
}
} }
} else if (SC_CP_UTF8 == dbcsCodePage) { } else if (SC_CP_UTF8 == dbcsCodePage) {
const size_t maxBytesCharacter = 4; const size_t maxBytesCharacter = 4;
@ -1281,12 +1362,43 @@ long Document::FindText(int minPos, int maxPos, const char *search,
if (forward) { if (forward) {
pos += widthFirstCharacter; pos += widthFirstCharacter;
} else { } else {
pos--; if (!NextCharacter(pos, increment))
if (pos > 0) { break;
// Ensure trying to match from start of character }
pos = MovePositionOutsideChar(pos, increment, false); }
} else if (dbcsCodePage) {
const size_t maxBytesCharacter = 2;
const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
int indexDocument = 0;
int indexSearch = 0;
bool characterMatches = true;
while (characterMatches &&
((pos + indexDocument) < limitPos) &&
(indexSearch < lenSearch)) {
char bytes[maxBytesCharacter + 1];
bytes[0] = cb.CharAt(pos + indexDocument);
const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
if (widthChar == 2)
bytes[1] = cb.CharAt(pos + indexDocument + 1);
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
folded[lenFlat] = 0;
// Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
indexDocument += widthChar;
indexSearch += lenFlat;
}
if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
*length = indexDocument;
return pos;
} }
} }
if (!NextCharacter(pos, increment))
break;
} }
} else { } else {
CaseFolderTable caseFolder; CaseFolderTable caseFolder;
@ -1303,11 +1415,8 @@ long Document::FindText(int minPos, int maxPos, const char *search,
if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
return pos; return pos;
} }
pos += increment; if (!NextCharacter(pos, increment))
if (dbcsCodePage && (pos >= 0)) { break;
// Ensure trying to match from start of character
pos = MovePositionOutsideChar(pos, increment, false);
}
} }
} }
} }
@ -1316,7 +1425,10 @@ long Document::FindText(int minPos, int maxPos, const char *search,
} }
const char *Document::SubstituteByPosition(const char *text, int *length) { const char *Document::SubstituteByPosition(const char *text, int *length) {
return regex->SubstituteByPosition(this, text, length); if (regex)
return regex->SubstituteByPosition(this, text, length);
else
return 0;
} }
int Document::LinesTotal() const { int Document::LinesTotal() const {
@ -1748,9 +1860,8 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1; direction = 1;
int depth = 1; int depth = 1;
position = position + direction; position = NextPosition(position, direction);
while ((position >= 0) && (position < Length())) { while ((position >= 0) && (position < Length())) {
position = MovePositionOutsideChar(position, direction, true);
char chAtPos = CharAt(position); char chAtPos = CharAt(position);
char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask); char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
if ((position > GetEndStyled()) || (styAtPos == styBrace)) { if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
@ -1761,7 +1872,10 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
if (depth == 0) if (depth == 0)
return position; return position;
} }
position = position + direction; int positionBeforeMove = position;
position = NextPosition(position, direction);
if (position == positionBeforeMove)
break;
} }
return - 1; return - 1;
} }

View File

@ -230,6 +230,8 @@ public:
int LenChar(int pos); int LenChar(int pos);
bool InGoodUTF8(int pos, int &start, int &end); bool InGoodUTF8(int pos, int &start, int &end);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
int NextPosition(int pos, int moveDir);
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const; int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const; bool SCI_METHOD IsDBCSLeadByte(char ch) const;
@ -252,9 +254,9 @@ public:
void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
void SetSavePoint(); void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); } bool IsSavePoint() { return cb.IsSavePoint(); }
const char *BufferPointer() { return cb.BufferPointer(); } const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); }
int GetLineIndentation(int line); int SCI_METHOD GetLineIndentation(int line);
void SetLineIndentation(int line, int indent); void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line) const; int GetLineIndentPosition(int line) const;
int GetColumn(int position); int GetColumn(int position);

View File

@ -2428,6 +2428,8 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
// Fill the remainder of the line // Fill the remainder of the line
rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth; rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
if (rcSegment.left < rcLine.left)
rcSegment.left = rcLine.left;
rcSegment.right = rcLine.right; rcSegment.right = rcLine.right;
if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
@ -4372,7 +4374,16 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
// Some lines are hidden so may need shown. // Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden. // TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) { if (mh.modificationType & SC_MOD_BEFOREINSERT) {
NotifyNeedShown(mh.position, 0); int lineOfPos = pdoc->LineFromPosition(mh.position);
bool insertingNewLine = false;
for (int i=0; i < mh.length; i++) {
if ((mh.text[i] == '\n') || (mh.text[i] == '\r'))
insertingNewLine = true;
}
if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos)))
NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position);
else
NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) { } else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length); NotifyNeedShown(mh.position, mh.length);
} }

View File

@ -181,7 +181,7 @@ def FindProperties(lexFile):
properties = {} properties = {}
f = open(lexFile) f = open(lexFile)
for l in f.readlines(): for l in f.readlines():
if "GetProperty" in l and '"' in l: if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l:
l = l.strip() l = l.strip()
if not l.startswith("//"): # Drop comments if not l.startswith("//"): # Drop comments
propertyName = l.split("\"")[1] propertyName = l.split("\"")[1]
@ -205,13 +205,35 @@ def FindPropertyDocumentation(lexFile):
# Only allow lower case property names # Only allow lower case property names
name = propertyName name = propertyName
documents[name] = "" documents[name] = ""
elif "DefineProperty" in l and "\"" in l:
propertyName = l.split("\"")[1]
if propertyName.lower() == propertyName:
# Only allow lower case property names
name = propertyName
documents[name] = ""
elif name: elif name:
if l.startswith("//"): if l.startswith("//"):
if documents[name]: if documents[name]:
documents[name] += " " documents[name] += " "
documents[name] += l[2:].strip() documents[name] += l[2:].strip()
elif l.startswith("\""):
if documents[name]:
documents[name] += " "
l = l[1:].strip()
if l.endswith(";"):
l = l[:-1].strip()
if l.endswith(")"):
l = l[:-1].strip()
if l.endswith("\""):
l = l[:-1]
# Fix escaped double quotes
l = l.replace("\\\"", "\"")
documents[name] += l
else: else:
name = "" name = ""
for name in list(documents.keys()):
if documents[name] == "":
del documents[name]
return documents return documents
def ciCompare(a,b): def ciCompare(a,b):
@ -230,7 +252,7 @@ def RegenerateAll():
root="../../" root="../../"
# Find all the lexer source code files # Find all the lexer source code files
lexFilePaths = glob.glob(root + "scintilla/src/Lex*.cxx") lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx")
sortListInsensitive(lexFilePaths) sortListInsensitive(lexFilePaths)
lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths] lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
print(lexFiles) print(lexFiles)
@ -267,15 +289,9 @@ def RegenerateAll():
sortListInsensitive(propFiles) sortListInsensitive(propFiles)
print(propFiles) print(propFiles)
Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules) Regenerate(root + "scintilla/src/Catalogue.cxx", "//", NATIVE, lexerModules)
Regenerate(root + "scintilla/win32/makefile", "#", NATIVE, lexFiles)
Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles) Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles) Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
# Use Unix EOLs for gtk Makefiles so they work for Linux users when
# extracted from the Scintilla source ZIP (typically created on
# Windows).
Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
Regenerate(root + "scintilla/macosx/makefile", "#", LF, lexFiles)
if os.path.exists(root + "scite"): if os.path.exists(root + "scite"):
Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles) Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles) Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)

View File

@ -322,6 +322,8 @@ int LineState::SetLineState(int line, int state) {
} }
int LineState::GetLineState(int line) { int LineState::GetLineState(int line) {
if (line < 0)
return 0;
lineStates.EnsureLength(line + 1); lineStates.EnsureLength(line + 1);
return lineStates[line]; return lineStates[line];
} }

View File

@ -350,10 +350,6 @@ SOURCE=..\lexers\LexNsis.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\lexers\LexObjC.cxx
# End Source File
# Begin Source File
SOURCE=..\lexers\LexOpal.cxx SOURCE=..\lexers\LexOpal.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -418,10 +414,6 @@ SOURCE=..\lexers\LexScriptol.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\lexers\LexSearchResult.cxx
# End Source File
# Begin Source File
SOURCE=..\lexers\LexSmalltalk.cxx SOURCE=..\lexers\LexSmalltalk.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -466,10 +458,6 @@ SOURCE=..\lexers\LexTeX.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\lexers\LexUser.cxx
# End Source File
# Begin Source File
SOURCE=..\lexers\LexTxt2tags.cxx SOURCE=..\lexers\LexTxt2tags.cxx
# End Source File # End Source File
# Begin Source File # Begin Source File

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
220 221

View File

@ -1322,7 +1322,6 @@ class ListBoxX : public ListBox {
int NcHitTest(WPARAM, LPARAM) const; int NcHitTest(WPARAM, LPARAM) const;
void CentreItem(int); void CentreItem(int);
void Paint(HDC); void Paint(HDC);
void Erase(HDC);
static LRESULT PASCAL ControlWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); static LRESULT PASCAL ControlWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
static const Point ItemInset; // Padding around whole item static const Point ItemInset; // Padding around whole item

View File

@ -9,8 +9,8 @@
#include "PlatformRes.h" #include "PlatformRes.h"
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2, 2, 0, 0 FILEVERSION 2, 2, 1, 0
PRODUCTVERSION 2, 2, 0, 0 PRODUCTVERSION 2, 2, 1, 0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32 FILEOS VOS_NT_WINDOWS32
@ -27,12 +27,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Neil Hodgson neilh@scintilla.org\0" VALUE "CompanyName", "Neil Hodgson neilh@scintilla.org\0"
VALUE "FileDescription", "Scintilla.DLL - a Source Editing Component\0" VALUE "FileDescription", "Scintilla.DLL - a Source Editing Component\0"
VALUE "FileVersion", "2.20\0" VALUE "FileVersion", "2.21\0"
VALUE "InternalName", "Scintilla\0" VALUE "InternalName", "Scintilla\0"
VALUE "LegalCopyright", "Copyright 1998-2010 by Neil Hodgson\0" VALUE "LegalCopyright", "Copyright 1998-2010 by Neil Hodgson\0"
VALUE "OriginalFilename", "Scintilla.DLL\0" VALUE "OriginalFilename", "Scintilla.DLL\0"
VALUE "ProductName", "Scintilla\0" VALUE "ProductName", "Scintilla\0"
VALUE "ProductVersion", "2.20\0" VALUE "ProductVersion", "2.21\0"
END END
END END
END END

View File

@ -741,18 +741,18 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
// Platform::IsKeyDown(VK_SHIFT), // Platform::IsKeyDown(VK_SHIFT),
// Platform::IsKeyDown(VK_CONTROL), // Platform::IsKeyDown(VK_CONTROL),
// Platform::IsKeyDown(VK_MENU)); // Platform::IsKeyDown(VK_MENU));
::SetFocus(MainHWND());
ButtonDown(Point::FromLong(lParam), ::GetMessageTime(), ButtonDown(Point::FromLong(lParam), ::GetMessageTime(),
(wParam & MK_SHIFT) != 0, (wParam & MK_SHIFT) != 0,
(wParam & MK_CONTROL) != 0, (wParam & MK_CONTROL) != 0,
Platform::IsKeyDown(VK_MENU)); Platform::IsKeyDown(VK_MENU));
::SetFocus(MainHWND());
} }
break; break;
case WM_MBUTTONDOWN: case WM_MBUTTONDOWN:
::SetFocus(MainHWND()); ::SetFocus(MainHWND());
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
SetTrackMouseLeaveEvent(true); SetTrackMouseLeaveEvent(true);
ButtonMove(Point::FromLong(lParam)); ButtonMove(Point::FromLong(lParam));
@ -1297,7 +1297,7 @@ void ScintillaWin::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt)
MAKELPARAM(pt.x, pt.y)); MAKELPARAM(pt.x, pt.y));
} }
class CaseFolderUTF8 : public CaseFolderTable { class CaseFolderUTF8 : public CaseFolderTable {
// Allocate the expandable storage here so that it does not need to be reallocated // Allocate the expandable storage here so that it does not need to be reallocated
// for each call to Fold. // for each call to Fold.
std::vector<wchar_t> utf16Mixed; std::vector<wchar_t> utf16Mixed;
@ -1341,13 +1341,63 @@ public:
} }
}; };
class CaseFolderDBCS : public CaseFolderTable {
// Allocate the expandable storage here so that it does not need to be reallocated
// for each call to Fold.
std::vector<wchar_t> utf16Mixed;
std::vector<wchar_t> utf16Folded;
UINT cp;
public:
CaseFolderDBCS(UINT cp_) : cp(cp_) {
StandardASCII();
}
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
if ((lenMixed == 1) && (sizeFolded > 0)) {
folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
return 1;
} else {
if (lenMixed > utf16Mixed.size()) {
utf16Mixed.resize(lenMixed + 8);
}
size_t nUtf16Mixed = ::MultiByteToWideChar(cp, 0, mixed, lenMixed,
&utf16Mixed[0], utf16Mixed.size());
if (nUtf16Mixed == 0) {
// Failed to convert -> bad input
folded[0] = '\0';
return 1;
}
if (nUtf16Mixed * 4 > utf16Folded.size()) { // Maximum folding expansion factor of 4
utf16Folded.resize(nUtf16Mixed * 4 + 8);
}
int lenFlat = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT,
LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE,
&utf16Mixed[0], nUtf16Mixed, &utf16Folded[0], utf16Folded.size());
size_t lenOut = ::WideCharToMultiByte(cp, 0,
&utf16Folded[0], lenFlat,
NULL, 0, NULL, 0);
if (lenOut < sizeFolded) {
::WideCharToMultiByte(cp, 0,
&utf16Folded[0], lenFlat,
folded, lenOut, NULL, 0);
return lenOut;
} else {
return 0;
}
}
}
};
CaseFolder *ScintillaWin::CaseFolderForEncoding() { CaseFolder *ScintillaWin::CaseFolderForEncoding() {
UINT cpDest = CodePageOfDocument(); UINT cpDest = CodePageOfDocument();
if (cpDest == SC_CP_UTF8) { if (cpDest == SC_CP_UTF8) {
return new CaseFolderUTF8(); return new CaseFolderUTF8();
} else { } else {
CaseFolderTable *pcf = new CaseFolderTable();
if (pdoc->dbcsCodePage == 0) { if (pdoc->dbcsCodePage == 0) {
CaseFolderTable *pcf = new CaseFolderTable();
pcf->StandardASCII(); pcf->StandardASCII();
// Only for single byte encodings // Only for single byte encodings
UINT cpDoc = CodePageOfDocument(); UINT cpDoc = CodePageOfDocument();
@ -1371,8 +1421,10 @@ CaseFolder *ScintillaWin::CaseFolderForEncoding() {
} }
} }
} }
return pcf;
} else {
return new CaseFolderDBCS(cpDest);
} }
return pcf;
} }
} }

View File

@ -6,7 +6,6 @@
.SUFFIXES: .cxx .SUFFIXES: .cxx
CC = g++ CC = g++
DLLWRAP = g++ -shared -Wl,--kill-at
DEL = del /q DEL = del /q
COMPONENT = ../bin/Scintilla.dll COMPONENT = ../bin/Scintilla.dll
@ -16,7 +15,8 @@ LEXLIB = Lexers.a
vpath %.h ../src ../include ../lexlib vpath %.h ../src ../include ../lexlib
vpath %.cxx ../src ../lexlib ../lexers vpath %.cxx ../src ../lexlib ../lexers
LDFLAGS=-mwindows -lstdc++ -limm32 -lole32 -luuid -mno-cygwin LDFLAGS=-shared -static -Wl,--enable-runtime-pseudo-reloc-v2 -mno-cygwin -mwindows --relocatable -Wl,--add-stdcall-alias
LIBS=-lstdc++ -limm32 -lole32 -luuid
# Add -MMD to get dependencies # Add -MMD to get dependencies
INCLUDEDIRS=-I ../include -I ../src -I../lexlib INCLUDEDIRS=-I ../include -I ../src -I../lexlib
CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -Wno-strict-overflow -pedantic $(INCLUDEDIRS) -fno-rtti -mno-cygwin CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -Wno-strict-overflow -pedantic $(INCLUDEDIRS) -fno-rtti -mno-cygwin
@ -71,7 +71,7 @@ BASEOBJS = \
SOBJS = ScintillaWin.o ScintillaBase.o $(BASEOBJS) SOBJS = ScintillaWin.o ScintillaBase.o $(BASEOBJS)
$(COMPONENT): $(SOBJS) Scintilla.def $(COMPONENT): $(SOBJS) Scintilla.def
$(DLLWRAP) --add-stdcall-alias --target=i386-mingw32 -o $@ $(SOBJS) $(LDFLAGS) $(STRIPFLAG) --relocatable $(CC) $(LDFLAGS) -o $@ $(STRIPFLAG) $(SOBJS) $(CXXFLAGS) $(LIBS)
LOBJS = \ LOBJS = \
Accessor.o \ Accessor.o \
@ -87,7 +87,7 @@ LOBJS = \
$(BASEOBJS) \ $(BASEOBJS) \
$(LEXOBJS) $(LEXOBJS)
$(LEXCOMPONENT): $(LOBJS) Scintilla.def $(LEXCOMPONENT): $(LOBJS) Scintilla.def
$(DLLWRAP) --add-stdcall-alias --target=i386-mingw32 -o $@ $(LOBJS) $(LDFLAGS) $(STRIPFLAG) --relocatable $(CC) $(LDFLAGS) -o $@ $(STRIPFLAG) $(LOBJS) $(CXXFLAGS) $(LIBS)
$(LEXLIB): $(LEXOBJS) $(LEXLIB): $(LEXOBJS)
$(AR) rc $@ $^ $(AR) rc $@ $^