diff --git a/PowerEditor/scintilla.original.forUpdating/scintilla.original.forUpdating.7z b/PowerEditor/scintilla.original.forUpdating/scintilla.original.forUpdating.7z new file mode 100644 index 00000000..1633e719 Binary files /dev/null and b/PowerEditor/scintilla.original.forUpdating/scintilla.original.forUpdating.7z differ diff --git a/scintilla/boostregex/BoostRegExSearch.cxx b/scintilla/boostregex/BoostRegExSearch.cxx index f8c8ce93..19a41e7d 100644 --- a/scintilla/boostregex/BoostRegExSearch.cxx +++ b/scintilla/boostregex/BoostRegExSearch.cxx @@ -9,6 +9,7 @@ */ #include #include +#include #include "scintilla.h" #include "Platform.h" #include "SplitVector.h" @@ -18,6 +19,7 @@ #include "CharClassify.h" #include "Decoration.h" #include "ILexer.h" +#include "CaseFolder.h" #include "Document.h" #include "UniConversion.h" #include "UTF8DocumentIterator.h" @@ -136,10 +138,17 @@ private: } } } + virtual void NotifyDeleted(Document* deletedDocument, void* /*userData*/) { if (deletedDocument == _document) + { + // We set the _document here, as we don't want to call the RemoveWatcher on this deleted document. + // Calling RemoveWatcher inside NotifyDeleted results in a crash, as NotifyDeleted is called whilst + // iterating on the watchers list (since Scintilla 3.x). Before 3.x, it was just a really bad idea. + _document = NULL; set(NULL); + } } virtual void NotifyModifyAttempt(Document* /*document*/, void* /*userData*/) {} virtual void NotifySavePoint(Document* /*document*/, void* /*userData*/, bool /*atSavePoint*/) {} diff --git a/scintilla/boostregex/UTF8DocumentIterator.h b/scintilla/boostregex/UTF8DocumentIterator.h index 3f36aad2..fee1b6b4 100644 --- a/scintilla/boostregex/UTF8DocumentIterator.h +++ b/scintilla/boostregex/UTF8DocumentIterator.h @@ -3,6 +3,7 @@ #include #include +#include #include "Platform.h" #include "SplitVector.h" #include "Partitioning.h" @@ -11,6 +12,7 @@ #include "CharClassify.h" #include "Decoration.h" #include +#include "CaseFolder.h" #include class UTF8DocumentIterator : public std::iterator diff --git a/scintilla/cocoa/InfoBar.h b/scintilla/cocoa/InfoBar.h index 96248115..1d10e795 100644 --- a/scintilla/cocoa/InfoBar.h +++ b/scintilla/cocoa/InfoBar.h @@ -45,7 +45,7 @@ - (void) setCallback: (id ) callback; - (void) createItems; -- (void) layout; +- (void) positionSubViews; - (void) setDisplay: (IBDisplay) display; - (void) zoomItemAction: (id) sender; - (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag; diff --git a/scintilla/cocoa/InfoBar.mm b/scintilla/cocoa/InfoBar.mm index dccafa7e..14035795 100644 --- a/scintilla/cocoa/InfoBar.mm +++ b/scintilla/cocoa/InfoBar.mm @@ -88,7 +88,7 @@ NSBundle* bundle = [NSBundle bundleForClass: [InfoBar class]]; NSString* path = [bundle pathForResource: @"info_bar_bg" ofType: @"png" inDirectory: nil]; - mBackground = [[[NSImage alloc] initWithContentsOfFile: path] retain]; + mBackground = [[NSImage alloc] initWithContentsOfFile: path]; if (![mBackground isValid]) NSLog(@"Background image for info bar is invalid."); @@ -294,12 +294,12 @@ static float BarFontSize = 10.0; - (void) setFrame: (NSRect) newFrame { [super setFrame: newFrame]; - [self layout]; + [self positionSubViews]; } //-------------------------------------------------------------------------------------------------- -- (void) layout +- (void) positionSubViews { NSRect currentBounds = {0, 0, 0, [self frame].size.height}; if (mDisplayMask & IBShowZoom) @@ -345,7 +345,7 @@ static float BarFontSize = 10.0; if (mDisplayMask != display) { mDisplayMask = display; - [self layout]; + [self positionSubViews]; [self needsDisplay]; } } diff --git a/scintilla/cocoa/PlatCocoa.h b/scintilla/cocoa/PlatCocoa.h index f84e3ff6..775602ba 100644 --- a/scintilla/cocoa/PlatCocoa.h +++ b/scintilla/cocoa/PlatCocoa.h @@ -57,8 +57,8 @@ private: int bitmapWidth; int bitmapHeight; - /** Set the CGContext's fill colour to the specified allocated colour. */ - void FillColour( const ColourAllocated& back ); + /** Set the CGContext's fill colour to the specified desired colour. */ + void FillColour( const ColourDesired& back ); // 24-bit RGB+A bitmap data constants @@ -76,7 +76,7 @@ public: void Release(); bool Initialised(); - void PenColour(ColourAllocated fore); + void PenColour(ColourDesired fore); /** Returns a CGImageRef that represents the surface. Returns NULL if this is not possible. */ CGImageRef GetImage(); @@ -86,31 +86,31 @@ public: int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); - void Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, ColourAllocated back); - void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void FillRectangle(PRectangle rc, ColourAllocated back); + void Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, ColourDesired back); + void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); + void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); - void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, - ColourAllocated outline, int alphaOutline, int flags); - void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); + void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, + ColourDesired outline, int alphaOutline, int flags); + void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); + void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource); - void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, - ColourAllocated back); - void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, - ColourAllocated back); - void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore); - void MeasureWidths(Font &font_, const char *s, int len, int *positions); - int WidthText(Font &font_, const char *s, int len); - int WidthChar(Font &font_, char ch); - int Ascent(Font &font_); - int Descent(Font &font_); - int InternalLeading(Font &font_); - int ExternalLeading(Font &font_); - int Height(Font &font_); - int AverageCharWidth(Font &font_); + void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, + ColourDesired back); + void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, + ColourDesired back); + void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); + void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); + XYPOSITION WidthText(Font &font_, const char *s, int len); + XYPOSITION WidthChar(Font &font_, char ch); + XYPOSITION Ascent(Font &font_); + XYPOSITION Descent(Font &font_); + XYPOSITION InternalLeading(Font &font_); + XYPOSITION ExternalLeading(Font &font_); + XYPOSITION Height(Font &font_); + XYPOSITION AverageCharWidth(Font &font_); - int SetPalette(Scintilla::Palette *pal, bool inBackGround); void SetClip(PRectangle rc); void FlushCachedState(); diff --git a/scintilla/cocoa/PlatCocoa.mm b/scintilla/cocoa/PlatCocoa.mm index f777a0db..a5e68795 100644 --- a/scintilla/cocoa/PlatCocoa.mm +++ b/scintilla/cocoa/PlatCocoa.mm @@ -28,8 +28,6 @@ #import -#import // Temporary - using namespace Scintilla; extern sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); @@ -92,48 +90,6 @@ Scintilla::Point Scintilla::Point::FromLong(long lpoint) ); } -//----------------- Palette ------------------------------------------------------------------------ - -// The Palette implementation is only here because we would get linker errors if not. -// We don't use indexed colors in ScintillaCocoa. - -Scintilla::Palette::Palette() -{ -} - -//-------------------------------------------------------------------------------------------------- - -Scintilla::Palette::~Palette() -{ -} - -//-------------------------------------------------------------------------------------------------- - -void Scintilla::Palette::Release() -{ -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Used to transform a given color, if needed. If the caller tries to find a color that matches the - * desired color then we simply pass it on, as we support the full color space. - */ -void Scintilla::Palette::WantFind(ColourPair &cp, bool want) -{ - if (!want) - cp.allocated.Set(cp.desired.AsLong()); - - // Don't do anything if the caller wants the color it has already set. -} - -//-------------------------------------------------------------------------------------------------- - -void Scintilla::Palette::Allocate(Window& w) -{ - // Nothing to allocate as we don't use palettes. -} - //----------------- Font --------------------------------------------------------------------------- Font::Font(): fid(0) @@ -149,23 +105,24 @@ Font::~Font() //-------------------------------------------------------------------------------------------------- +static int FontCharacterSet(Font &f) { + return reinterpret_cast(f.GetID())->getCharacterSet(); +} + /** - * Creates a Quartz 2D font with the given properties. - * TODO: rewrite to use NSFont. + * Creates a CTFontRef with the given properties. */ -void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic, - int extraFontFlag) +void Font::Create(const FontParameters &fp) { - // TODO: How should I handle the characterSet request? Release(); QuartzTextStyle* style = new QuartzTextStyle(); fid = style; // Create the font with attributes - QuartzFont font(faceName, strlen(faceName), size, bold, italic); + QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.italic); CTFontRef fontRef = font.getFontID(); - style->setFontRef(fontRef); + style->setFontRef(fontRef, fp.characterSet); } //-------------------------------------------------------------------------------------------------- @@ -236,7 +193,7 @@ bool SurfaceImpl::Initialised() //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Init(WindowID wid) +void SurfaceImpl::Init(WindowID) { // To be able to draw, the surface must get a CGContext handle. We save the graphics port, // then aquire/release the context on an as-need basis (see above). @@ -249,7 +206,7 @@ void SurfaceImpl::Init(WindowID wid) //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Init(SurfaceID sid, WindowID wid) +void SurfaceImpl::Init(SurfaceID sid, WindowID) { Release(); gc = reinterpret_cast(sid); @@ -259,7 +216,7 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::InitPixMap(int width, int height, Surface* surface_, WindowID wid) +void SurfaceImpl::InitPixMap(int width, int height, Surface* /* surface_ */, WindowID /* wid */) { Release(); @@ -277,26 +234,23 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface* surface_, WindowID // Create the bitmap. bitmapData = new uint8_t[bitmapByteCount]; - if (bitmapData != NULL) - { - // create the context - gc = CGBitmapContextCreate(bitmapData, - width, - height, - BITS_PER_COMPONENT, - bitmapBytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast); + // create the context + gc = CGBitmapContextCreate(bitmapData, + width, + height, + BITS_PER_COMPONENT, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaPremultipliedLast); - if (gc == NULL) - { - // the context couldn't be created for some reason, - // and we have no use for the bitmap without the context - delete[] bitmapData; - bitmapData = NULL; - } - textLayout->setContext (gc); + if (gc == NULL) + { + // the context couldn't be created for some reason, + // and we have no use for the bitmap without the context + delete[] bitmapData; + bitmapData = NULL; } + textLayout->setContext (gc); // the context retains the color space, so we can release it CGColorSpaceRelease(colorSpace); @@ -312,7 +266,7 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface* surface_, WindowID //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::PenColour(ColourAllocated fore) +void SurfaceImpl::PenColour(ColourDesired fore) { if (gc) { @@ -326,7 +280,7 @@ void SurfaceImpl::PenColour(ColourAllocated fore) //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::FillColour(const ColourAllocated& back) +void SurfaceImpl::FillColour(const ColourDesired& back) { if (gc) { @@ -356,9 +310,13 @@ CGImageRef SurfaceImpl::GetImage() const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL); const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight); + // Make a copy of the bitmap data for the image creation and divorce it + // From the SurfaceImpl lifetime + CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bitmapData, bitmapByteCount); + // Create a data provider. - CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, bitmapData, bitmapByteCount, - NULL); + CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataRef); + CGImageRef image = NULL; if (dataProvider != NULL) { @@ -384,6 +342,9 @@ CGImageRef SurfaceImpl::GetImage() CGDataProviderRelease(dataProvider); dataProvider = NULL; + // Done with the data provider. + CFRelease(dataRef); + return image; } @@ -391,27 +352,23 @@ CGImageRef SurfaceImpl::GetImage() /** * Returns the vertical logical device resolution of the main monitor. + * This is no longer called. + * For Cocoa, all screens are treated as 72 DPI, even retina displays. */ int SurfaceImpl::LogPixelsY() { - if (verticalDeviceResolution == 0) - { - NSSize deviceResolution = [[[[NSScreen mainScreen] deviceDescription] - objectForKey: NSDeviceResolution] sizeValue]; - verticalDeviceResolution = (int) deviceResolution.height; - } - return verticalDeviceResolution; + return 72; } //-------------------------------------------------------------------------------------------------- /** - * Converts the logical font height (in dpi) into a pixel height for the current main screen. + * Converts the logical font height in points into a device height. + * For Cocoa, points are always used for the result even on retina displays. */ int SurfaceImpl::DeviceHeightFont(int points) { - int logPix = LogPixelsY(); - return (points * logPix + logPix / 2) / 72; + return points; } //-------------------------------------------------------------------------------------------------- @@ -442,11 +399,11 @@ void SurfaceImpl::LineTo(int x_, int y_) //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, - ColourAllocated back) +void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, + ColourDesired back) { // Allocate memory for the array of points. - CGPoint *points = new CGPoint[npts]; + std::vector points(npts); for (int i = 0;i < npts;i++) { @@ -462,21 +419,16 @@ void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, PenColour(fore); // Draw the polygon - CGContextAddLines(gc, points, npts); + CGContextAddLines(gc, points.data(), npts); - // TODO: Should the path be automatically closed, or is that the caller's responsability? // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) CGContextClosePath( gc ); CGContextDrawPath( gc, kCGPathFillStroke ); - - // Deallocate memory. - delete points; - points = NULL; } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { if (gc) { @@ -487,7 +439,6 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAlloc // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo) // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom. - // TODO: Create some version of PRectangleToCGRect to do this conversion for us? CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) ); CGContextDrawPath( gc, kCGPathFillStroke ); } @@ -495,11 +446,14 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAlloc //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) +void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { if (gc) { FillColour(back); + // Snap rectangle boundaries to nearest int + rc.left = lround(rc.left); + rc.right = lround(rc.right); CGRect rect = PRectangleToCGRect(rc); CGContextFillRect(gc, rect); } @@ -514,6 +468,13 @@ void drawImageRefCallback(CGImageRef pattern, CGContextRef gc) //-------------------------------------------------------------------------------------------------- +void releaseImageRefCallback(CGImageRef pattern) +{ + CGImageRelease(pattern); +} + +//-------------------------------------------------------------------------------------------------- + void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl& patternSurface = static_cast(surfacePattern); @@ -522,12 +483,13 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) CGImageRef image = patternSurface.GetImage(); if (image == NULL) { - FillRectangle(rc, ColourAllocated(0)); + FillRectangle(rc, ColourDesired(0)); return; } - const CGPatternCallbacks drawImageCallbacks = { 0, - reinterpret_cast(drawImageRefCallback), NULL }; + const CGPatternCallbacks drawImageCallbacks = { 0, + reinterpret_cast(drawImageRefCallback), + reinterpret_cast(releaseImageRefCallback) }; CGPatternRef pattern = CGPatternCreate(image, CGRectMake(0, 0, patternSurface.bitmapWidth, patternSurface.bitmapHeight), @@ -559,14 +521,16 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) colorSpace = NULL; CGPatternRelease( pattern ); pattern = NULL; - CGImageRelease( image ); - image = NULL; } /* pattern != NULL */ } -void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { - // TODO: Look at the Win32 API to determine what this is supposed to do: +void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { + // This is only called from the margin marker drawing code for SC_MARK_ROUNDRECT + // The Win32 version does // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); + // which is a rectangle with rounded corners each having a radius of 4 pixels. + // It would be almost as good just cutting off the corners with lines at + // 45 degrees as is done on GTK+. // Create a rectangle with semicircles at the corners const int MAX_RADIUS = 4; @@ -600,12 +564,13 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl }; // Align the points in the middle of the pixels - // TODO: Should I include these +0.5 in the array creation code above? - for( int i = 0; i < 4*3; ++ i ) + for( int i = 0; i < 4; ++ i ) { - CGPoint* c = (CGPoint*) corners; - c[i].x += 0.5; - c[i].y += 0.5; + for( int j = 0; j < 3; ++ j ) + { + corners[i][j].x += 0.5; + corners[i][j].y += 0.5; + } } PenColour( fore ); @@ -626,12 +591,15 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl CGContextDrawPath( gc, kCGPathFillStroke ); } -void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourAllocated fill, int alphaFill, - ColourAllocated /*outline*/, int /*alphaOutline*/, int /*flags*/) +void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourDesired fill, int alphaFill, + ColourDesired /*outline*/, int /*alphaOutline*/, int /*flags*/) { if ( gc ) { ColourDesired colour( fill.AsLong() ); - + + // Snap rectangle boundaries to nearest int + rc.left = lround(rc.left); + rc.right = lround(rc.right); // Set the Fill color to match CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, alphaFill / 255.0 ); CGRect rect = PRectangleToCGRect( rc ); @@ -639,7 +607,72 @@ void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, C } } -void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +static void ProviderReleaseData(void *, const void *data, size_t) { + const unsigned char *pixels = reinterpret_cast(data); + delete []pixels; +} + +static CGImageRef ImageCreateFromRGBA(int width, int height, const unsigned char *pixelsImage, bool invert) { + CGImageRef image = 0; + + // Create an RGB color space. + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + if (colorSpace) { + const int bitmapBytesPerRow = ((int) width * 4); + const int bitmapByteCount = (bitmapBytesPerRow * (int) height); + + // Create a data provider. + CGDataProviderRef dataProvider = 0; + if (invert) { + unsigned char *pixelsUpsideDown = new unsigned char[bitmapByteCount]; + + for (int y=0; y(font_.GetID()); style->setCTStyleColor(color); + + CGColorRelease(color); - textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + textLayout->setText (reinterpret_cast(s), len, encoding, *reinterpret_cast(font_.GetID())); textLayout->draw(rc.left, ybase); } +static size_t utf8LengthFromLead(unsigned char uch) { + if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { + return 4; + } else if (uch >= (0x80 + 0x40 + 0x20)) { + return 3; + } else if (uch >= (0x80)) { + return 2; + } else { + return 1; + } +} + //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { - for (int i = 0; i < len; i++) - positions [i] = 0; - textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); + textLayout->setText (reinterpret_cast(s), len, encoding, *reinterpret_cast(font_.GetID())); CTLineRef mLine = textLayout->getCTLine(); assert(mLine != NULL); - CGFloat* secondaryOffset= 0; - int unicodeCharStart = 0; - for ( int i = 0; i < len+1; i ++ ){ - unsigned char uch = s[i]; - CFIndex charIndex = unicodeCharStart+1; - CGFloat advance = CTLineGetOffsetForStringIndex(mLine, charIndex, secondaryOffset); - - if ( unicodeMode ) - { - unsigned char mask = 0xc0; - int lcount = 1; - // Add one additonal byte for each extra high order one in the byte - while ( uch >= mask && lcount < 8 ) - { - positions[i++] = (int)(advance+0.5); - lcount ++; - mask = mask >> 1 | 0x80; // add an additional one in the highest order position + if (unicodeMode) { + // Map the widths given for UTF-16 characters back onto the UTF-8 input string + CFIndex fit = textLayout->getStringLength(); + int ui=0; + const unsigned char *us = reinterpret_cast(s); + int i=0; + while (ui 0) + lastPos = positions[i-1]; + while (isetText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); + textLayout->setText (reinterpret_cast(s), len, encoding, *reinterpret_cast(font_.GetID())); return textLayout->MeasureStringWidth(); } return 1; } -int SurfaceImpl::WidthChar(Font &font_, char ch) { +XYPOSITION SurfaceImpl::WidthChar(Font &font_, char ch) { char str[2] = { ch, '\0' }; if (font_.GetID()) { - textLayout->setText (reinterpret_cast(str), 1, *reinterpret_cast(font_.GetID())); + CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); + textLayout->setText (reinterpret_cast(str), 1, encoding, *reinterpret_cast(font_.GetID())); return textLayout->MeasureStringWidth(); } @@ -909,7 +975,7 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) { const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -int SurfaceImpl::Ascent(Font &font_) { +XYPOSITION SurfaceImpl::Ascent(Font &font_) { if (!font_.GetID()) return 1; @@ -918,7 +984,7 @@ int SurfaceImpl::Ascent(Font &font_) { } -int SurfaceImpl::Descent(Font &font_) { +XYPOSITION SurfaceImpl::Descent(Font &font_) { if (!font_.GetID()) return 1; @@ -927,13 +993,11 @@ int SurfaceImpl::Descent(Font &font_) { } -int SurfaceImpl::InternalLeading(Font &) { - // TODO: How do we get EM_Size? - // internal leading = ascent - descent - EM_size +XYPOSITION SurfaceImpl::InternalLeading(Font &) { return 0; } -int SurfaceImpl::ExternalLeading(Font &font_) { +XYPOSITION SurfaceImpl::ExternalLeading(Font &font_) { if (!font_.GetID()) return 1; @@ -942,13 +1006,13 @@ int SurfaceImpl::ExternalLeading(Font &font_) { } -int SurfaceImpl::Height(Font &font_) { +XYPOSITION SurfaceImpl::Height(Font &font_) { int ht = Ascent(font_) + Descent(font_); return ht; } -int SurfaceImpl::AverageCharWidth(Font &font_) { +XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { if (!font_.GetID()) return 1; @@ -959,11 +1023,6 @@ int SurfaceImpl::AverageCharWidth(Font &font_) { return (int) ((width / (float) sizeStringLength) + 0.5); } -int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) { - // Mac OS X is always true colour (I think) so this doesn't matter - return 0; -} - void SurfaceImpl::SetClip(PRectangle rc) { CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); } @@ -981,7 +1040,7 @@ void SurfaceImpl::SetDBCSMode(int codePage_) { codePage = codePage_; } -Surface *Surface::Allocate() +Surface *Surface::Allocate(int) { return new SurfaceImpl(); } @@ -1041,8 +1100,7 @@ PRectangle Window::GetPosition() // NSView NSView* view = reinterpret_cast(idWin); win = [view window]; - rect = [view bounds]; - rect = [view convertRectToBase: rect]; + rect = [view convertRect: [view bounds] toView: nil]; rect.origin = [win convertBaseToScreen:rect.origin]; } else @@ -1260,17 +1318,18 @@ static NSImage* ImageFromXPM(XPM* pxpm) const int width = pxpm->GetWidth(); const int height = pxpm->GetHeight(); PRectangle rcxpm(0, 0, width, height); - Surface* surfaceXPM = Surface::Allocate(); + Surface* surfaceXPM = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceXPM) { surfaceXPM->InitPixMap(width, height, NULL, NULL); SurfaceImpl* surfaceIXPM = static_cast(surfaceXPM); CGContextClearRect(surfaceIXPM->GetContext(), CGRectMake(0, 0, width, height)); pxpm->Draw(surfaceXPM, rcxpm); - img = [NSImage alloc]; - [img autorelease]; + img = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease]; CGImageRef imageRef = surfaceIXPM->GetImage(); - [img initWithCGImage:imageRef size:NSZeroSize]; + NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; + [img addRepresentation: bitmapRep]; + [bitmapRep release]; CGImageRelease(imageRef); delete surfaceXPM; } @@ -1278,19 +1337,85 @@ static NSImage* ImageFromXPM(XPM* pxpm) return img; } -//----------------- ListBox ------------------------------------------------------------------------ +//----------------- ListBox and related classes ---------------------------------------------------- -ListBox::ListBox() +namespace { + +// unnamed namespace hides IListBox interface + +class IListBox { +public: + virtual int Rows() = 0; + virtual NSImage* ImageForRow(NSInteger row) = 0; + virtual NSString* TextForRow(NSInteger row) = 0; + virtual void DoubleClick() = 0; +}; + +} // unnamed namespace + +//----------------- AutoCompletionDataSource ------------------------------------------------------- + +@interface AutoCompletionDataSource : +NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + +#endif { + IListBox* box; } -//-------------------------------------------------------------------------------------------------- +@property IListBox* box; -ListBox::~ListBox() +@end + +@implementation AutoCompletionDataSource + +@synthesize box; + +- (void) doubleClick: (id) sender { +#pragma unused(sender) + if (box) + { + box->DoubleClick(); + } } -//-------------------------------------------------------------------------------------------------- +- (id)tableView: (NSTableView*)aTableView objectValueForTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex +{ +#pragma unused(aTableView) + if (!box) + return nil; + if ([(NSString*)[aTableColumn identifier] isEqualToString: @"icon"]) + { + return box->ImageForRow(rowIndex); + } + else { + return box->TextForRow(rowIndex); + } +} + +- (void)tableView: (NSTableView*)aTableView setObjectValue: anObject forTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex +{ +#pragma unused(aTableView) +#pragma unused(anObject) +#pragma unused(aTableColumn) +#pragma unused(rowIndex) +} + +- (NSInteger)numberOfRowsInTableView: (NSTableView*)aTableView +{ +#pragma unused(aTableView) + if (!box) + return 0; + return box->Rows(); +} + +@end + +//----------------- ListBoxImpl -------------------------------------------------------------------- + +namespace { // unnamed namespace hides ListBoxImpl and associated classes struct RowData { @@ -1314,17 +1439,17 @@ public: } int Length() const { - return lines.size(); + return static_cast(lines.size()); } void Clear() { lines.clear(); } - void Add(int index, int type, char* str) + void Add(int /* index */, int type, char* str) { lines.push_back(RowData(type, str)); } - int GetType(int index) const + int GetType(size_t index) const { if (index < lines.size()) { @@ -1335,7 +1460,7 @@ public: return 0; } } - const char* GetString(int index) const + const char* GetString(size_t index) const { if (index < lines.size()) { @@ -1348,25 +1473,12 @@ public: } }; -class ListBoxImpl; - -@interface AutoCompletionDataSource : -NSObject -{ - ListBoxImpl* box; -} - -@end - -//----------------- ListBoxImpl -------------------------------------------------------------------- - // Map from icon type to an NSImage* -typedef std::map ImageMap; +typedef std::map ImageMap; -class ListBoxImpl : public ListBox +class ListBoxImpl : public ListBox, IListBox { private: - ControlRef lb; ImageMap images; int lineHeight; bool unicodeMode; @@ -1381,22 +1493,23 @@ private: NSScrollView* scroller; NSTableColumn* colIcon; NSTableColumn* colText; - + AutoCompletionDataSource* ds; + LinesData ld; CallBackAction doubleClickAction; void* doubleClickActionData; public: - ListBoxImpl() : lb(NULL), lineHeight(10), unicodeMode(false), + ListBoxImpl() : lineHeight(10), unicodeMode(false), desiredVisibleRows(5), maxItemWidth(0), aveCharWidth(8), maxIconWidth(0), doubleClickAction(NULL), doubleClickActionData(NULL) { } - ~ListBoxImpl() {}; + ~ListBoxImpl() {} // ListBox methods void SetFont(Font& font); - void Create(Window& parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_); + void Create(Window& parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int technology_); void SetAverageCharWidth(int width); void SetVisibleRows(int rows); int GetVisibleRows() const; @@ -1410,6 +1523,7 @@ public: int Find(const char* prefix); void GetValue(int n, char* value, int len); void RegisterImage(int type, const char* xpm_data); + void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage); void ClearRegisteredImages(); void SetDoubleClickAction(CallBackAction action, void* data) { @@ -1418,68 +1532,15 @@ public: } void SetList(const char* list, char separator, char typesep); - // For access from AutoCompletionDataSource + // For access from AutoCompletionDataSource implement IListBox int Rows(); - NSImage* ImageForRow(int row); - NSString* TextForRow(int row); + NSImage* ImageForRow(NSInteger row); + NSString* TextForRow(NSInteger row); void DoubleClick(); }; -@implementation AutoCompletionDataSource - -- (void)setBox: (ListBoxImpl*)box_ -{ - box = box_; -} - -- (void) doubleClick: (id) sender -{ - if (box) - { - box->DoubleClick(); - } -} - -- (id)tableView: (NSTableView*)aTableView objectValueForTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex -{ -#pragma unused(aTableView) - if (!box) - return nil; - if ([(NSString*)[aTableColumn identifier] isEqualToString: @"icon"]) - { - return box->ImageForRow(rowIndex); - } - else { - return box->TextForRow(rowIndex); - } -} - -- (void)tableView: (NSTableView*)aTableView setObjectValue: anObject forTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex -{ -#pragma unused(aTableView) -#pragma unused(anObject) -#pragma unused(aTableColumn) -#pragma unused(rowIndex) -} - -- (NSInteger)numberOfRowsInTableView: (NSTableView*)aTableView -{ -#pragma unused(aTableView) - if (!box) - return 0; - return box->Rows(); -} - -@end - -ListBox* ListBox::Allocate() -{ - ListBoxImpl* lb = new ListBoxImpl(); - return lb; -} - void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt, - int lineHeight_, bool unicodeMode_) + int lineHeight_, bool unicodeMode_, int) { lineHeight = lineHeight_; unicodeMode = unicodeMode_; @@ -1496,24 +1557,23 @@ void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt NSRect scRect = NSMakeRect(0, 0, lbRect.size.width, lbRect.size.height); [scroller initWithFrame: scRect]; [scroller setHasVerticalScroller:YES]; - table = [NSTableView alloc]; - [table initWithFrame: scRect]; + table = [[NSTableView alloc] initWithFrame: scRect]; [table setHeaderView:nil]; [scroller setDocumentView: table]; colIcon = [[NSTableColumn alloc] initWithIdentifier:@"icon"]; [colIcon setWidth: 20]; [colIcon setEditable:NO]; [colIcon setHidden:YES]; - NSImageCell* imCell = [[NSImageCell alloc] init]; + NSImageCell* imCell = [[[NSImageCell alloc] init] autorelease]; [colIcon setDataCell:imCell]; [table addTableColumn:colIcon]; colText = [[NSTableColumn alloc] initWithIdentifier:@"name"]; [colText setResizingMask:NSTableColumnAutoresizingMask]; [colText setEditable:NO]; [table addTableColumn:colText]; - AutoCompletionDataSource* ds = [[AutoCompletionDataSource alloc] init]; + ds = [[AutoCompletionDataSource alloc] init]; [ds setBox:this]; - [table setDataSource: ds]; + [table setDataSource: ds]; // Weak reference [scroller setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [[winLB contentView] addSubview: scroller]; @@ -1524,13 +1584,14 @@ void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt void ListBoxImpl::SetFont(Font& font_) { - font.SetID(font_.GetID()); // NSCell setFont takes an NSFont* rather than a CTFontRef but they // are the same thing toll-free bridged. QuartzTextStyle* style = reinterpret_cast(font_.GetID()); + font.Release(); + font.SetID(new QuartzTextStyle(*style)); NSFont *pfont = (NSFont *)style->getFontRef(); [[colText dataCell] setFont: pfont]; - CGFloat itemHeight = lround([pfont ascender] - [pfont descender]); + CGFloat itemHeight = ceil([pfont boundingRectForFont].size.height); [table setRowHeight:itemHeight]; } @@ -1600,7 +1661,7 @@ void ListBoxImpl::Append(char* s, int type) ld.Add(count, type, s); Scintilla::SurfaceImpl surface; - unsigned int width = surface.WidthText(font, s, strlen(s)); + unsigned int width = surface.WidthText(font, s, static_cast(strlen(s))); if (width > maxItemWidth) { maxItemWidth = width; @@ -1626,37 +1687,32 @@ void ListBoxImpl::Append(char* s, int type) void ListBoxImpl::SetList(const char* list, char separator, char typesep) { Clear(); - int count = strlen(list) + 1; - char* words = new char[count]; - if (words) + size_t count = strlen(list) + 1; + std::vector words(list, list+count); + char* startword = words.data(); + char* numword = NULL; + int i = 0; + for (; words[i]; i++) { - memcpy(words, list, count); - char* startword = words; - char* numword = NULL; - int i = 0; - for (; words[i]; i++) - { - if (words[i] == separator) - { - words[i] = '\0'; - if (numword) - *numword = '\0'; - Append(startword, numword?atoi(numword + 1):-1); - startword = words + i + 1; - numword = NULL; - } - else if (words[i] == typesep) - { - numword = words + i; - } - } - if (startword) + if (words[i] == separator) { + words[i] = '\0'; if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); + startword = words.data() + i + 1; + numword = NULL; } - delete []words; + else if (words[i] == typesep) + { + numword = words.data() + i; + } + } + if (startword) + { + if (numword) + *numword = '\0'; + Append(startword, numword?atoi(numword + 1):-1); } [table reloadData]; } @@ -1674,7 +1730,7 @@ void ListBoxImpl::Select(int n) int ListBoxImpl::GetSelection() { - return [table selectedRow]; + return static_cast([table selectedRow]); } int ListBoxImpl::Find(const char* prefix) @@ -1706,7 +1762,6 @@ void ListBoxImpl::GetValue(int n, char* value, int len) void ListBoxImpl::RegisterImage(int type, const char* xpm_data) { XPM xpm(xpm_data); - xpm.CopyDesiredColours(); NSImage* img = ImageFromXPM(&xpm); [img retain]; ImageMap::iterator it=images.find(type); @@ -1721,6 +1776,27 @@ void ListBoxImpl::RegisterImage(int type, const char* xpm_data) } } +void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { + CGImageRef imageRef = ImageCreateFromRGBA(width, height, pixelsImage, false); + NSSize sz = {static_cast(width), static_cast(height)}; + NSImage *img = [[[NSImage alloc] initWithSize: sz] autorelease]; + NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; + [img addRepresentation: bitmapRep]; + [bitmapRep release]; + CGImageRelease(imageRef); + [img retain]; + ImageMap::iterator it=images.find(type); + if (it == images.end()) + { + images[type] = img; + } + else + { + [it->second release]; + it->second = img; + } +} + void ListBoxImpl::ClearRegisteredImages() { for (ImageMap::iterator it=images.begin(); @@ -1737,13 +1813,12 @@ int ListBoxImpl::Rows() return ld.Length(); } -NSImage* ListBoxImpl::ImageForRow(int row) +NSImage* ListBoxImpl::ImageForRow(NSInteger row) { ImageMap::iterator it = images.find(ld.GetType(row)); if (it != images.end()) { NSImage* img = it->second; - [img retain]; return img; } else @@ -1752,7 +1827,7 @@ NSImage* ListBoxImpl::ImageForRow(int row) } } -NSString* ListBoxImpl::TextForRow(int row) +NSString* ListBoxImpl::TextForRow(NSInteger row) { const char* textString = ld.GetString(row); NSString* sTitle; @@ -1771,6 +1846,24 @@ void ListBoxImpl::DoubleClick() } } +} // unnamed namespace + +//----------------- ListBox ------------------------------------------------------------------------ + +ListBox::ListBox() +{ +} + +ListBox::~ListBox() +{ +} + +ListBox* ListBox::Allocate() +{ + ListBoxImpl* lb = new ListBoxImpl(); + return lb; +} + //----------------- ScintillaContextMenu ----------------------------------------------------------- @implementation ScintillaContextMenu : NSMenu @@ -1818,7 +1911,7 @@ void Menu::Destroy() //-------------------------------------------------------------------------------------------------- -void Menu::Show(Point pt, Window &) +void Menu::Show(Point, Window &) { // Cocoa menus are handled a bit differently. We only create the menu. The framework // takes care to show it properly. @@ -1826,11 +1919,12 @@ void Menu::Show(Point pt, Window &) //----------------- ElapsedTime -------------------------------------------------------------------- -// TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday +// ElapsedTime is used for precise performance measurements during development +// and not for anything a user sees. + ElapsedTime::ElapsedTime() { struct timeval curTime; - int retVal; - retVal = gettimeofday( &curTime, NULL ); + gettimeofday( &curTime, NULL ); bigBit = curTime.tv_sec; littleBit = curTime.tv_usec; @@ -1838,8 +1932,7 @@ ElapsedTime::ElapsedTime() { double ElapsedTime::Duration(bool reset) { struct timeval curTime; - int retVal; - retVal = gettimeofday( &curTime, NULL ); + gettimeofday( &curTime, NULL ); long endBigBit = curTime.tv_sec; long endLittleBit = curTime.tv_usec; double result = 1000000.0 * (endBigBit - bigBit); @@ -1884,7 +1977,8 @@ const char *Platform::DefaultFont() */ int Platform::DefaultFontSize() { - return [[NSUserDefaults standardUserDefaults] integerForKey: @"NSFixedPitchFontSize"]; + return static_cast([[NSUserDefaults standardUserDefaults] + integerForKey: @"NSFixedPitchFontSize"]); } //-------------------------------------------------------------------------------------------------- @@ -1901,7 +1995,7 @@ unsigned int Platform::DoubleClickTime() @"com.apple.mouse.doubleClickThreshold"]; if (threshold == 0) threshold = 0.5; - return static_cast(threshold / kEventDurationMillisecond); + return static_cast(threshold * 1000.0); } //-------------------------------------------------------------------------------------------------- @@ -1914,7 +2008,7 @@ bool Platform::MouseButtonBounce() //-------------------------------------------------------------------------------------------------- /** - * Helper method for the backend to reach through to the scintiall window. + * Helper method for the backend to reach through to the scintilla window. */ long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { @@ -1924,7 +2018,7 @@ long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, //-------------------------------------------------------------------------------------------------- /** - * Helper method for the backend to reach through to the scintiall window. + * Helper method for the backend to reach through to the scintilla window. */ long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { @@ -1942,7 +2036,8 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || - ((uch >= 0xE0) && (uch <= 0xEF)); + ((uch >= 0xE0) && (uch <= 0xFC)); + // Lead bytes F0 to FC may be a Microsoft addition. case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); @@ -1964,9 +2059,9 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) //-------------------------------------------------------------------------------------------------- -int Platform::DBCSCharLength(int codePage, const char* s) +int Platform::DBCSCharLength(int /* codePage */, const char* /* s */) { - // No support for DBCS. + // DBCS no longer uses this. return 1; } @@ -1974,7 +2069,6 @@ int Platform::DBCSCharLength(int codePage, const char* s) int Platform::DBCSCharMaxLength() { - // No support for DBCS. return 2; } @@ -1998,7 +2092,7 @@ int Platform::Maximum(int a, int b) { void Platform::DebugDisplay(const char *s) { - fprintf( stderr, s ); + fprintf( stderr, "%s", s ); } //-------------------------------------------------------------------------------------------------- @@ -2067,8 +2161,9 @@ int Platform::Clamp(int val, int minVal, int maxVal) * @param modulePath The path to the module to load. * @return A library instance or NULL if the module could not be found or another problem occured. */ -DynamicLibrary* DynamicLibrary::Load(const char* modulePath) +DynamicLibrary* DynamicLibrary::Load(const char* /* modulePath */) { + // Not implemented. return NULL; } diff --git a/scintilla/cocoa/QuartzTextLayout.h b/scintilla/cocoa/QuartzTextLayout.h index df09cde2..9f2681ec 100644 --- a/scintilla/cocoa/QuartzTextLayout.h +++ b/scintilla/cocoa/QuartzTextLayout.h @@ -24,6 +24,7 @@ public: { mString = NULL; mLine = NULL; + stringLength = 0; setContext(context); } @@ -41,12 +42,14 @@ public: } } - inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) + inline void setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding, const QuartzTextStyle& r ) { - CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, kCFStringEncodingUTF8, false ); + CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); if (!str) return; + stringLength = CFStringGetLength(str); + CFMutableDictionaryRef stringAttribs = r.getCTStyle(); if (mString != NULL) @@ -89,6 +92,10 @@ public: return mLine; } + CFIndex getStringLength() { + return stringLength; + } + inline void setContext (CGContextRef context) { gc = context; @@ -98,6 +105,7 @@ private: CGContextRef gc; CFAttributedStringRef mString; CTLineRef mLine; + CFIndex stringLength; }; #endif diff --git a/scintilla/cocoa/QuartzTextStyle.h b/scintilla/cocoa/QuartzTextStyle.h index cd3a9012..976169b9 100644 --- a/scintilla/cocoa/QuartzTextStyle.h +++ b/scintilla/cocoa/QuartzTextStyle.h @@ -13,65 +13,96 @@ class QuartzTextStyle { public: - QuartzTextStyle() - { - styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL); - } + QuartzTextStyle() + { + fontRef = NULL; + styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); - ~QuartzTextStyle() - { + characterSet = 0; + } + + QuartzTextStyle(const QuartzTextStyle &other) + { + // Does not copy font colour attribute + fontRef = static_cast(CFRetain(other.fontRef)); + styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); + characterSet = other.characterSet; + } + + ~QuartzTextStyle() + { if (styleDict != NULL) { CFRelease(styleDict); styleDict = NULL; } - } - + + if (fontRef) + { + CFRelease(fontRef); + fontRef = NULL; + } + } + CFMutableDictionaryRef getCTStyle() const { return styleDict; } - - void setCTStyleColor(CGColor* inColor ) + + void setCTStyleColor(CGColor *inColor) { CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, inColor); } - + float getAscent() const { return ::CTFontGetAscent(fontRef); } - + float getDescent() const { return ::CTFontGetDescent(fontRef); } - + float getLeading() const { return ::CTFontGetLeading(fontRef); } - - void setFontRef(CTFontRef inRef) + + void setFontRef(CTFontRef inRef, int characterSet_) { fontRef = inRef; - + characterSet = characterSet_; + if (styleDict != NULL) CFRelease(styleDict); - styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL); - + styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); } - + CTFontRef getFontRef() { return fontRef; } - + + int getCharacterSet() + { + return characterSet; + } + private: CFMutableDictionaryRef styleDict; CTFontRef fontRef; + int characterSet; }; #endif diff --git a/scintilla/cocoa/QuartzTextStyleAttribute.h b/scintilla/cocoa/QuartzTextStyleAttribute.h index c7505818..7f389b41 100644 --- a/scintilla/cocoa/QuartzTextStyleAttribute.h +++ b/scintilla/cocoa/QuartzTextStyleAttribute.h @@ -16,12 +16,13 @@ class QuartzFont { public: /** Create a font style from a name. */ - QuartzFont( const char* name, int length, float size, bool bold, bool italic ) + QuartzFont( const char* name, size_t length, float size, int weight, bool italic ) { assert( name != NULL && length > 0 && name[length] == '\0' ); CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); assert(fontName != NULL); + bool bold = weight > SC_WEIGHT_NORMAL; if (bold || italic) { @@ -43,13 +44,29 @@ public: // create a font and then a copy of it with the sym traits CTFontRef iFont = ::CTFontCreateWithName(fontName, size, NULL); fontid = ::CTFontCreateCopyWithSymbolicTraits(iFont, size, NULL, desiredTrait, traitMask); - CFRelease(iFont); + if (fontid) + { + CFRelease(iFont); + } + else + { + // Traits failed so use base font + fontid = iFont; + } } else { // create the font, no traits fontid = ::CTFontCreateWithName(fontName, size, NULL); } + + if (!fontid) + { + // Failed to create requested font so use font always present + fontid = ::CTFontCreateWithName((CFStringRef)@"Monaco", size, NULL); + } + + CFRelease(fontName); } CTFontRef getFontID() diff --git a/scintilla/cocoa/ScintillaCocoa.h b/scintilla/cocoa/ScintillaCocoa.h index fbf4b002..c12c7e8f 100644 --- a/scintilla/cocoa/ScintillaCocoa.h +++ b/scintilla/cocoa/ScintillaCocoa.h @@ -20,6 +20,7 @@ #include #include +#include #include "ILexer.h" @@ -28,7 +29,6 @@ #include "PropSetSimple.h" #endif -#include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" @@ -44,18 +44,23 @@ #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" +#include "CaseFolder.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" -//#include "ScintillaCallTip.h" #include "ScintillaBase.h" +#include "CaseConvert.h" extern "C" NSString* ScintillaRecPboardType; +@class InnerView; +@class MarginView; @class ScintillaView; +@class FindHighlightLayer; + /** * Helper class to be used as timer target (NSTimer). */ @@ -106,6 +111,8 @@ private: bool capturedMouse; + bool enteredSetScrollingSize; + // Private so ScintillaCocoa objects can not be copied ScintillaCocoa(const ScintillaCocoa &) : ScintillaBase() {} ScintillaCocoa &operator=(const ScintillaCocoa &) { return * this; } @@ -115,7 +122,14 @@ private: int scrollSpeed; int scrollTicks; + NSTimer* tickTimer; + NSTimer* idleTimer; + CFRunLoopObserverRef observer; + + FindHighlightLayer *layerFindIndicator; + protected: + Point GetVisibleOriginInMain(); PRectangle GetClientRectangle(); Point ConvertPoint(NSPoint point); @@ -123,31 +137,36 @@ protected: virtual void Finalise(); virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); -public: - NSView* ContentView(); + virtual void CancelModes(); - ScintillaCocoa(NSView* view); +public: + ScintillaCocoa(InnerView* view, MarginView* viewMargin); virtual ~ScintillaCocoa(); void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback); sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); ScintillaView* TopContainer(); + NSScrollView* ScrollContainer(); + InnerView* ContentView(); - void SyncPaint(void* gc, PRectangle rc); - void Draw(NSRect rect, CGContextRef gc); + bool SyncPaint(void* gc, PRectangle rc); + bool Draw(NSRect rect, CGContextRef gc); + void PaintMargin(NSRect aRect); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); void SetTicking(bool on); bool SetIdle(bool on); void SetMouseCapture(bool on); bool HaveMouseCapture(); + void ScrollText(int linesToMove); void SetVerticalScrollPos(); void SetHorizontalScrollPos(); bool ModifyScrollBars(int nMax, int nPage); + bool SetScrollingSize(void); void Resize(); - void DoScroll(float position, NSScrollerPart part, bool horizontal); - + void UpdateForScroll(); + // Notifications for the owner. void NotifyChange(); void NotifyFocus(bool focus); @@ -174,8 +193,15 @@ public: void TimerFired(NSTimer* timer); void IdleTimerFired(); + static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *sci); + void ObserverAdd(); + void ObserverRemove(); + virtual void IdleWork(); + virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo); int InsertText(NSString* input); - + void SelectOnlyMainSelection(); + virtual void SetDocPointer(Document *document); + bool KeyboardInput(NSEvent* event); void MouseDown(NSEvent* event); void MouseMove(NSEvent* event); @@ -204,6 +230,11 @@ public: void HandleCommand(NSInteger command); virtual void ActiveStateChanged(bool isActive); + + // Find indicator + void ShowFindIndicatorForRange(NSRange charRange, BOOL retaining); + void MoveFindIndicatorWithBounce(BOOL bounce); + void HideFindIndicator(); }; diff --git a/scintilla/cocoa/ScintillaCocoa.mm b/scintilla/cocoa/ScintillaCocoa.mm index 030397ec..8b93521b 100644 --- a/scintilla/cocoa/ScintillaCocoa.mm +++ b/scintilla/cocoa/ScintillaCocoa.mm @@ -15,8 +15,11 @@ */ #import - -#import // Temporary +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 +#import +#endif +#import +#import #include "ScintillaView.h" #include "PlatCocoa.h" @@ -34,18 +37,19 @@ NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular" // Define keyboard shortcuts (equivalents) the Mac way. #define SCI_CMD ( SCI_CTRL) #define SCI_SCMD ( SCI_CMD | SCI_SHIFT) -#define SCI_META ( SCMOD_META ) #define SCI_SMETA ( SCI_META | SCI_SHIFT) static const KeyToCommand macMapDefault[] = { // OS X specific - {SCK_DOWN, SCI_CMD, SCI_DOCUMENTEND}, - {SCK_UP, SCI_CMD, SCI_DOCUMENTSTART}, - {SCK_LEFT, SCI_CMD, SCI_VCHOME}, - {SCK_LEFT, SCI_SCMD, SCI_VCHOMEEXTEND}, - {SCK_RIGHT, SCI_CMD, SCI_LINEEND}, - {SCK_RIGHT, SCI_SCMD, SCI_LINEENDEXTEND}, + {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, + {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, + {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, + {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, + {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, + {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, + {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, + {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, // Similar to Windows and GTK+ // Where equivalent clashes with OS X standard, use Meta instead @@ -106,7 +110,7 @@ static const KeyToCommand macMapDefault[] = {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {SCK_BACK, SCI_ALT, SCI_UNDO}, + {SCK_BACK, SCI_ALT, SCI_DELWORDLEFT}, {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, {'z', SCI_CMD, SCI_UNDO}, {'z', SCI_SCMD, SCI_REDO}, @@ -133,11 +137,179 @@ static const KeyToCommand macMapDefault[] = //-------------------------------------------------------------------------------------------------- +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + +// Only implement FindHighlightLayer on OS X 10.6+ + +/** + * Class to display the animated gold roundrect used on OS X for matches. + */ +@interface FindHighlightLayer : CAGradientLayer +{ +@private + NSString *sFind; + int positionFind; + BOOL retaining; + CGFloat widthText; + CGFloat heightLine; + NSString *sFont; + CGFloat fontSize; +} + +@property (copy) NSString *sFind; +@property (assign) int positionFind; +@property (assign) BOOL retaining; +@property (assign) CGFloat widthText; +@property (assign) CGFloat heightLine; +@property (copy) NSString *sFont; +@property (assign) CGFloat fontSize; + +- (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce; +- (void) hideMatch; + +@end + +//-------------------------------------------------------------------------------------------------- + +@implementation FindHighlightLayer + +@synthesize sFind, positionFind, retaining, widthText, heightLine, sFont, fontSize; + +-(id) init { + if (self = [super init]) { + [self setNeedsDisplayOnBoundsChange: YES]; + // A gold to slightly redder gradient to match other applications + CGColorRef colGold = CGColorCreateGenericRGB(1.0, 1.0, 0, 1.0); + CGColorRef colGoldRed = CGColorCreateGenericRGB(1.0, 0.8, 0, 1.0); + self.colors = [NSArray arrayWithObjects:(id)colGoldRed, (id)colGold, nil]; + CGColorRelease(colGoldRed); + CGColorRelease(colGold); + + CGColorRef colGreyBorder = CGColorCreateGenericGray(0.756f, 0.5f); + self.borderColor = colGreyBorder; + CGColorRelease(colGreyBorder); + + self.borderWidth = 1.0; + self.cornerRadius = 5.0f; + self.shadowRadius = 1.0f; + self.shadowOpacity = 0.9f; + self.shadowOffset = CGSizeMake(0.0f, -2.0f); + self.anchorPoint = CGPointMake(0.5, 0.5); + } + return self; + +} + +const CGFloat paddingHighlightX = 4; +const CGFloat paddingHighlightY = 2; + +-(void) drawInContext:(CGContextRef)context { + if (!sFind || !sFont) + return; + + CFStringRef str = CFStringRef(sFind); + + CFMutableDictionaryRef styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CGColorRef color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0); + CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, color); + CTFontRef fontRef = ::CTFontCreateWithName((CFStringRef)sFont, fontSize, NULL); + CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); + + CFAttributedStringRef attrString = ::CFAttributedStringCreate(NULL, str, styleDict); + CTLineRef textLine = ::CTLineCreateWithAttributedString(attrString); + // Indent from corner of bounds + CGContextSetTextPosition(context, paddingHighlightX, 3 + paddingHighlightY); + CTLineDraw(textLine, context); + + CFRelease(textLine); + CFRelease(attrString); + CFRelease(fontRef); + CGColorRelease(color); + CFRelease(styleDict); +} + +- (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce { + if (!self.sFind || ![self.sFind length]) { + [self hideMatch]; + return; + } + + CGFloat width = self.widthText + paddingHighlightX * 2; + CGFloat height = self.heightLine + paddingHighlightY * 2; + + CGFloat flipper = self.geometryFlipped ? -1.0 : 1.0; + + // Adjust for padding + ptText.x -= paddingHighlightX; + ptText.y += flipper * paddingHighlightY; + + // Shift point to centre as expanding about centre + ptText.x += width / 2.0; + ptText.y -= flipper * height / 2.0; + + [CATransaction begin]; + [CATransaction setValue:[NSNumber numberWithFloat:0.0] forKey:kCATransactionAnimationDuration]; + self.bounds = CGRectMake(0,0, width, height); + self.position = ptText; + if (bounce) { + // Do not reset visibility when just moving + self.hidden = NO; + self.opacity = 1.0; + } + [self setNeedsDisplay]; + [CATransaction commit]; + + if (bounce) { + CABasicAnimation *animBounce = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + animBounce.duration = 0.15; + animBounce.autoreverses = YES; + animBounce.removedOnCompletion = NO; + animBounce.fromValue = [NSNumber numberWithFloat: 1.0]; + animBounce.toValue = [NSNumber numberWithFloat: 1.25]; + + if (self.retaining) { + + [self addAnimation: animBounce forKey:@"animateFound"]; + + } else { + + CABasicAnimation *animFade = [CABasicAnimation animationWithKeyPath:@"opacity"]; + animFade.duration = 0.1; + animFade.beginTime = 0.4; + animFade.removedOnCompletion = NO; + animFade.fromValue = [NSNumber numberWithFloat: 1.0]; + animFade.toValue = [NSNumber numberWithFloat: 0.0]; + + CAAnimationGroup *group = [CAAnimationGroup animation]; + [group setDuration:0.5]; + group.removedOnCompletion = NO; + group.fillMode = kCAFillModeForwards; + [group setAnimations:[NSArray arrayWithObjects:animBounce, animFade, nil]]; + + [self addAnimation:group forKey:@"animateFound"]; + } + } +} + +- (void) hideMatch { + self.sFind = @""; + self.positionFind = INVALID_POSITION; + self.hidden = YES; +} + +@end + +#endif + +//-------------------------------------------------------------------------------------------------- + @implementation TimerTarget - (id) init: (void*) target { - [super init]; + self = [super init]; if (self != nil) { mTarget = target; @@ -155,6 +327,8 @@ static const KeyToCommand macMapDefault[] = - (void) dealloc { + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self]; [notificationQueue release]; [super dealloc]; } @@ -177,6 +351,7 @@ static const KeyToCommand macMapDefault[] = */ - (void) idleTimerFired: (NSTimer*) timer { +#pragma unused(timer) // Idle timer event. // Post a new idle notification, which gets executed when the run loop is idle. // Since we are coalescing on name and sender there will always be only one actual notification @@ -196,6 +371,7 @@ static const KeyToCommand macMapDefault[] = */ - (void) idleTriggered: (NSNotification*) notification { +#pragma unused(notification) reinterpret_cast(mTarget)->IdleTimerFired(); } @@ -203,10 +379,23 @@ static const KeyToCommand macMapDefault[] = //----------------- ScintillaCocoa ----------------------------------------------------------------- -ScintillaCocoa::ScintillaCocoa(NSView* view) +ScintillaCocoa::ScintillaCocoa(InnerView* view, MarginView* viewMargin) { - wMain= [view retain]; - timerTarget = [[[TimerTarget alloc] init: this] retain]; + vs.marginInside = false; + wMain = view; // Don't retain since we're owned by view, which would cause a cycle + wMargin = viewMargin; + timerTarget = [[TimerTarget alloc] init: this]; + lastMouseEvent = NULL; + notifyObj = NULL; + notifyProc = NULL; + capturedMouse = false; + enteredSetScrollingSize = false; + scrollSpeed = 1; + scrollTicks = 2000; + tickTimer = NULL; + idleTimer = NULL; + observer = NULL; + layerFindIndicator = NULL; Initialise(); } @@ -214,10 +403,8 @@ ScintillaCocoa::ScintillaCocoa(NSView* view) ScintillaCocoa::~ScintillaCocoa() { - SetTicking(false); + Finalise(); [timerTarget release]; - NSView* container = ContentView(); - [container release]; } //-------------------------------------------------------------------------------------------------- @@ -227,16 +414,7 @@ ScintillaCocoa::~ScintillaCocoa() */ void ScintillaCocoa::Initialise() { - static bool initedLexers = false; - if (!initedLexers) - { - initedLexers = true; - Scintilla_LinkLexers(); - } - notifyObj = NULL; - notifyProc = NULL; - - capturedMouse = false; + Scintilla_LinkLexers(); // Tell Scintilla not to buffer: Quartz buffers drawing for us. WndProc(SCI_SETBUFFEREDDRAW, 0, 0); @@ -257,12 +435,70 @@ void ScintillaCocoa::Initialise() */ void ScintillaCocoa::Finalise() { + ObserverRemove(); SetTicking(false); ScintillaBase::Finalise(); } //-------------------------------------------------------------------------------------------------- +void ScintillaCocoa::UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { + ScintillaCocoa* sci = reinterpret_cast(info); + sci->IdleWork(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Add an observer to the run loop to perform styling as high-priority idle task. + */ + +void ScintillaCocoa::ObserverAdd() { + if (!observer) { + CFRunLoopObserverContext context; + context.version = 0; + context.info = this; + context.retain = NULL; + context.release = NULL; + context.copyDescription = NULL; + + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + observer = CFRunLoopObserverCreate(NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, + true, 0, UpdateObserver, &context); + CFRunLoopAddObserver(mainRunLoop, observer, kCFRunLoopCommonModes); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Remove the run loop observer. + */ +void ScintillaCocoa::ObserverRemove() { + if (observer) { + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + CFRunLoopRemoveObserver(mainRunLoop, observer, kCFRunLoopCommonModes); + CFRelease(observer); + } + observer = NULL; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::IdleWork() { + Editor::IdleWork(); + ObserverRemove(); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::QueueIdleWork(WorkNeeded::workItems items, int upTo) { + Editor::QueueIdleWork(items, upTo); + ObserverAdd(); +} + +//-------------------------------------------------------------------------------------------------- + /** * Convert a core foundation string into an array of bytes in a particular encoding */ @@ -286,36 +522,6 @@ static char *EncodedBytes(CFStringRef cfsRef, CFStringEncoding encoding) { * Case folders. */ -class CaseFolderUTF8 : public CaseFolderTable { -public: - CaseFolderUTF8() { - 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(mixed[0])]; - return 1; - } else { - CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast(mixed), - lenMixed, kCFStringEncodingUTF8, false); - - NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch - locale:[NSLocale currentLocale]]; - - const char *cpMapped = [sMapped UTF8String]; - size_t lenMapped = strlen(cpMapped); - if (lenMapped < sizeFolded) { - memcpy(folded, cpMapped, lenMapped); - } else { - lenMapped = 0; - } - CFRelease(cfsVal); - return lenMapped; - } - } -}; - class CaseFolderDBCS : public CaseFolderTable { CFStringEncoding encoding; public: @@ -355,7 +561,7 @@ public: CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { if (pdoc->dbcsCodePage == SC_CP_UTF8) { - return new CaseFolderUTF8(); + return new CaseFolderUnicode(); } else { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); @@ -369,6 +575,8 @@ CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast(sCharacter), 1, encoding, false); + if (!cfsVal) + continue; NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch locale:[NSLocale currentLocale]]; @@ -398,6 +606,17 @@ CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { */ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) { + if ((s.size() == 0) || (caseMapping == cmSame)) + return s; + + if (IsUnicodeMode()) { + std::string retMapped(s.length() * maxExpansionCaseConversion, 0); + size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), + (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); + retMapped.resize(lenMapped); + return retMapped; + } + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, @@ -414,7 +633,7 @@ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) sMapped = [(NSString *)cfsVal lowercaseString]; break; default: - sMapped = [(NSString *)cfsVal copy]; + sMapped = (NSString *)cfsVal; } // Back to encoding @@ -427,13 +646,33 @@ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) //-------------------------------------------------------------------------------------------------- +/** + * Cancel all modes, both for base class and any find indicator. + */ +void ScintillaCocoa::CancelModes() { + ScintillaBase::CancelModes(); + HideFindIndicator(); +} + +//-------------------------------------------------------------------------------------------------- + /** * Helper function to get the outer container which represents the Scintilla editor on application side. */ ScintillaView* ScintillaCocoa::TopContainer() { NSView* container = static_cast(wMain.GetID()); - return static_cast([container superview]); + return static_cast([[[container superview] superview] superview]); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper function to get the scrolling view. + */ +NSScrollView* ScintillaCocoa::ScrollContainer() { + NSView* container = static_cast(wMain.GetID()); + return static_cast([[container superview] superview]); } //-------------------------------------------------------------------------------------------------- @@ -441,9 +680,21 @@ ScintillaView* ScintillaCocoa::TopContainer() /** * Helper function to get the inner container which represents the actual "canvas" we work with. */ -NSView* ScintillaCocoa::ContentView() +InnerView* ScintillaCocoa::ContentView() { - return static_cast(wMain.GetID()); + return static_cast(wMain.GetID()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Return the top left visible point relative to the origin point of the whole document. + */ +Scintilla::Point ScintillaCocoa::GetVisibleOriginInMain() +{ + NSScrollView *scrollView = ScrollContainer(); + NSRect contentRect = [[scrollView contentView] bounds]; + return Point(contentRect.origin.x, contentRect.origin.y); } //-------------------------------------------------------------------------------------------------- @@ -451,26 +702,29 @@ NSView* ScintillaCocoa::ContentView() /** * Instead of returning the size of the inner view we have to return the visible part of it * in order to make scrolling working properly. + * The returned value is in document coordinates. */ PRectangle ScintillaCocoa::GetClientRectangle() { - NSView* host = ContentView(); - NSSize size = [host frame].size; - return PRectangle(0, 0, size.width, size.height); + NSScrollView *scrollView = ScrollContainer(); + NSSize size = [[scrollView contentView] bounds].size; + Point origin = GetVisibleOriginInMain(); + return PRectangle(origin.x, origin.y, origin.x+size.width, origin.y + size.height); } //-------------------------------------------------------------------------------------------------- /** * Converts the given point from base coordinates to local coordinates and at the same time into - * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. + * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. + * Returned value is in view coordinates. */ Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) { NSView* container = ContentView(); NSPoint result = [container convertPoint: point fromView: nil]; - - return Point(result.x, result.y); + Scintilla::Point ptOrigin = GetVisibleOriginInMain(); + return Point(result.x - ptOrigin.x, result.y - ptOrigin.y); } //-------------------------------------------------------------------------------------------------- @@ -507,10 +761,10 @@ sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, s //-------------------------------------------------------------------------------------------------- -/** +/** * That's our fake window procedure. On Windows each window has a dedicated procedure to handle * commands (also used to synchronize UI and background threads), which is not the case in Cocoa. - * + * * Messages handled here are almost solely for special commands of the backend. Everything which * would be sytem messages on Windows (e.g. for key down, mouse move etc.) are handled by * directly calling appropriate handlers. @@ -526,20 +780,35 @@ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPar return reinterpret_cast(this); case SCI_GRABFOCUS: - [[ContentView() window] makeFirstResponder:ContentView()]; + [[ContentView() window] makeFirstResponder:ContentView()]; break; - + + case SCI_SETBUFFEREDDRAW: + // Buffered drawing not supported on Cocoa + bufferedDraw = false; break; - - case WM_UNICHAR: + + case SCI_FINDINDICATORSHOW: + ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), YES); + return 0; + + case SCI_FINDINDICATORFLASH: + ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), NO); + return 0; + + case SCI_FINDINDICATORHIDE: + HideFindIndicator(); + return 0; + + case WM_UNICHAR: // Special case not used normally. Characters passed in this way will be inserted // regardless of their value or modifier states. That means no command interpretation is // performed. if (IsUnicodeMode()) { - NSString* input = [[NSString stringWithCharacters: (const unichar*) &wParam length: 1] autorelease]; + NSString* input = [NSString stringWithCharacters: (const unichar*) &wParam length: 1]; const char* utf8 = [input UTF8String]; - AddCharUTF((char*) utf8, strlen(utf8), false); + AddCharUTF((char*) utf8, static_cast(strlen(utf8)), false); return 1; } return 0; @@ -577,12 +846,11 @@ void ScintillaCocoa::SetTicking(bool on) if (timer.ticking) { // Scintilla ticks = milliseconds - // Using userInfo as flag to distinct between tick and idle timer. - NSTimer* tickTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 - target: timerTarget - selector: @selector(timerFired:) - userInfo: nil - repeats: YES]; + tickTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 + target: timerTarget + selector: @selector(timerFired:) + userInfo: nil + repeats: YES]; timer.tickerID = reinterpret_cast(tickTimer); } else @@ -605,11 +873,11 @@ bool ScintillaCocoa::SetIdle(bool on) if (idler.state) { // Scintilla ticks = milliseconds - NSTimer* idleTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 - target: timerTarget - selector: @selector(idleTimerFired:) - userInfo: nil - repeats: YES]; + idleTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 + target: timerTarget + selector: @selector(idleTimerFired:) + userInfo: nil + repeats: YES]; idler.idlerID = reinterpret_cast(idleTimer); } else @@ -670,20 +938,20 @@ void ScintillaCocoa::Paste(bool forceRectangular) if (forceRectangular) selectedText.rectangular = forceRectangular; - if (!ok || !selectedText.s) + if (!ok || selectedText.Empty()) // No data or no flavor we support. return; pdoc->BeginUndoAction(); ClearSelection(false); - int length = selectedText.len - 1; // One less to avoid inserting the terminating 0 character. + int length = selectedText.Length(); if (selectedText.rectangular) { SelectionPosition selStart = sel.RangeMain().Start(); - PasteRectangular(selStart, selectedText.s, length); + PasteRectangular(selStart, selectedText.Data(), length); } else - if (pdoc->InsertString(sel.RangeMain().caret.Position(), selectedText.s, length)) + if (pdoc->InsertString(sel.RangeMain().caret.Position(), selectedText.Data(), length)) SetEmptySelection(sel.RangeMain().caret.Position() + length); pdoc->EndUndoAction(); @@ -695,7 +963,8 @@ void ScintillaCocoa::Paste(bool forceRectangular) //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::CTPaint(void* gc, NSRect rc) { - Surface *surfaceWindow = Surface::Allocate(); +#pragma unused(rc) + Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { surfaceWindow->Init(gc, wMain.GetID()); surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage); @@ -775,8 +1044,7 @@ void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) { [callTip setLevel:NSFloatingWindowLevel]; [callTip setHasShadow:YES]; NSRect ctContent = NSMakeRect(0,0, rc.Width(), rc.Height()); - CallTipView *caption = [CallTipView alloc]; - [caption initWithFrame: ctContent]; + CallTipView *caption = [[CallTipView alloc] initWithFrame: ctContent]; [caption setAutoresizingMask: NSViewWidthSizable | NSViewMaxYMargin]; [caption setSci: this]; [[callTip contentView] addSubview: caption]; @@ -793,15 +1061,15 @@ void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) [menu setOwner: this]; [menu setAutoenablesItems: NO]; - if (cmd == 0) + if (cmd == 0) { item = [NSMenuItem separatorItem]; - else - item = [[NSMenuItem alloc] init]; - + } else { + item = [[[NSMenuItem alloc] init] autorelease]; + [item setTitle: [NSString stringWithUTF8String: label]]; + } [item setTarget: menu]; [item setAction: @selector(handleCommand:)]; [item setTag: cmd]; - [item setTitle: [NSString stringWithUTF8String: label]]; [item setEnabled: enabled]; [menu addItem: item]; @@ -831,7 +1099,7 @@ NSPoint ScintillaCocoa::GetCaretPosition() // ------------------------------------------------------------------------------------------------- -#pragma segment Drag +#pragma mark Drag /** * Triggered by the tick timer on a regular basis to scroll the content during a drag operation. @@ -892,13 +1160,84 @@ void ScintillaCocoa::StartDrag() CopySelectionRange(&selectedText); SetPasteboardData(pasteboard, selectedText); + // calculate the bounds of the selection + PRectangle client = GetTextRectangle(); + int selStart = sel.RangeMain().Start().Position(); + int selEnd = sel.RangeMain().End().Position(); + int startLine = pdoc->LineFromPosition(selStart); + int endLine = pdoc->LineFromPosition(selEnd); + Point pt; + long startPos, endPos, ep; + Rect rcSel; + + if (startLine==endLine && WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE) { + // Komodo bug http://bugs.activestate.com/show_bug.cgi?id=87571 + // Scintilla bug https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040200&group_id=2439 + // If the width on a wrapped-line selection is negative, + // find a better bounding rectangle. + + Point ptStart, ptEnd; + startPos = WndProc(SCI_GETLINESELSTARTPOSITION, startLine, 0); + endPos = WndProc(SCI_GETLINESELENDPOSITION, startLine, 0); + // step back a position if we're counting the newline + ep = WndProc(SCI_GETLINEENDPOSITION, startLine, 0); + if (endPos > ep) endPos = ep; + ptStart = LocationFromPosition(static_cast(startPos)); + ptEnd = LocationFromPosition(static_cast(endPos)); + if (ptStart.y == ptEnd.y) { + // We're just selecting part of one visible line + rcSel.left = ptStart.x; + rcSel.right = ptEnd.x < client.right ? ptEnd.x : client.right; + } else { + // Find the bounding box. + startPos = WndProc(SCI_POSITIONFROMLINE, startLine, 0); + rcSel.left = LocationFromPosition(static_cast(startPos)).x; + rcSel.right = client.right; + } + rcSel.top = ptStart.y; + rcSel.bottom = ptEnd.y + vs.lineHeight; + if (rcSel.bottom > client.bottom) { + rcSel.bottom = client.bottom; + } + } else { + rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1; + for (int l = startLine; l <= endLine; l++) { + startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0); + endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0); + if (endPos == startPos) continue; + // step back a position if we're counting the newline + ep = WndProc(SCI_GETLINEENDPOSITION, l, 0); + if (endPos > ep) endPos = ep; + pt = LocationFromPosition(static_cast(startPos)); // top left of line selection + if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x; + if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y; + pt = LocationFromPosition(static_cast(endPos)); // top right of line selection + pt.y += vs.lineHeight; // get to the bottom of the line + if (pt.x > rcSel.right || rcSel.right < 0) { + if (pt.x > client.right) + rcSel.right = client.right; + else + rcSel.right = pt.x; + } + if (pt.y > rcSel.bottom || rcSel.bottom < 0) { + if (pt.y > client.bottom) + rcSel.bottom = client.bottom; + else + rcSel.bottom = pt.y; + } + } + } + // must convert to global coordinates for drag regions, but also save the + // image rectangle for further calculations and copy operations + PRectangle localRectangle = PRectangle(rcSel.left, rcSel.top, rcSel.right, rcSel.bottom); + // Prepare drag image. - PRectangle localRectangle = RectangleFromRange(sel.RangeMain().Start().Position(), sel.RangeMain().End().Position()); NSRect selectionRectangle = PRectangleToNSRect(localRectangle); NSView* content = ContentView(); + +#if 1 -#if 0 // TODO: fix initialization of the drag image with CGImageRef. // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. SurfaceImpl *sw = new SurfaceImpl(); SurfaceImpl *pixmap = NULL; @@ -910,19 +1249,22 @@ void ScintillaCocoa::StartDrag() pixmap = new SurfaceImpl(); if (pixmap) { - PRectangle client = GetClientRectangle(); PRectangle imageRect = NSRectToPRectangle(selectionRectangle); paintState = painting; - //sw->InitPixMap(client.Width(), client.Height(), NULL, NULL); - sw->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL); + sw->InitPixMap(client.Width(), client.Height(), NULL, NULL); paintingAllText = true; - Paint(sw, imageRect); + // Have to create a new context and make current as text drawing goes + // to the current context, not a passed context. + CGContextRef gcsw = sw->GetContext(); + NSGraphicsContext *nsgc = [NSGraphicsContext graphicsContextWithGraphicsPort: gcsw + flipped: YES]; + [NSGraphicsContext setCurrentContext:nsgc]; + Paint(sw, client); paintState = notPainting; pixmap->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL); CGContextRef gc = pixmap->GetContext(); - // To make Paint() work on a bitmap, we have to flip our coordinates and translate the origin CGContextTranslateCTM(gc, 0, imageRect.Height()); CGContextScaleCTM(gc, 1.0, -1.0); @@ -940,7 +1282,9 @@ void ScintillaCocoa::StartDrag() NSBitmapImageRep* bitmap = NULL; if (pixmap) { - bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: pixmap->GetImage()] autorelease]; + CGImageRef imagePixmap = pixmap->GetImage(); + bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: imagePixmap] autorelease]; + CGImageRelease(imagePixmap); pixmap->Release(); delete pixmap; } @@ -1023,6 +1367,7 @@ NSDragOperation ScintillaCocoa::DraggingUpdated(id info) */ void ScintillaCocoa::DraggingExited(id info) { +#pragma unused(info) SetDragPosition(SelectionPosition(invalidPosition)); inDragDrop = ddNone; } @@ -1047,12 +1392,12 @@ bool ScintillaCocoa::PerformDragOperation(id info) SelectionText text; GetPasteboardData(pasteboard, &text); - if (text.len > 0) + if (text.Length() > 0) { NSDragOperation operation = [info draggingSourceOperationMask]; bool moving = (operation & NSDragOperationMove) != 0; - DropAt(posDrag, text.s, moving, text.rectangular); + DropAt(posDrag, text.Data(), text.Length(), moving, text.rectangular); }; } @@ -1063,25 +1408,30 @@ bool ScintillaCocoa::PerformDragOperation(id info) void ScintillaCocoa::SetPasteboardData(NSPasteboard* board, const SelectionText &selectedText) { - if (selectedText.len == 0) + if (selectedText.Length() == 0) return; - NSString *string; - string = [NSString stringWithUTF8String: selectedText.s]; + CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, + selectedText.characterSet); + CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast(selectedText.Data()), + selectedText.Length(), encoding, false); - [board declareTypes:[NSArray arrayWithObjects: - NSStringPboardType, - selectedText.rectangular ? ScintillaRecPboardType : nil, - nil] owner:nil]; + NSArray *pbTypes = selectedText.rectangular ? + [NSArray arrayWithObjects: NSStringPboardType, ScintillaRecPboardType, nil] : + [NSArray arrayWithObjects: NSStringPboardType, nil]; + [board declareTypes:pbTypes owner:nil]; if (selectedText.rectangular) { // This is specific to scintilla, allows us to drag rectangular selections around the document. - [board setString: string forType: ScintillaRecPboardType]; + [board setString: (NSString *)cfsVal forType: ScintillaRecPboardType]; } - [board setString: string forType: NSStringPboardType]; - + [board setString: (NSString *)cfsVal forType: NSStringPboardType]; + + if (cfsVal) + CFRelease(cfsVal); } //-------------------------------------------------------------------------------------------------- @@ -1101,9 +1451,25 @@ bool ScintillaCocoa::GetPasteboardData(NSPasteboard* board, SelectionText* selec { if (selectedText != nil) { - char* text = (char*) [data UTF8String]; + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + CFRange rangeAll = {0, static_cast([data length])}; + CFIndex usedLen = 0; + CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', + false, NULL, 0, &usedLen); + + std::vector buffer(usedLen); + + CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', + false, buffer.data(),usedLen, NULL); + bool rectangular = bestType == ScintillaRecPboardType; - selectedText->Copy(text, strlen(text) + 1, SC_CP_UTF8, SC_CHARSET_DEFAULT , rectangular, false); + + int len = static_cast(usedLen); + std::string dest = Document::TransformLineEnds((char *)buffer.data(), len, pdoc->eolMode); + + selectedText->Copy(dest, pdoc->dbcsCodePage, + vs.styles[STYLE_DEFAULT].characterSet , rectangular, false); } return true; } @@ -1116,16 +1482,6 @@ bool ScintillaCocoa::GetPasteboardData(NSPasteboard* board, SelectionText* selec void ScintillaCocoa::SetMouseCapture(bool on) { capturedMouse = on; - /* - if (mouseDownCaptures) - { - if (capturedMouse) - WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); - else - // Reset to normal. Actual image will be set on mouse move. - WndProc(SCI_SETCURSOR, (unsigned int) SC_CURSORNORMAL, 0); - } - */ } //-------------------------------------------------------------------------------------------------- @@ -1140,63 +1496,116 @@ bool ScintillaCocoa::HaveMouseCapture() /** * Synchronously paint a rectangle of the window. */ -void ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) +bool ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) { paintState = painting; rcPaint = rc; PRectangle rcText = GetTextRectangle(); paintingAllText = rcPaint.Contains(rcText); - Surface *sw = Surface::Allocate(); + bool succeeded = true; + Surface *sw = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (sw) { + CGContextSetAllowsAntialiasing((CGContextRef)gc, + vs.extraFontFlag != SC_EFF_QUALITY_NON_ANTIALIASED); + CGContextSetAllowsFontSmoothing((CGContextRef)gc, + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + if (CGContextSetAllowsFontSubpixelPositioning != NULL) + CGContextSetAllowsFontSubpixelPositioning((CGContextRef)gc, + vs.extraFontFlag == SC_EFF_QUALITY_DEFAULT || + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); +#endif sw->Init(gc, wMain.GetID()); Paint(sw, rc); - if (paintState == paintAbandoned) - { - // Do a full paint. - rcPaint = GetClientRectangle(); - paintState = painting; - paintingAllText = true; - Paint(sw, rcPaint); - } + succeeded = paintState != paintAbandoned; sw->Release(); delete sw; } paintState = notPainting; + if (!succeeded) + { + NSView *marginView = static_cast(wMargin.GetID()); + [marginView setNeedsDisplay:YES]; + } + return succeeded; } //-------------------------------------------------------------------------------------------------- /** - * Modfies the vertical scroll position to make the current top line show up as such. + * Paint the margin into the MarginView space. */ -void ScintillaCocoa::SetVerticalScrollPos() +void ScintillaCocoa::PaintMargin(NSRect aRect) { - ScintillaView* topContainer = TopContainer(); - - // Convert absolute coordinate into the range [0..1]. Keep in mind that the visible area - // does *not* belong to the scroll range. - float relativePosition = (float) topLine / MaxScrollPos(); - [topContainer setVerticalScrollPosition: relativePosition]; + CGContextRef gc = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + + PRectangle rc = NSRectToPRectangle(aRect); + rcPaint = rc; + Surface *sw = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); + if (sw) + { + sw->Init(gc, wMargin.GetID()); + PaintSelMargin(sw, rc); + sw->Release(); + delete sw; + } } //-------------------------------------------------------------------------------------------------- +/** + * ScrollText is empty because scrolling is handled by the NSScrollView. + */ +void ScintillaCocoa::ScrollText(int linesToMove) +{ +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Modifies the vertical scroll position to make the current top line show up as such. + */ +void ScintillaCocoa::SetVerticalScrollPos() +{ + NSScrollView *scrollView = ScrollContainer(); + if (scrollView) { + NSClipView *clipView = [scrollView contentView]; + NSRect contentRect = [clipView bounds]; + [clipView scrollToPoint: NSMakePoint(contentRect.origin.x, topLine * vs.lineHeight)]; + [scrollView reflectScrolledClipView:clipView]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Modifies the horizontal scroll position to match xOffset. + */ void ScintillaCocoa::SetHorizontalScrollPos() { - ScintillaView* topContainer = TopContainer(); PRectangle textRect = GetTextRectangle(); - - // Convert absolute coordinate into the range [0..1]. Keep in mind that the visible area - // does *not* belong to the scroll range. - float relativePosition = (float) xOffset / (scrollWidth - textRect.Width()); - [topContainer setHorizontalScrollPosition: relativePosition]; + + int maxXOffset = scrollWidth - textRect.Width(); + if (maxXOffset < 0) + maxXOffset = 0; + if (xOffset > maxXOffset) + xOffset = maxXOffset; + NSScrollView *scrollView = ScrollContainer(); + if (scrollView) { + NSClipView * clipView = [scrollView contentView]; + NSRect contentRect = [clipView bounds]; + [clipView scrollToPoint: NSMakePoint(xOffset, contentRect.origin.y)]; + [scrollView reflectScrolledClipView:clipView]; + } + MoveFindIndicatorWithBounce(NO); } //-------------------------------------------------------------------------------------------------- /** * Used to adjust both scrollers to reflect the current scroll range and position in the editor. + * Arguments no longer used as NSScrollView handles details of scroll bar sizes. * * @param nMax Number of lines in the editor. * @param nPage Number of lines per scroll page. @@ -1204,102 +1613,66 @@ void ScintillaCocoa::SetHorizontalScrollPos() */ bool ScintillaCocoa::ModifyScrollBars(int nMax, int nPage) { - // Input values are given in lines, not pixels, so we have to convert. - int lineHeight = WndProc(SCI_TEXTHEIGHT, 0, 0); - PRectangle bounds = GetTextRectangle(); - ScintillaView* topContainer = TopContainer(); +#pragma unused(nMax, nPage) + return SetScrollingSize(); +} - // Set page size to the same value as the scroll range to hide the scrollbar. - int scrollRange = lineHeight * (nMax + 1); // +1 because the caller subtracted one. - int pageSize; - if (verticalScrollBarVisible) - pageSize = bounds.Height(); - else - pageSize = scrollRange; - bool verticalChange = [topContainer setVerticalScrollRange: scrollRange page: pageSize]; - - scrollRange = scrollWidth; - if (horizontalScrollBarVisible) - pageSize = bounds.Width(); - else - pageSize = scrollRange; - bool horizontalChange = [topContainer setHorizontalScrollRange: scrollRange page: pageSize]; - - return verticalChange || horizontalChange; +bool ScintillaCocoa::SetScrollingSize(void) { + bool changes = false; + InnerView *inner = ContentView(); + if (!enteredSetScrollingSize) { + enteredSetScrollingSize = true; + NSScrollView *scrollView = ScrollContainer(); + NSClipView *clipView = [ScrollContainer() contentView]; + NSRect clipRect = [clipView bounds]; + int docHeight = (cs.LinesDisplayed()+1) * vs.lineHeight; + if (!endAtLastLine) + docHeight += (int([scrollView bounds].size.height / vs.lineHeight)-3) * vs.lineHeight; + // Allow extra space so that last scroll position places whole line at top + int clipExtra = int(clipRect.size.height) % vs.lineHeight; + docHeight += clipExtra; + // Ensure all of clipRect covered by Scintilla drawing + if (docHeight < clipRect.size.height) + docHeight = clipRect.size.height; + int docWidth = scrollWidth; + bool showHorizontalScroll = horizontalScrollBarVisible && + (wrapState == eWrapNone); + if (!showHorizontalScroll) + docWidth = clipRect.size.width; + NSRect contentRect = {0, 0, docWidth, docHeight}; + NSRect contentRectNow = [inner frame]; + changes = (contentRect.size.width != contentRectNow.size.width) || + (contentRect.size.height != contentRectNow.size.height); + if (changes) { + [inner setFrame: contentRect]; + } + [scrollView setHasVerticalScroller: verticalScrollBarVisible]; + [scrollView setHasHorizontalScroller: showHorizontalScroll]; + SetVerticalScrollPos(); + enteredSetScrollingSize = false; + } + [inner.owner setMarginWidth: vs.fixedColumnWidth]; + return changes; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::Resize() { + SetScrollingSize(); ChangeSize(); } //-------------------------------------------------------------------------------------------------- /** - * Called by the frontend control when the user manipulates one of the scrollers. - * - * @param position The relative position of the scroller in the range of [0..1]. - * @param part Specifies which part was clicked on by the user, so we can handle thumb tracking - * as well as page and line scrolling. - * @param horizontal True if the horizontal scroller was hit, otherwise false. + * Update fields to match scroll position after receiving a notification that the user has scrolled. */ -void ScintillaCocoa::DoScroll(float position, NSScrollerPart part, bool horizontal) -{ - // If the given scroller part is not the knob (or knob slot) then the given position is not yet - // current and we have to update it. - if (horizontal) - { - // Horizontal offset is given in pixels. - PRectangle textRect = GetTextRectangle(); - int offset = (int) (position * (scrollWidth - textRect.Width())); - int smallChange = (int) (textRect.Width() / 30); - if (smallChange < 5) - smallChange = 5; - switch (part) - { - case NSScrollerDecrementLine: - offset -= smallChange; - break; - case NSScrollerDecrementPage: - offset -= textRect.Width(); - break; - case NSScrollerIncrementLine: - offset += smallChange; - break; - case NSScrollerIncrementPage: - offset += textRect.Width(); - break; - }; - HorizontalScrollTo(offset); - } - else - { - // VerticalScrolling is by line. If the user is scrolling using the knob we can directly - // set the new scroll position. Otherwise we have to compute it first. - if (part == NSScrollerKnob) - ScrollTo(position * MaxScrollPos(), false); - else - { - switch (part) - { - case NSScrollerDecrementLine: - ScrollTo(topLine - 1, true); - break; - case NSScrollerDecrementPage: - ScrollTo(topLine - LinesOnScreen(), true); - break; - case NSScrollerIncrementLine: - ScrollTo(topLine + 1, true); - break; - case NSScrollerIncrementPage: - ScrollTo(topLine + LinesOnScreen(), true); - break; - }; - - } - } +void ScintillaCocoa::UpdateForScroll() { + Point ptOrigin = GetVisibleOriginInMain(); + xOffset = ptOrigin.x; + int newTop = Platform::Minimum(ptOrigin.y / vs.lineHeight, MaxScrollPos()); + SetTopLine(newTop); } //-------------------------------------------------------------------------------------------------- @@ -1324,7 +1697,8 @@ void ScintillaCocoa::RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc cal void ScintillaCocoa::NotifyChange() { if (notifyProc != NULL) - notifyProc(notifyObj, WM_COMMAND, (uintptr_t) (SCEN_CHANGE << 16), (uintptr_t) this); + notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), + (uintptr_t) this); } //-------------------------------------------------------------------------------------------------- @@ -1332,7 +1706,8 @@ void ScintillaCocoa::NotifyChange() void ScintillaCocoa::NotifyFocus(bool focus) { if (notifyProc != NULL) - notifyProc(notifyObj, WM_COMMAND, (uintptr_t) ((focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS) << 16), (uintptr_t) this); + notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(GetCtrlID(), (focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS)), + (uintptr_t) this); } //-------------------------------------------------------------------------------------------------- @@ -1389,6 +1764,7 @@ bool ScintillaCocoa::CanRedo() void ScintillaCocoa::TimerFired(NSTimer* timer) { +#pragma unused(timer) Tick(); DragScroll(); } @@ -1410,9 +1786,9 @@ void ScintillaCocoa::IdleTimerFired() * @param rect The area to paint, given in the sender's coordinate system. * @param gc The context we can use to paint. */ -void ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) +bool ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) { - SyncPaint(gc, NSRectToPRectangle(rect)); + return SyncPaint(gc, NSRectToPRectangle(rect)); } //-------------------------------------------------------------------------------------------------- @@ -1483,7 +1859,7 @@ bool ScintillaCocoa::KeyboardInput(NSEvent* event) bool handled = false; // Handle each entry individually. Usually we only have one entry anway. - for (int i = 0; i < input.length; i++) + for (size_t i = 0; i < input.length; i++) { const UniChar originalKey = [input characterAtIndex: i]; UniChar key = KeyTranslate(originalKey); @@ -1512,9 +1888,50 @@ bool ScintillaCocoa::KeyboardInput(NSEvent* event) */ int ScintillaCocoa::InsertText(NSString* input) { - const char* utf8 = [input UTF8String]; - AddCharUTF((char*) utf8, strlen(utf8), false); - return true; + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + CFRange rangeAll = {0, static_cast([input length])}; + CFIndex usedLen = 0; + CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', + false, NULL, 0, &usedLen); + + std::vector buffer(usedLen); + + CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', + false, buffer.data(),usedLen, NULL); + + AddCharUTF((char*) buffer.data(), static_cast(usedLen), false); + return static_cast(usedLen); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to ensure that only one selection is active for input composition as composition + * does not support multi-typing. + * Also drop virtual space as that is not supported by composition. + */ +void ScintillaCocoa::SelectOnlyMainSelection() +{ + SelectionRange mainSel = sel.RangeMain(); + mainSel.ClearVirtualSpace(); + sel.SetSelection(mainSel); + Redraw(); +} + +//-------------------------------------------------------------------------------------------------- +/** + * When switching documents discard any incomplete character composition state as otherwise tries to + * act on the new document. + */ +void ScintillaCocoa::SetDocPointer(Document *document) +{ + // Drop input composition. + NSTextInputContext *inctxt = [NSTextInputContext currentInputContext]; + [inctxt discardMarkedText]; + InnerView *inner = ContentView(); + [inner unmarkText]; + Editor::SetDocPointer(document); } //-------------------------------------------------------------------------------------------------- @@ -1536,7 +1953,7 @@ void ScintillaCocoa::MouseEntered(NSEvent* event) //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseExited(NSEvent* event) +void ScintillaCocoa::MouseExited(NSEvent* /* event */) { // Nothing to do here. } @@ -1559,7 +1976,7 @@ void ScintillaCocoa::MouseDown(NSEvent* event) void ScintillaCocoa::MouseMove(NSEvent* event) { lastMouseEvent = event; - + ButtonMove(ConvertPoint([event locationInWindow])); } @@ -1578,11 +1995,8 @@ void ScintillaCocoa::MouseUp(NSEvent* event) void ScintillaCocoa::MouseWheel(NSEvent* event) { bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; - int dX = 0; int dY = 0; - dX = 10 * [event deltaX]; // Arbitrary scale factor. - // In order to make scrolling with larger offset smoother we scroll less lines the larger the // delta value is. if ([event deltaY] < 0) @@ -1601,8 +2015,6 @@ void ScintillaCocoa::MouseWheel(NSEvent* event) } else { - HorizontalScrollTo(xOffset - dX); - ScrollTo(topLine - dY, true); } } @@ -1640,7 +2052,7 @@ void ScintillaCocoa::Redo() /** * Creates and returns a popup menu, which is then displayed by the Cocoa framework. */ -NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* event) +NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* /* event */) { // Call ScintillaBase to create the context menu. ContextMenu(Point(0, 0)); @@ -1656,7 +2068,7 @@ NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* event) */ void ScintillaCocoa::HandleCommand(NSInteger command) { - Command(command); + Command(static_cast(command)); } //-------------------------------------------------------------------------------------------------- @@ -1676,3 +2088,81 @@ void ScintillaCocoa::ActiveStateChanged(bool isActive) //-------------------------------------------------------------------------------------------------- +void ScintillaCocoa::ShowFindIndicatorForRange(NSRange charRange, BOOL retaining) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + NSView *content = ContentView(); + if (!layerFindIndicator) + { + layerFindIndicator = [[FindHighlightLayer alloc] init]; + [content setWantsLayer: YES]; + layerFindIndicator.geometryFlipped = content.layer.geometryFlipped; + [[content layer] addSublayer:layerFindIndicator]; + } + [layerFindIndicator removeAnimationForKey:@"animateFound"]; + + if (charRange.length) + { + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + std::vector buffer(charRange.length); + pdoc->GetCharRange(&buffer[0], charRange.location, charRange.length); + + CFStringRef cfsFind = CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast(&buffer[0]), + charRange.length, encoding, false); + layerFindIndicator.sFind = (NSString *)cfsFind; + if (cfsFind) + CFRelease(cfsFind); + layerFindIndicator.retaining = retaining; + layerFindIndicator.positionFind = charRange.location; + int style = WndProc(SCI_GETSTYLEAT, charRange.location, 0); + std::vector bufferFontName(WndProc(SCI_STYLEGETFONT, style, 0) + 1); + WndProc(SCI_STYLEGETFONT, style, (sptr_t)&bufferFontName[0]); + layerFindIndicator.sFont = [NSString stringWithUTF8String: &bufferFontName[0]]; + + layerFindIndicator.fontSize = WndProc(SCI_STYLEGETSIZEFRACTIONAL, style, 0) / + (float)SC_FONT_SIZE_MULTIPLIER; + layerFindIndicator.widthText = WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location + charRange.length) - + WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location); + layerFindIndicator.heightLine = WndProc(SCI_TEXTHEIGHT, 0, 0); + MoveFindIndicatorWithBounce(YES); + } + else + { + [layerFindIndicator hideMatch]; + } +#endif +} + +void ScintillaCocoa::MoveFindIndicatorWithBounce(BOOL bounce) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + if (layerFindIndicator) + { + CGPoint ptText = CGPointMake( + WndProc(SCI_POINTXFROMPOSITION, 0, layerFindIndicator.positionFind), + WndProc(SCI_POINTYFROMPOSITION, 0, layerFindIndicator.positionFind)); + ptText.x = ptText.x - vs.fixedColumnWidth + xOffset; + ptText.y += topLine * vs.lineHeight; + if (!layerFindIndicator.geometryFlipped) + { + NSView *content = ContentView(); + ptText.y = content.bounds.size.height - ptText.y; + } + [layerFindIndicator animateMatch:ptText bounce:bounce]; + } +#endif +} + +void ScintillaCocoa::HideFindIndicator() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + if (layerFindIndicator) + { + [layerFindIndicator hideMatch]; + } +#endif +} + + diff --git a/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj index 0998d297..a519d2ed 100644 --- a/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj +++ b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj @@ -3,10 +3,18 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 1100F1EB178E393200105727 /* CaseConvert.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1100F1E6178E393200105727 /* CaseConvert.cxx */; }; + 1100F1EC178E393200105727 /* CaseConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = 1100F1E7178E393200105727 /* CaseConvert.h */; }; + 1100F1ED178E393200105727 /* CaseFolder.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1100F1E8178E393200105727 /* CaseFolder.cxx */; }; + 1100F1EE178E393200105727 /* CaseFolder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1100F1E9178E393200105727 /* CaseFolder.h */; }; + 1100F1EF178E393200105727 /* UnicodeFromUTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = 1100F1EA178E393200105727 /* UnicodeFromUTF8.h */; }; + 1102C31C169FB49300DC16AB /* LexLaTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */; }; + 11126B8214CD3A6200803C49 /* LexAVS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11126B8114CD3A6200803C49 /* LexAVS.cxx */; }; + 1114D6CB1602A951001DC345 /* LexPO.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1114D6CA1602A951001DC345 /* LexPO.cxx */; }; 114B6F0D11FA7526004FB6AB /* LexAbaqus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */; }; 114B6F0E11FA7526004FB6AB /* LexAda.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EBF11FA7526004FB6AB /* LexAda.cxx */; }; 114B6F0F11FA7526004FB6AB /* LexAPDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC011FA7526004FB6AB /* LexAPDL.cxx */; }; @@ -142,7 +150,6 @@ 114B6FD111FA7623004FB6AB /* Selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB611FA7623004FB6AB /* Selection.h */; }; 114B6FD211FA7623004FB6AB /* SplitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB711FA7623004FB6AB /* SplitVector.h */; }; 114B6FD311FA7623004FB6AB /* Style.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB811FA7623004FB6AB /* Style.h */; }; - 114B6FD411FA7623004FB6AB /* SVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB911FA7623004FB6AB /* SVector.h */; }; 114B6FD511FA7623004FB6AB /* UniConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBA11FA7623004FB6AB /* UniConversion.h */; }; 114B6FD611FA7623004FB6AB /* ViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBB11FA7623004FB6AB /* ViewStyle.h */; }; 114B6FD711FA7623004FB6AB /* XPM.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBC11FA7623004FB6AB /* XPM.h */; }; @@ -157,8 +164,18 @@ 114B6FEB11FA7645004FB6AB /* PropSetSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE011FA7645004FB6AB /* PropSetSimple.h */; }; 114B6FEC11FA7645004FB6AB /* StyleContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE111FA7645004FB6AB /* StyleContext.h */; }; 114B6FED11FA7645004FB6AB /* WordList.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE211FA7645004FB6AB /* WordList.h */; }; + 1152A77315313E58000D4E1A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1152A77215313E58000D4E1A /* QuartzCore.framework */; }; + 11594BE9155B91DF0099E1FA /* LexOScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11594BE7155B91DF0099E1FA /* LexOScript.cxx */; }; + 11594BEA155B91DF0099E1FA /* LexVisualProlog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */; }; + 117ACE9114A29A1E002876F9 /* LexTCMD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */; }; + 119FF1BF13C9D1820007CE42 /* QuartzTextStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */; }; + 11A0A8A1148602DF0018D143 /* LexCoffeeScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */; }; 11BB124D12FF9C1300F6BCF7 /* LexModula.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */; }; + 11BEB6A214EF189600BDE92A /* LexECL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11BEB6A114EF189600BDE92A /* LexECL.cxx */; }; 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */; }; + 11FBA39D17817DA00048C071 /* CharacterCategory.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11FBA39B17817DA00048C071 /* CharacterCategory.cxx */; }; + 11FBA39E17817DA00048C071 /* CharacterCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 11FBA39C17817DA00048C071 /* CharacterCategory.h */; }; + 11FDAEB7174E1A9800FA161B /* LexSTTXT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11FDAEB6174E1A9700FA161B /* LexSTTXT.cxx */; }; 2744E5A40FC168A100E85C33 /* InfoBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59D0FC168A100E85C33 /* InfoBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2744E5AA0FC168A100E85C33 /* ScintillaView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A30FC168A100E85C33 /* ScintillaView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2744E5AC0FC168B200E85C33 /* InfoBarCommunicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -173,7 +190,6 @@ 2791F3E00FC1A390009DBCF9 /* ScintillaCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3E30FC1A3AE009DBCF9 /* QuartzTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3E40FC1A3AE009DBCF9 /* QuartzTextStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2791F3E80FC1A3AE009DBCF9 /* ScintillaWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27FEF4540FC1B413005E115A /* info_bar_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4510FC1B413005E115A /* info_bar_bg.png */; }; 27FEF4550FC1B413005E115A /* mac_cursor_busy.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */; }; 27FEF4560FC1B413005E115A /* mac_cursor_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */; }; @@ -186,6 +202,14 @@ 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 1100F1E6178E393200105727 /* CaseConvert.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CaseConvert.cxx; path = ../../src/CaseConvert.cxx; sourceTree = ""; }; + 1100F1E7178E393200105727 /* CaseConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CaseConvert.h; path = ../../src/CaseConvert.h; sourceTree = ""; }; + 1100F1E8178E393200105727 /* CaseFolder.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CaseFolder.cxx; path = ../../src/CaseFolder.cxx; sourceTree = ""; }; + 1100F1E9178E393200105727 /* CaseFolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CaseFolder.h; path = ../../src/CaseFolder.h; sourceTree = ""; }; + 1100F1EA178E393200105727 /* UnicodeFromUTF8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnicodeFromUTF8.h; path = ../../src/UnicodeFromUTF8.h; sourceTree = ""; }; + 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLaTeX.cxx; path = ../../lexers/LexLaTeX.cxx; sourceTree = ""; }; + 11126B8114CD3A6200803C49 /* LexAVS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVS.cxx; path = ../../lexers/LexAVS.cxx; sourceTree = ""; }; + 1114D6CA1602A951001DC345 /* LexPO.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPO.cxx; path = ../../lexers/LexPO.cxx; sourceTree = ""; }; 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAbaqus.cxx; path = ../../lexers/LexAbaqus.cxx; sourceTree = SOURCE_ROOT; }; 114B6EBF11FA7526004FB6AB /* LexAda.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAda.cxx; path = ../../lexers/LexAda.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC011FA7526004FB6AB /* LexAPDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAPDL.cxx; path = ../../lexers/LexAPDL.cxx; sourceTree = SOURCE_ROOT; }; @@ -321,7 +345,6 @@ 114B6FB611FA7623004FB6AB /* Selection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Selection.h; path = ../../src/Selection.h; sourceTree = SOURCE_ROOT; }; 114B6FB711FA7623004FB6AB /* SplitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SplitVector.h; path = ../../src/SplitVector.h; sourceTree = SOURCE_ROOT; }; 114B6FB811FA7623004FB6AB /* Style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Style.h; path = ../../src/Style.h; sourceTree = SOURCE_ROOT; }; - 114B6FB911FA7623004FB6AB /* SVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SVector.h; path = ../../src/SVector.h; sourceTree = SOURCE_ROOT; }; 114B6FBA11FA7623004FB6AB /* UniConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UniConversion.h; path = ../../src/UniConversion.h; sourceTree = SOURCE_ROOT; }; 114B6FBB11FA7623004FB6AB /* ViewStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ViewStyle.h; path = ../../src/ViewStyle.h; sourceTree = SOURCE_ROOT; }; 114B6FBC11FA7623004FB6AB /* XPM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPM.h; path = ../../src/XPM.h; sourceTree = SOURCE_ROOT; }; @@ -336,12 +359,21 @@ 114B6FE011FA7645004FB6AB /* PropSetSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PropSetSimple.h; path = ../../lexlib/PropSetSimple.h; sourceTree = SOURCE_ROOT; }; 114B6FE111FA7645004FB6AB /* StyleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleContext.h; path = ../../lexlib/StyleContext.h; sourceTree = SOURCE_ROOT; }; 114B6FE211FA7645004FB6AB /* WordList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WordList.h; path = ../../lexlib/WordList.h; sourceTree = SOURCE_ROOT; }; + 1152A77215313E58000D4E1A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = ../../../../../../../../System/Library/Frameworks/QuartzCore.framework; sourceTree = ""; }; + 11594BE7155B91DF0099E1FA /* LexOScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOScript.cxx; path = ../../lexers/LexOScript.cxx; sourceTree = ""; }; + 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVisualProlog.cxx; path = ../../lexers/LexVisualProlog.cxx; sourceTree = ""; }; + 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCMD.cxx; path = ../../lexers/LexTCMD.cxx; sourceTree = ""; }; + 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextStyle.h; path = ../QuartzTextStyle.h; sourceTree = ""; }; + 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCoffeeScript.cxx; path = ../../lexers/LexCoffeeScript.cxx; sourceTree = ""; }; 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexModula.cxx; path = ../../lexers/LexModula.cxx; sourceTree = SOURCE_ROOT; }; + 11BEB6A114EF189600BDE92A /* LexECL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexECL.cxx; path = ../../lexers/LexECL.cxx; sourceTree = ""; }; 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexA68k.cxx; path = ../../lexers/LexA68k.cxx; sourceTree = SOURCE_ROOT; }; + 11FBA39B17817DA00048C071 /* CharacterCategory.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterCategory.cxx; path = ../../lexlib/CharacterCategory.cxx; sourceTree = ""; }; + 11FBA39C17817DA00048C071 /* CharacterCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterCategory.h; path = ../../lexlib/CharacterCategory.h; sourceTree = ""; }; + 11FDAEB6174E1A9700FA161B /* LexSTTXT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSTTXT.cxx; path = ../../lexers/LexSTTXT.cxx; sourceTree = ""; }; 2744E4850FC1678600E85C33 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = ../../include/Platform.h; sourceTree = SOURCE_ROOT; }; 2744E4870FC1678600E85C33 /* SciLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SciLexer.h; path = ../../include/SciLexer.h; sourceTree = SOURCE_ROOT; }; 2744E4880FC1678600E85C33 /* Scintilla.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scintilla.h; path = ../../include/Scintilla.h; sourceTree = SOURCE_ROOT; }; - 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaWidget.h; path = ../../include/ScintillaWidget.h; sourceTree = SOURCE_ROOT; }; 2744E59D0FC168A100E85C33 /* InfoBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InfoBar.h; path = ../InfoBar.h; sourceTree = SOURCE_ROOT; }; 2744E59E0FC168A100E85C33 /* PlatCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatCocoa.h; path = ../PlatCocoa.h; sourceTree = SOURCE_ROOT; }; 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextLayout.h; path = ../QuartzTextLayout.h; sourceTree = SOURCE_ROOT; }; @@ -368,6 +400,7 @@ buildActionMask = 2147483647; files = ( 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, + 1152A77315313E58000D4E1A /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -435,6 +468,7 @@ 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( + 1152A77215313E58000D4E1A /* QuartzCore.framework */, 0867D6A5FE840307C02AAC07 /* AppKit.framework */, D2F7E79907B2D74100F64583 /* CoreData.framework */, 0867D69BFE84028FC02AAC07 /* Foundation.framework */, @@ -454,7 +488,7 @@ 2744E47D0FC1674E00E85C33 /* Lexers */ = { isa = PBXGroup; children = ( - 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */, + 11126B8114CD3A6200803C49 /* LexAVS.cxx */, 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */, 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */, 114B6EBF11FA7526004FB6AB /* LexAda.cxx */, @@ -472,12 +506,14 @@ 114B6ECB11FA7526004FB6AB /* LexCLW.cxx */, 114B6ECC11FA7526004FB6AB /* LexCmake.cxx */, 114B6ECD11FA7526004FB6AB /* LexCOBOL.cxx */, + 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */, 114B6ECE11FA7526004FB6AB /* LexConf.cxx */, 114B6ECF11FA7526004FB6AB /* LexCPP.cxx */, 114B6ED011FA7526004FB6AB /* LexCrontab.cxx */, 114B6ED111FA7526004FB6AB /* LexCsound.cxx */, 114B6ED211FA7526004FB6AB /* LexCSS.cxx */, 114B6ED311FA7526004FB6AB /* LexD.cxx */, + 11BEB6A114EF189600BDE92A /* LexECL.cxx */, 114B6ED411FA7526004FB6AB /* LexEiffel.cxx */, 114B6ED511FA7526004FB6AB /* LexErlang.cxx */, 114B6ED611FA7526004FB6AB /* LexEScript.cxx */, @@ -490,6 +526,7 @@ 114B6EDD11FA7526004FB6AB /* LexHTML.cxx */, 114B6EDE11FA7526004FB6AB /* LexInno.cxx */, 114B6EDF11FA7526004FB6AB /* LexKix.cxx */, + 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */, 114B6EE011FA7526004FB6AB /* LexLisp.cxx */, 114B6EE111FA7526004FB6AB /* LexLout.cxx */, 114B6EE211FA7526004FB6AB /* LexLua.cxx */, @@ -498,17 +535,20 @@ 114B6EE511FA7526004FB6AB /* LexMatlab.cxx */, 114B6EE611FA7526004FB6AB /* LexMetapost.cxx */, 114B6EE711FA7526004FB6AB /* LexMMIXAL.cxx */, + 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */, 114B6EE811FA7526004FB6AB /* LexMPT.cxx */, 114B6EE911FA7526004FB6AB /* LexMSSQL.cxx */, 114B6EEA11FA7526004FB6AB /* LexMySQL.cxx */, 114B6EEB11FA7526004FB6AB /* LexNimrod.cxx */, 114B6EEC11FA7526004FB6AB /* LexNsis.cxx */, 114B6EED11FA7526004FB6AB /* LexOpal.cxx */, + 11594BE7155B91DF0099E1FA /* LexOScript.cxx */, 114B6EEE11FA7526004FB6AB /* LexOthers.cxx */, 114B6EEF11FA7526004FB6AB /* LexPascal.cxx */, 114B6EF011FA7526004FB6AB /* LexPB.cxx */, 114B6EF111FA7526004FB6AB /* LexPerl.cxx */, 114B6EF211FA7526004FB6AB /* LexPLM.cxx */, + 1114D6CA1602A951001DC345 /* LexPO.cxx */, 114B6EF311FA7526004FB6AB /* LexPOV.cxx */, 114B6EF411FA7526004FB6AB /* LexPowerPro.cxx */, 114B6EF511FA7526004FB6AB /* LexPowerShell.cxx */, @@ -525,15 +565,18 @@ 114B6F0011FA7526004FB6AB /* LexSpecman.cxx */, 114B6F0111FA7526004FB6AB /* LexSpice.cxx */, 114B6F0211FA7526004FB6AB /* LexSQL.cxx */, + 11FDAEB6174E1A9700FA161B /* LexSTTXT.cxx */, 114B6F0311FA7526004FB6AB /* LexTACL.cxx */, 114B6F0411FA7526004FB6AB /* LexTADS3.cxx */, 114B6F0511FA7526004FB6AB /* LexTAL.cxx */, 114B6F0611FA7526004FB6AB /* LexTCL.cxx */, + 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */, 114B6F0711FA7526004FB6AB /* LexTeX.cxx */, 114B6F0811FA7526004FB6AB /* LexTxt2tags.cxx */, 114B6F0911FA7526004FB6AB /* LexVB.cxx */, 114B6F0A11FA7526004FB6AB /* LexVerilog.cxx */, 114B6F0B11FA7526004FB6AB /* LexVHDL.cxx */, + 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */, 114B6F0C11FA7526004FB6AB /* LexYAML.cxx */, ); name = Lexers; @@ -543,20 +586,14 @@ isa = PBXGroup; children = ( 114B6FD811FA7645004FB6AB /* Accessor.h */, - 114B6FD911FA7645004FB6AB /* CharacterSet.h */, - 114B6FDA11FA7645004FB6AB /* LexAccessor.h */, - 114B6FDB11FA7645004FB6AB /* LexerBase.h */, - 114B6FDC11FA7645004FB6AB /* LexerModule.h */, - 114B6FDD11FA7645004FB6AB /* LexerNoExceptions.h */, - 114B6FDE11FA7645004FB6AB /* LexerSimple.h */, - 114B6FDF11FA7645004FB6AB /* OptionSet.h */, - 114B6FE011FA7645004FB6AB /* PropSetSimple.h */, - 114B6FE111FA7645004FB6AB /* StyleContext.h */, - 114B6FE211FA7645004FB6AB /* WordList.h */, 114B6FA211FA7623004FB6AB /* AutoComplete.h */, 114B6FA311FA7623004FB6AB /* CallTip.h */, + 1100F1E7178E393200105727 /* CaseConvert.h */, + 1100F1E9178E393200105727 /* CaseFolder.h */, 114B6FA411FA7623004FB6AB /* Catalogue.h */, 114B6FA511FA7623004FB6AB /* CellBuffer.h */, + 11FBA39C17817DA00048C071 /* CharacterCategory.h */, + 114B6FD911FA7645004FB6AB /* CharacterSet.h */, 114B6FA611FA7623004FB6AB /* CharClassify.h */, 114B6FA711FA7623004FB6AB /* ContractionState.h */, 114B6FA811FA7623004FB6AB /* Decoration.h */, @@ -564,23 +601,32 @@ 114B6FAA11FA7623004FB6AB /* Editor.h */, 114B6FAB11FA7623004FB6AB /* ExternalLexer.h */, 114B6FAC11FA7623004FB6AB /* FontQuality.h */, + 114B6FA011FA75DB004FB6AB /* ILexer.h */, 114B6FAD11FA7623004FB6AB /* Indicator.h */, 114B6FAE11FA7623004FB6AB /* KeyMap.h */, + 114B6FDA11FA7645004FB6AB /* LexAccessor.h */, + 114B6FDB11FA7645004FB6AB /* LexerBase.h */, + 114B6FDC11FA7645004FB6AB /* LexerModule.h */, + 114B6FDD11FA7645004FB6AB /* LexerNoExceptions.h */, + 114B6FDE11FA7645004FB6AB /* LexerSimple.h */, 114B6FAF11FA7623004FB6AB /* LineMarker.h */, + 114B6FDF11FA7645004FB6AB /* OptionSet.h */, 114B6FB011FA7623004FB6AB /* Partitioning.h */, 114B6FB111FA7623004FB6AB /* PerLine.h */, 114B6FB211FA7623004FB6AB /* PositionCache.h */, + 114B6FE011FA7645004FB6AB /* PropSetSimple.h */, 114B6FB311FA7623004FB6AB /* RESearch.h */, 114B6FB411FA7623004FB6AB /* RunStyles.h */, 114B6FB511FA7623004FB6AB /* ScintillaBase.h */, 114B6FB611FA7623004FB6AB /* Selection.h */, 114B6FB711FA7623004FB6AB /* SplitVector.h */, 114B6FB811FA7623004FB6AB /* Style.h */, - 114B6FB911FA7623004FB6AB /* SVector.h */, + 114B6FE111FA7645004FB6AB /* StyleContext.h */, + 1100F1EA178E393200105727 /* UnicodeFromUTF8.h */, 114B6FBA11FA7623004FB6AB /* UniConversion.h */, 114B6FBB11FA7623004FB6AB /* ViewStyle.h */, + 114B6FE211FA7645004FB6AB /* WordList.h */, 114B6FBC11FA7623004FB6AB /* XPM.h */, - 114B6FA011FA75DB004FB6AB /* ILexer.h */, ); name = "Header Files"; sourceTree = ""; @@ -589,18 +635,14 @@ isa = PBXGroup; children = ( 114B6F8E11FA75BE004FB6AB /* Accessor.cxx */, - 114B6F8F11FA75BE004FB6AB /* CharacterSet.cxx */, - 114B6F9011FA75BE004FB6AB /* LexerBase.cxx */, - 114B6F9111FA75BE004FB6AB /* LexerModule.cxx */, - 114B6F9211FA75BE004FB6AB /* LexerNoExceptions.cxx */, - 114B6F9311FA75BE004FB6AB /* LexerSimple.cxx */, - 114B6F9411FA75BE004FB6AB /* PropSetSimple.cxx */, - 114B6F9511FA75BE004FB6AB /* StyleContext.cxx */, - 114B6F9611FA75BE004FB6AB /* WordList.cxx */, 114B6F6011FA7597004FB6AB /* AutoComplete.cxx */, 114B6F6111FA7597004FB6AB /* CallTip.cxx */, + 1100F1E6178E393200105727 /* CaseConvert.cxx */, + 1100F1E8178E393200105727 /* CaseFolder.cxx */, 114B6F6211FA7597004FB6AB /* Catalogue.cxx */, 114B6F6311FA7597004FB6AB /* CellBuffer.cxx */, + 11FBA39B17817DA00048C071 /* CharacterCategory.cxx */, + 114B6F8F11FA75BE004FB6AB /* CharacterSet.cxx */, 114B6F6411FA7597004FB6AB /* CharClassify.cxx */, 114B6F6511FA7597004FB6AB /* ContractionState.cxx */, 114B6F6611FA7597004FB6AB /* Decoration.cxx */, @@ -609,16 +651,23 @@ 114B6F6911FA7598004FB6AB /* ExternalLexer.cxx */, 114B6F6A11FA7598004FB6AB /* Indicator.cxx */, 114B6F6B11FA7598004FB6AB /* KeyMap.cxx */, + 114B6F9011FA75BE004FB6AB /* LexerBase.cxx */, + 114B6F9111FA75BE004FB6AB /* LexerModule.cxx */, + 114B6F9211FA75BE004FB6AB /* LexerNoExceptions.cxx */, + 114B6F9311FA75BE004FB6AB /* LexerSimple.cxx */, 114B6F6C11FA7598004FB6AB /* LineMarker.cxx */, 114B6F6D11FA7598004FB6AB /* PerLine.cxx */, 114B6F6E11FA7598004FB6AB /* PositionCache.cxx */, + 114B6F9411FA75BE004FB6AB /* PropSetSimple.cxx */, 114B6F6F11FA7598004FB6AB /* RESearch.cxx */, 114B6F7011FA7598004FB6AB /* RunStyles.cxx */, 114B6F7111FA7598004FB6AB /* ScintillaBase.cxx */, 114B6F7211FA7598004FB6AB /* Selection.cxx */, 114B6F7311FA7598004FB6AB /* Style.cxx */, + 114B6F9511FA75BE004FB6AB /* StyleContext.cxx */, 114B6F7411FA7598004FB6AB /* UniConversion.cxx */, 114B6F7511FA7598004FB6AB /* ViewStyle.cxx */, + 114B6F9611FA75BE004FB6AB /* WordList.cxx */, 114B6F7611FA7598004FB6AB /* XPM.cxx */, ); name = "Source Files"; @@ -630,14 +679,14 @@ 2744E59D0FC168A100E85C33 /* InfoBar.h */, 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */, 2744E59E0FC168A100E85C33 /* PlatCocoa.h */, - 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */, - 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */, - 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */, - 2744E5A30FC168A100E85C33 /* ScintillaView.h */, 2744E4850FC1678600E85C33 /* Platform.h */, + 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */, + 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */, + 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */, 2744E4870FC1678600E85C33 /* SciLexer.h */, 2744E4880FC1678600E85C33 /* Scintilla.h */, - 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */, + 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */, + 2744E5A30FC168A100E85C33 /* ScintillaView.h */, ); name = "Header Files"; sourceTree = ""; @@ -689,7 +738,6 @@ 2791F3C70FC19F71009DBCF9 /* Platform.h in Headers */, 2791F3C80FC19F71009DBCF9 /* SciLexer.h in Headers */, 2791F3C90FC19F71009DBCF9 /* Scintilla.h in Headers */, - 2791F3E80FC1A3AE009DBCF9 /* ScintillaWidget.h in Headers */, 114B6FA111FA75DB004FB6AB /* ILexer.h in Headers */, 114B6FBD11FA7623004FB6AB /* AutoComplete.h in Headers */, 114B6FBE11FA7623004FB6AB /* CallTip.h in Headers */, @@ -714,7 +762,6 @@ 114B6FD111FA7623004FB6AB /* Selection.h in Headers */, 114B6FD211FA7623004FB6AB /* SplitVector.h in Headers */, 114B6FD311FA7623004FB6AB /* Style.h in Headers */, - 114B6FD411FA7623004FB6AB /* SVector.h in Headers */, 114B6FD511FA7623004FB6AB /* UniConversion.h in Headers */, 114B6FD611FA7623004FB6AB /* ViewStyle.h in Headers */, 114B6FD711FA7623004FB6AB /* XPM.h in Headers */, @@ -729,6 +776,11 @@ 114B6FEB11FA7645004FB6AB /* PropSetSimple.h in Headers */, 114B6FEC11FA7645004FB6AB /* StyleContext.h in Headers */, 114B6FED11FA7645004FB6AB /* WordList.h in Headers */, + 119FF1BF13C9D1820007CE42 /* QuartzTextStyle.h in Headers */, + 11FBA39E17817DA00048C071 /* CharacterCategory.h in Headers */, + 1100F1EC178E393200105727 /* CaseConvert.h in Headers */, + 1100F1EE178E393200105727 /* CaseFolder.h in Headers */, + 1100F1EF178E393200105727 /* UnicodeFromUTF8.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -759,8 +811,11 @@ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "ScintillaFramework" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -915,6 +970,18 @@ 114B6F9F11FA75BE004FB6AB /* WordList.cxx in Sources */, 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */, 11BB124D12FF9C1300F6BCF7 /* LexModula.cxx in Sources */, + 11A0A8A1148602DF0018D143 /* LexCoffeeScript.cxx in Sources */, + 117ACE9114A29A1E002876F9 /* LexTCMD.cxx in Sources */, + 11126B8214CD3A6200803C49 /* LexAVS.cxx in Sources */, + 11BEB6A214EF189600BDE92A /* LexECL.cxx in Sources */, + 11594BE9155B91DF0099E1FA /* LexOScript.cxx in Sources */, + 11594BEA155B91DF0099E1FA /* LexVisualProlog.cxx in Sources */, + 1114D6CB1602A951001DC345 /* LexPO.cxx in Sources */, + 1102C31C169FB49300DC16AB /* LexLaTeX.cxx in Sources */, + 11FDAEB7174E1A9800FA161B /* LexSTTXT.cxx in Sources */, + 11FBA39D17817DA00048C071 /* CharacterCategory.cxx in Sources */, + 1100F1EB178E393200105727 /* CaseConvert.cxx in Sources */, + 1100F1ED178E393200105727 /* CaseFolder.cxx in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -943,7 +1010,6 @@ EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = ".bzr *.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj"; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -952,10 +1018,15 @@ SCI_NAMESPACE, SCI_LEXER, ); + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; - SDKROOT = macosx10.6; + SDKROOT = macosx10.7; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -976,10 +1047,15 @@ SCI_NAMESPACE, SCI_LEXER, ); + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; - SDKROOT = macosx10.6; + SDKROOT = macosx10.7; WRAPPER_EXTENSION = framework; }; name = Release; @@ -998,8 +1074,7 @@ ../../lexlib, ); ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = macosx10.7; }; name = Debug; }; @@ -1015,8 +1090,7 @@ ../../src, ../../lexlib, ); - PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = macosx10.7; }; name = Release; }; diff --git a/scintilla/cocoa/ScintillaTest/AppController.mm b/scintilla/cocoa/ScintillaTest/AppController.mm index a42c8162..71dc130e 100644 --- a/scintilla/cocoa/ScintillaTest/AppController.mm +++ b/scintilla/cocoa/ScintillaTest/AppController.mm @@ -116,10 +116,12 @@ const char user_keywords[] = // Definition of own keywords, not used by MySQL. [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 7 value: user_keywords]; // Colors and styles for various syntactic elements. First the default style. - [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Andale Mono"]; + [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Helvetica"]; // [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Monospac821 BT"]; // Very pleasing programmer's font. [mEditor setGeneralProperty: SCI_STYLESETSIZE parameter: STYLE_DEFAULT value: 14]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: STYLE_DEFAULT value: [NSColor blackColor]]; + + [mEditor setGeneralProperty: SCI_STYLECLEARALL parameter: 0 value: 0]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DEFAULT value: [NSColor blackColor]]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_COMMENT fromHTML: @"#097BF7"]; @@ -211,6 +213,47 @@ const char user_keywords[] = // Definition of own keywords, not used by MySQL. //-------------------------------------------------------------------------------------------------- +/* XPM */ +static const char * box_xpm[] = { + "12 12 2 1", + " c None", + ". c #800000", + " .........", + " . . ..", + " . . . .", + "......... .", + ". . . .", + ". . . ..", + ". . .. .", + "......... .", + ". . . .", + ". . . . ", + ". . .. ", + "......... "}; + + +- (void) showAutocompletion +{ + const char *words = "Babylon-5?1 Battlestar-Galactica Millenium-Falcon?2 Moya?2 Serenity Voyager"; + [mEditor setGeneralProperty: SCI_AUTOCSETIGNORECASE parameter: 1 value:0]; + [mEditor setGeneralProperty: SCI_REGISTERIMAGE parameter: 1 value:(sptr_t)box_xpm]; + const int imSize = 12; + [mEditor setGeneralProperty: SCI_RGBAIMAGESETWIDTH parameter: imSize value:0]; + [mEditor setGeneralProperty: SCI_RGBAIMAGESETHEIGHT parameter: imSize value:0]; + char image[imSize * imSize * 4]; + for (size_t y = 0; y < imSize; y++) { + for (size_t x = 0; x < imSize; x++) { + char *p = image + (y * imSize + x) * 4; + p[0] = 0xFF; + p[1] = 0xA0; + p[2] = 0; + p[3] = x * 23; + } + } + [mEditor setGeneralProperty: SCI_REGISTERRGBAIMAGE parameter: 2 value:(sptr_t)image]; + [mEditor setGeneralProperty: SCI_AUTOCSHOW parameter: 0 value:(sptr_t)words]; +} + - (IBAction) searchText: (id) sender { NSSearchField* searchField = (NSSearchField*) sender; @@ -219,6 +262,18 @@ const char user_keywords[] = // Definition of own keywords, not used by MySQL. wholeWord: NO scrollTo: YES wrap: YES]; + + long matchStart = [mEditor getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + long matchEnd = [mEditor getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; + [mEditor setGeneralProperty: SCI_FINDINDICATORFLASH parameter: matchStart value:matchEnd]; + + if ([[searchField stringValue] isEqualToString: @"XX"]) + [self showAutocompletion]; +} + +-(IBAction) setFontQuality: (id) sender +{ + [ScintillaView directCall:mEditor message:SCI_SETFONTQUALITY wParam:[sender tag] lParam:0]; } @end diff --git a/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib b/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib index 6de46071..e2d93cca 100644 --- a/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib +++ b/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib @@ -856,6 +856,56 @@ + + + Font Quality + + 2147483647 + + + submenuAction: + + Font Quality + + YES + + + Default + + 2147483647 + + + + + + Non-antialiased + + 2147483647 + + + 1 + + + + Antialiased + + 2147483647 + + + 2 + + + + LCD Optimized + + 2147483647 + + + 3 + + + + YES @@ -1833,6 +1883,38 @@ 468 + + + setFontQuality: + + + + 475 + + + + setFontQuality: + + + + 476 + + + + setFontQuality: + + + + 477 + + + + setFontQuality: + + + + 478 + @@ -2537,6 +2619,7 @@ + @@ -2771,6 +2854,47 @@ + + 469 + + + YES + + + + + + 470 + + + YES + + + + + + + + + 471 + + + + + 472 + + + + + 473 + + + + + 474 + + + diff --git a/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj index 30398ef9..ba5405c3 100644 --- a/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj +++ b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -190,8 +190,11 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ScintillaTest" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -286,7 +289,6 @@ COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -301,6 +303,7 @@ LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ""; PRODUCT_NAME = ScintillaTest; + SDKROOT = macosx10.7; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; @@ -325,6 +328,7 @@ LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ""; PRODUCT_NAME = ScintillaTest; + SDKROOT = macosx10.7; USER_HEADER_SEARCH_PATHS = ""; }; name = Release; @@ -335,12 +339,12 @@ ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; - PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx10.7; }; name = Debug; }; @@ -349,11 +353,11 @@ buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = ""; - PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx10.7; }; name = Release; }; diff --git a/scintilla/cocoa/ScintillaView.h b/scintilla/cocoa/ScintillaView.h index bf987870..8d0a9bb8 100644 --- a/scintilla/cocoa/ScintillaView.h +++ b/scintilla/cocoa/ScintillaView.h @@ -4,7 +4,8 @@ * * Created by Mike Lischke. * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright 2009, 2011 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ @@ -21,11 +22,33 @@ extern NSString *SCIUpdateUINotification; +@protocol ScintillaNotificationProtocol +- (void)notification: (Scintilla::SCNotification*)notification; +@end + +/** + * MarginView draws line numbers and other margins next to the text view. + */ +@interface MarginView : NSRulerView +{ +@private + int marginWidth; + ScintillaView *owner; + NSMutableArray *currentCursors; +} + +@property (assign) int marginWidth; +@property (assign) ScintillaView *owner; + +- (id)initWithScrollView:(NSScrollView *)aScrollView; + +@end + /** * InnerView is the Cocoa interface to the Scintilla backend. It handles text input and * provides a canvas for painting the output. */ -@interface InnerView : NSView +@interface InnerView : NSView { @private ScintillaView* mOwner; @@ -34,11 +57,11 @@ extern NSString *SCIUpdateUINotification; // Set when we are in composition mode and partial input is displayed. NSRange mMarkedTextRange; - - // Caret position when a drag operation started. - int mLastPosition; + BOOL undoCollectionWasActive; } +@property (nonatomic, assign) ScintillaView* owner; + - (void) dealloc; - (void) removeMarkedText; - (void) setCursor: (Scintilla::Window::Cursor) cursor; @@ -46,7 +69,6 @@ extern NSString *SCIUpdateUINotification; - (BOOL) canUndo; - (BOOL) canRedo; -@property (retain) ScintillaView* owner; @end @interface ScintillaView : NSView @@ -56,23 +78,28 @@ extern NSString *SCIUpdateUINotification; // It uses the content view for display. Scintilla::ScintillaCocoa* mBackend; - // The object (eg NSDocument) that controls the ScintillaView. - NSObject* mOwner; - // This is the actual content to which the backend renders itself. InnerView* mContent; - NSScroller* mHorizontalScroller; - NSScroller* mVerticalScroller; + NSScrollView *scrollView; + MarginView *marginView; + + CGFloat zoomDelta; // Area to display additional controls (e.g. zoom info, caret position, status info). NSView * mInfoBar; BOOL mInfoBarAtTop; int mInitialInfoBarWidth; + + id mDelegate; } +@property (nonatomic, readonly) Scintilla::ScintillaCocoa* backend; +@property (nonatomic, assign) id delegate; +@property (nonatomic, readonly) NSScrollView *scrollView; + - (void) dealloc; -- (void) layout; +- (void) positionSubViews; - (void) sendNotification: (NSString*) notificationName; - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location @@ -82,11 +109,7 @@ extern NSString *SCIUpdateUINotification; - (void) suspendDrawing: (BOOL) suspend; // Scroller handling -- (BOOL) setVerticalScrollRange: (int) range page: (int) page; -- (void) setVerticalScrollPosition: (float) position; -- (BOOL) setHorizontalScrollRange: (int) range page: (int) page; -- (void) setHorizontalScrollPosition: (float) position; - +- (void) setMarginWidth: (int) width; - (void) scrollerAction: (id) sender; - (InnerView*) content; @@ -108,6 +131,9 @@ extern NSString *SCIUpdateUINotification; // Native call through to the backend. + (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam; +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam; +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam; +- (sptr_t) message: (unsigned int) message; // Back end properties getters and setters. - (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value; @@ -132,12 +158,23 @@ extern NSString *SCIUpdateUINotification; - (void) setInfoBar: (NSView *) aView top: (BOOL) top; - (void) setStatusText: (NSString*) text; -- (void) findAndHighlightText: (NSString*) searchText +- (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap; -@property Scintilla::ScintillaCocoa* backend; -@property (retain) NSObject* owner; +- (BOOL) findAndHighlightText: (NSString*) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap + backwards: (BOOL) backwards; + +- (int) findAndReplaceText: (NSString*) searchText + byText: (NSString*) newText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + doAll: (BOOL) doAll; + @end diff --git a/scintilla/cocoa/ScintillaView.mm b/scintilla/cocoa/ScintillaView.mm index 3e991211..1ec29a67 100644 --- a/scintilla/cocoa/ScintillaView.mm +++ b/scintilla/cocoa/ScintillaView.mm @@ -4,7 +4,8 @@ * * Created by Mike Lischke. * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright 2009, 2011 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ @@ -21,13 +22,138 @@ static NSCursor* waitCursor; NSString *SCIUpdateUINotification = @"SCIUpdateUI"; +/** + * Provide an NSCursor object that matches the Window::Cursor enumeration. + */ +static NSCursor *cursorFromEnum(Window::Cursor cursor) +{ + switch (cursor) + { + case Window::cursorText: + return [NSCursor IBeamCursor]; + case Window::cursorArrow: + return [NSCursor arrowCursor]; + case Window::cursorWait: + return waitCursor; + case Window::cursorHoriz: + return [NSCursor resizeLeftRightCursor]; + case Window::cursorVert: + return [NSCursor resizeUpDownCursor]; + case Window::cursorReverseArrow: + return reverseArrowCursor; + case Window::cursorUp: + default: + return [NSCursor arrowCursor]; + } +} + + +@implementation MarginView + +@synthesize marginWidth, owner; + +- (id)initWithScrollView:(NSScrollView *)aScrollView +{ + self = [super initWithScrollView:aScrollView orientation:NSVerticalRuler]; + if (self != nil) + { + owner = nil; + marginWidth = 20; + currentCursors = [[NSMutableArray arrayWithCapacity:0] retain]; + for (size_t i=0; i<5; i++) + { + [currentCursors addObject: [reverseArrowCursor retain]]; + } + [self setClientView:[aScrollView documentView]]; + } + return self; +} + +- (void) dealloc +{ + [currentCursors release]; + [super dealloc]; +} + +- (void) setFrame: (NSRect) frame +{ + [super setFrame: frame]; + + [[self window] invalidateCursorRectsForView: self]; +} + +- (CGFloat)requiredThickness +{ + return marginWidth; +} + +- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect +{ + if (owner) { + NSRect contentRect = [[[self scrollView] contentView] bounds]; + NSRect marginRect = [self bounds]; + // Ensure paint to bottom of view to avoid glitches + if (marginRect.size.height > contentRect.size.height) { + // Legacy scroll bar mode leaves a poorly painted corner + aRect = marginRect; + } + owner.backend->PaintMargin(aRect); + } +} + +- (void) mouseDown: (NSEvent *) theEvent +{ + owner.backend->MouseDown(theEvent); +} + +- (void) mouseDragged: (NSEvent *) theEvent +{ + owner.backend->MouseMove(theEvent); +} + +- (void) mouseMoved: (NSEvent *) theEvent +{ + owner.backend->MouseMove(theEvent); +} + +- (void) mouseUp: (NSEvent *) theEvent +{ + owner.backend->MouseUp(theEvent); +} + +/** + * This method is called to give us the opportunity to define our mouse sensitive rectangle. + */ +- (void) resetCursorRects +{ + [super resetCursorRects]; + + int x = 0; + NSRect marginRect = [self bounds]; + size_t co = [currentCursors count]; + for (size_t i=0; iWndProc(SCI_GETMARGINCURSORN, i, 0); + int width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); + NSCursor *cc = cursorFromEnum(static_cast(cursType)); + [currentCursors replaceObjectAtIndex:i withObject: cc]; + marginRect.origin.x = x; + marginRect.size.width = width; + [self addCursorRect: marginRect cursor: cc]; + [cc setOnMouseEntered: YES]; + x += width; + } +} + +@end + @implementation InnerView @synthesize owner = mOwner; //-------------------------------------------------------------------------------------------------- -- (NSView*) initWithFrame: (NSRect) frame +- (NSView*) initWithFrame: (NSRect) frame { self = [super initWithFrame: frame]; @@ -72,32 +198,7 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; - (void) setCursor: (Window::Cursor) cursor { [mCurrentCursor autorelease]; - switch (cursor) - { - case Window::cursorText: - mCurrentCursor = [NSCursor IBeamCursor]; - break; - case Window::cursorArrow: - mCurrentCursor = [NSCursor arrowCursor]; - break; - case Window::cursorWait: - mCurrentCursor = waitCursor; - break; - case Window::cursorHoriz: - mCurrentCursor = [NSCursor resizeLeftRightCursor]; - break; - case Window::cursorVert: - mCurrentCursor = [NSCursor resizeUpDownCursor]; - break; - case Window::cursorReverseArrow: - mCurrentCursor = reverseArrowCursor; - break; - case Window::cursorUp: - default: - mCurrentCursor = [NSCursor arrowCursor]; - break; - } - + mCurrentCursor = cursorFromEnum(cursor); [mCurrentCursor retain]; // Trigger recreation of the cursor rectangle(s). @@ -127,7 +228,11 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; { CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; - mOwner.backend->Draw(rect, context); + if (!mOwner.backend->Draw(rect, context)) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self setNeedsDisplay:YES]; + }); + } } //-------------------------------------------------------------------------------------------------- @@ -158,6 +263,7 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; */ - (BOOL) acceptsFirstMouse: (NSEvent *) theEvent { +#pragma unused(theEvent) return YES; } @@ -186,9 +292,9 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- -// Adoption of NSTextInput protocol. +// Adoption of NSTextInputClient protocol. -- (NSAttributedString*) attributedSubstringFromRange: (NSRange) range +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { return nil; } @@ -202,14 +308,6 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- -- (NSInteger) conversationIdentifier -{ - return (NSInteger) self; - -} - -//-------------------------------------------------------------------------------------------------- - - (void) doCommandBySelector: (SEL) selector { if ([self respondsToSelector: @selector(selector)]) @@ -218,9 +316,41 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- -- (NSRect) firstRectForCharacterRange: (NSRange) range +- (NSRect) firstRectForCharacterRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange { - return NSZeroRect; + NSRect rect; + rect.origin.x = [ScintillaView directCall: mOwner + message: SCI_POINTXFROMPOSITION + wParam: 0 + lParam: aRange.location]; + rect.origin.y = [ScintillaView directCall: mOwner + message: SCI_POINTYFROMPOSITION + wParam: 0 + lParam: aRange.location]; + int rangeEnd = aRange.location + aRange.length; + rect.size.width = [ScintillaView directCall: mOwner + message: SCI_POINTXFROMPOSITION + wParam: 0 + lParam: rangeEnd] - rect.origin.x; + rect.size.height = [ScintillaView directCall: mOwner + message: SCI_POINTYFROMPOSITION + wParam: 0 + lParam: rangeEnd] - rect.origin.y; + rect.size.height += [ScintillaView directCall: mOwner + message: SCI_TEXTHEIGHT + wParam: 0 + lParam: 0]; + rect = [[[self superview] superview] convertRect:rect toView:nil]; +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6 + if ([self.window respondsToSelector:@selector(convertRectToScreen:)]) + rect = [self.window convertRectToScreen:rect]; + else // convertRectToScreen not available on 10.6 + rect.origin = [self.window convertBaseToScreen:rect.origin]; +#else + rect.origin = [self.window convertBaseToScreen:rect.origin]; +#endif + + return rect; } //-------------------------------------------------------------------------------------------------- @@ -235,11 +365,26 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; /** * General text input. Used to insert new text at the current input position, replacing the current * selection if there is any. + * First removes the replacementRange. */ -- (void) insertText: (id) aString +- (void) insertText: (id) aString replacementRange: (NSRange) replacementRange { // Remove any previously marked text first. [self removeMarkedText]; + + if (replacementRange.location == (NSNotFound-1)) + // This occurs when the accent popup is visible and menu selected. + // Its replacing a non-existant position so do nothing. + return; + + if (replacementRange.length > 0) + { + [ScintillaView directCall: mOwner + message: SCI_DELETERANGE + wParam: replacementRange.location + lParam: replacementRange.length]; + } + NSString* newText = @""; if ([aString isKindOfClass:[NSString class]]) newText = (NSString*) aString; @@ -260,8 +405,8 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; - (NSRange) selectedRange { - int begin = [mOwner getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; - int end = [mOwner getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; + long begin = [mOwner getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + long end = [mOwner getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; return NSMakeRange(begin, end - begin); } @@ -274,51 +419,82 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; * @param aString The text to insert, either what has been marked already or what is selected already * or simply added at the current insertion point. Depending on what is available. * @param range The range of the new text to select (given relative to the insertion point of the new text). + * @param replacementRange The range to remove before insertion. */ -- (void) setMarkedText: (id) aString selectedRange: (NSRange) range +- (void) setMarkedText: (id) aString selectedRange: (NSRange)range replacementRange: (NSRange)replacementRange { - // Since we did not return any valid attribute for marked text (see validAttributesForMarkedText) - // we can safely assume the passed in text is an NSString instance. - NSString* newText = @""; - if ([aString isKindOfClass:[NSString class]]) - newText = (NSString*) aString; - else if ([aString isKindOfClass:[NSAttributedString class]]) - newText = (NSString*) [aString string]; - - int currentPosition = [mOwner getGeneralProperty: SCI_GETCURRENTPOS parameter: 0]; + NSString* newText = @""; + if ([aString isKindOfClass:[NSString class]]) + newText = (NSString*) aString; + else + if ([aString isKindOfClass:[NSAttributedString class]]) + newText = (NSString*) [aString string]; + + long currentPosition = [mOwner getGeneralProperty: SCI_GETCURRENTPOS parameter: 0]; // Replace marked text if there is one. if (mMarkedTextRange.length > 0) { - // We have already marked text. Replace that. [mOwner setGeneralProperty: SCI_SETSELECTIONSTART value: mMarkedTextRange.location]; [mOwner setGeneralProperty: SCI_SETSELECTIONEND value: mMarkedTextRange.location + mMarkedTextRange.length]; currentPosition = mMarkedTextRange.location; } + else + { + // Switching into composition so remember if collecting undo. + undoCollectionWasActive = [mOwner getGeneralProperty: SCI_GETUNDOCOLLECTION] != 0; + + // Keep Scintilla from collecting undo actions for the composition task. + [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: 0]; + + // Ensure only a single selection + mOwner.backend->SelectOnlyMainSelection(); + } + + if (replacementRange.length > 0) + { + [ScintillaView directCall: mOwner + message: SCI_DELETERANGE + wParam: replacementRange.location + lParam: replacementRange.length]; + } // Note: Scintilla internally works almost always with bytes instead chars, so we need to take // this into account when determining selection ranges and such. std::string raw_text = [newText UTF8String]; - mOwner.backend->InsertText(newText); + int lengthInserted = mOwner.backend->InsertText(newText); mMarkedTextRange.location = currentPosition; - mMarkedTextRange.length = raw_text.size(); + mMarkedTextRange.length = lengthInserted; - // Mark the just inserted text. Keep the marked range for later reset. - [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INPUT_INDICATOR]; - [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE - parameter: mMarkedTextRange.location - value: mMarkedTextRange.length]; - + if (lengthInserted > 0) + { + // Mark the just inserted text. Keep the marked range for later reset. + [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INPUT_INDICATOR]; + [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE + parameter: mMarkedTextRange.location + value: mMarkedTextRange.length]; + } + else + { + // Re-enable undo action collection if composition ended (indicated by an empty mark string). + if (undoCollectionWasActive) + [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: range.length == 0]; + } + // Select the part which is indicated in the given range. It does not scroll the caret into view. if (range.length > 0) { - [mOwner setGeneralProperty: SCI_SETSELECTIONSTART - value: currentPosition + range.location]; - [mOwner setGeneralProperty: SCI_SETSELECTIONEND - value: currentPosition + range.location + range.length]; + // range is in characters so convert to bytes for selection. + int rangeStart = currentPosition; + for (size_t characterInComposition=0; characterInCompositionInsertText(@""); mMarkedTextRange = NSMakeRange(NSNotFound, 0); + + // Reenable undo action collection, after we are done with text composition. + if (undoCollectionWasActive) + [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: 1]; } } @@ -362,14 +546,14 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; return nil; } -// End of the NSTextInput protocol adoption. +// End of the NSTextInputClient protocol adoption. //-------------------------------------------------------------------------------------------------- /** * Generic input method. It is used to pass on keyboard input to Scintilla. The control itself only * handles shortcuts. The input is then forwarded to the Cocoa text input system, which in turn does - * its own input handling (character composition via NSTextInput protocol): + * its own input handling (character composition via NSTextInputClient protocol): */ - (void) keyDown: (NSEvent *) theEvent { @@ -423,9 +607,35 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- +/** + * Mouse wheel with command key magnifies text. + */ - (void) scrollWheel: (NSEvent *) theEvent { - mOwner.backend->MouseWheel(theEvent); + if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { + mOwner.backend->MouseWheel(theEvent); + } else { + [super scrollWheel:theEvent]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Ensure scrolling is aligned to whole lines instead of starting part-way through a line + */ +- (NSRect)adjustScroll:(NSRect)proposedVisibleRect +{ + NSRect rc = proposedVisibleRect; + // Snap to lines + NSRect contentRect = [self bounds]; + if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { + // Only snap for positions inside the document - allow outside + // for overshoot. + int lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); + rc.origin.y = roundf(rc.origin.y / lineHeight) * lineHeight; + } + return rc; } //-------------------------------------------------------------------------------------------------- @@ -484,6 +694,7 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; - (BOOL) prepareForDragOperation: (id ) sender { +#pragma unused(sender) return YES; } @@ -501,7 +712,19 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; */ - (NSDragOperation) draggingSourceOperationMaskForLocal: (BOOL) flag { - return NSDragOperationCopy | NSDragOperationMove; + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Finished a drag: may need to delete selection. + */ + +- (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation { + if (operation == NSDragOperationDelete) { + mOwner.backend->WndProc(SCI_CLEAR, 0, 0); + } } //-------------------------------------------------------------------------------------------------- @@ -521,36 +744,43 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; - (void) selectAll: (id) sender { +#pragma unused(sender) mOwner.backend->SelectAll(); } - (void) deleteBackward: (id) sender { +#pragma unused(sender) mOwner.backend->DeleteBackward(); } - (void) cut: (id) sender { +#pragma unused(sender) mOwner.backend->Cut(); } - (void) copy: (id) sender { +#pragma unused(sender) mOwner.backend->Copy(); } - (void) paste: (id) sender { +#pragma unused(sender) mOwner.backend->Paste(); } - (void) undo: (id) sender { +#pragma unused(sender) mOwner.backend->Undo(); } - (void) redo: (id) sender { +#pragma unused(sender) mOwner.backend->Redo(); } @@ -564,6 +794,28 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; return mOwner.backend->CanRedo(); } +- (BOOL) validateUserInterfaceItem: (id ) anItem +{ + SEL action = [anItem action]; + if (action==@selector(undo:)) { + return [self canUndo]; + } + else if (action==@selector(redo:)) { + return [self canRedo]; + } + else if (action==@selector(cut:) || action==@selector(copy:) || action==@selector(clear:)) { + return mOwner.backend->HasSelection(); + } + else if (action==@selector(paste:)) { + return mOwner.backend->CanPaste(); + } + return YES; +} + +- (void) clear: (id) sender +{ + [self deleteBackward:sender]; +} - (BOOL) isEditable { @@ -585,10 +837,11 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; @implementation ScintillaView @synthesize backend = mBackend; -@synthesize owner = mOwner; +@synthesize delegate = mDelegate; +@synthesize scrollView; /** - * ScintiallView is a composite control made from an NSView and an embedded NSView that is + * ScintillaView is a composite control made from an NSView and an embedded NSView that is * used as canvas for the output (by the backend, using its CGContext), plus other elements * (scrollers, info bar). */ @@ -616,6 +869,29 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- +/** + * Receives zoom messages, for example when a "pinch zoom" is performed on the trackpad. + */ +- (void) magnifyWithEvent: (NSEvent *) event +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + zoomDelta += event.magnification * 10.0; + + if (fabsf(zoomDelta)>=1.0) { + long zoomFactor = [self getGeneralProperty: SCI_GETZOOM] + zoomDelta; + [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value:0]; + zoomDelta = 0.0; + } +#endif +} + +- (void) beginGestureWithEvent: (NSEvent *) event +{ + zoomDelta = 0.0; +} + +//-------------------------------------------------------------------------------------------------- + /** * Sends a new notification of the given type to the default notification center. */ @@ -643,7 +919,7 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; case IBNZoomChanged: { // Compute point increase/decrease based on default font size. - int fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; int zoom = (int) (fontSize * (value - 1)); [self setGeneralProperty: SCI_SETZOOM value: zoom]; break; @@ -679,6 +955,8 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; /** * Notification function used by Scintilla to call us back (e.g. for handling clicks on the * folder margin or changes in the editor). + * A delegate can be set to receive all notifications. If set no handling takes place here, except + * for action pertaining to internal stuff (like the info bar). */ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam) { @@ -693,6 +971,14 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa SCNotification* scn = reinterpret_cast(lParam); ScintillaCocoa *psc = reinterpret_cast(scn->nmhdr.hwndFrom); editor = reinterpret_cast(psc->ContentView()).owner; + + if (editor.delegate != nil) + { + [editor.delegate notification: scn]; + if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) + return; + } + switch (scn->nmhdr.code) { case SCN_MARGINCLICK: @@ -700,7 +986,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa if (scn->margin == 2) { // Click on the folder margin. Toggle the current line if possible. - int line = [editor getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; + long line = [editor getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; [editor setGeneralProperty: SCI_TOGGLEFOLD value: line]; } break; @@ -717,7 +1003,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa { // A zoom change happend. Notify info bar if there is one. float zoom = [editor getGeneralProperty: SCI_GETZOOM parameter: 0]; - int fontSize = [editor getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + long fontSize = [editor getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; float factor = (zoom / fontSize) + 1; [editor->mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; break; @@ -764,27 +1050,32 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa if (self) { mContent = [[[InnerView alloc] init] autorelease]; - mBackend = new ScintillaCocoa(mContent); mContent.owner = self; - [self addSubview: mContent]; - + // Initialize the scrollers but don't show them yet. // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction // (horizontal or vertical). NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); - mHorizontalScroller = [[[NSScroller alloc] initWithFrame: scrollerRect] autorelease]; - [mHorizontalScroller setHidden: YES]; - [mHorizontalScroller setTarget: self]; - [mHorizontalScroller setAction: @selector(scrollerAction:)]; - [self addSubview: mHorizontalScroller]; - - scrollerRect.size = NSMakeSize(10, 100); - mVerticalScroller = [[[NSScroller alloc] initWithFrame: scrollerRect] autorelease]; - [mVerticalScroller setHidden: YES]; - [mVerticalScroller setTarget: self]; - [mVerticalScroller setAction: @selector(scrollerAction:)]; - [self addSubview: mVerticalScroller]; + scrollView = [[[NSScrollView alloc] initWithFrame: scrollerRect] autorelease]; + [scrollView setDocumentView: mContent]; + [scrollView setHasVerticalScroller:YES]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; + //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; + //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; + [self addSubview: scrollView]; + + marginView = [[MarginView alloc] initWithScrollView:scrollView]; + marginView.owner = self; + [marginView setRuleThickness:[marginView requiredThickness]]; + [scrollView setVerticalRulerView:marginView]; + [scrollView setHasHorizontalRuler:NO]; + [scrollView setHasVerticalRuler:YES]; + [scrollView setRulersVisible:YES]; + mBackend = new ScintillaCocoa(mContent, marginView); + // Establish a connection from the back end to this container so we can handle situations // which require our attention. mBackend->RegisterNotifyCallback(nil, notification); @@ -806,6 +1097,12 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; + + [[scrollView contentView] setPostsBoundsChangedNotifications:YES]; + [center addObserver:self + selector:@selector(scrollerAction:) + name:NSViewBoundsDidChangeNotification + object:[scrollView contentView]]; } return self; } @@ -814,7 +1111,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa - (void) dealloc { - [mInfoBar release]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; delete mBackend; [super dealloc]; } @@ -822,12 +1119,14 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa //-------------------------------------------------------------------------------------------------- - (void) applicationDidResignActive: (NSNotification *)note { +#pragma unused(note) mBackend->ActiveStateChanged(false); } //-------------------------------------------------------------------------------------------------- - (void) applicationDidBecomeActive: (NSNotification *)note { +#pragma unused(note) mBackend->ActiveStateChanged(true); } @@ -837,7 +1136,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa { [super viewDidMoveToWindow]; - [self layout]; + [self positionSubViews]; // Enable also mouse move events for our window (and so this view). [[self window] setAcceptsMouseMovedEvents: YES]; @@ -848,198 +1147,51 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa /** * Used to position and size the parts of the editor (content, scrollers, info bar). */ -- (void) layout +- (void) positionSubViews { int scrollerWidth = [NSScroller scrollerWidth]; NSSize size = [self frame].size; - NSRect hScrollerRect = {0, 0, size.width, scrollerWidth}; - NSRect vScrollerRect = {size.width - scrollerWidth, 0, scrollerWidth, size.height}; - NSRect barFrame = {0, size.height - scrollerWidth, size.width, scrollerWidth}; + NSRect barFrame = {0, size.height - scrollerWidth, size.width, static_cast(scrollerWidth)}; BOOL infoBarVisible = mInfoBar != nil && ![mInfoBar isHidden]; - + // Horizontal offset of the content. Almost always 0 unless the vertical scroller // is on the left side. int contentX = 0; - - // Vertical scroller frame calculation. - if (![mVerticalScroller isHidden]) - { - // Consider user settings (left vs right vertical scrollbar). - BOOL isLeft = [[[NSUserDefaults standardUserDefaults] stringForKey: @"NSScrollerPosition"] - isEqualToString: @"left"]; - if (isLeft) - { - vScrollerRect.origin.x = 0; - hScrollerRect.origin.x = scrollerWidth; - contentX = scrollerWidth; - }; - - size.width -= scrollerWidth; - hScrollerRect.size.width -= scrollerWidth; - } - - // Same for horizontal scroller. - if (![mHorizontalScroller isHidden]) - { - // Make room for the h-scroller. - size.height -= scrollerWidth; - vScrollerRect.size.height -= scrollerWidth; - vScrollerRect.origin.y += scrollerWidth; - }; - + NSRect scrollRect = {contentX, 0, size.width, size.height}; + // Info bar frame. if (infoBarVisible) { + scrollRect.size.height -= scrollerWidth; // Initial value already is as if the bar is at top. - if (mInfoBarAtTop) + if (!mInfoBarAtTop) { - vScrollerRect.size.height -= scrollerWidth; - size.height -= scrollerWidth; - } - else - { - // Layout info bar and h-scroller side by side in a friendly manner. - int nativeWidth = mInitialInfoBarWidth; - int remainingWidth = barFrame.size.width; - + scrollRect.origin.y += scrollerWidth; barFrame.origin.y = 0; - - if ([mHorizontalScroller isHidden]) - { - // H-scroller is not visible, so take the full space. - vScrollerRect.origin.y += scrollerWidth; - vScrollerRect.size.height -= scrollerWidth; - size.height -= scrollerWidth; - } - else - { - // If the left offset of the h-scroller is > 0 then the v-scroller is on the left side. - // In this case we take the full width, otherwise what has been given to the h-scroller - // and content up to now. - if (hScrollerRect.origin.x == 0) - remainingWidth = size.width; - - // Note: remainingWidth can become < 0, which hides the scroller. - remainingWidth -= nativeWidth; - - hScrollerRect.origin.x = nativeWidth; - hScrollerRect.size.width = remainingWidth; - barFrame.size.width = nativeWidth; - } } } - - NSRect contentRect = {contentX, vScrollerRect.origin.y, size.width, size.height}; - [mContent setFrame: contentRect]; - + + if (!NSEqualRects([scrollView frame], scrollRect)) { + [scrollView setFrame: scrollRect]; + } + if (infoBarVisible) [mInfoBar setFrame: barFrame]; - if (![mHorizontalScroller isHidden]) - [mHorizontalScroller setFrame: hScrollerRect]; - if (![mVerticalScroller isHidden]) - [mVerticalScroller setFrame: vScrollerRect]; } //-------------------------------------------------------------------------------------------------- /** - * Called by the backend to adjust the vertical scroller (range and page). - * - * @param range Determines the total size of the scroll area used in the editor. - * @param page Determines how many pixels a page is. - * @result Returns YES if anything changed, otherwise NO. + * Set the width of the margin. */ -- (BOOL) setVerticalScrollRange: (int) range page: (int) page +- (void) setMarginWidth: (int) width { - BOOL result = NO; - BOOL hideScroller = page >= range; - - if ([mVerticalScroller isHidden] != hideScroller) + if (marginView.ruleThickness != width) { - result = YES; - [mVerticalScroller setHidden: hideScroller]; - if (!hideScroller) - [mVerticalScroller setFloatValue: 0]; - [self layout]; + marginView.marginWidth = width; + [marginView setRuleThickness:[marginView requiredThickness]]; } - - if (!hideScroller) - { - [mVerticalScroller setEnabled: YES]; - - CGFloat currentProportion = [mVerticalScroller knobProportion]; - CGFloat newProportion = page / (CGFloat) range; - if (currentProportion != newProportion) - { - result = YES; - [mVerticalScroller setKnobProportion: newProportion]; - } - } - - return result; -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Used to set the position of the vertical scroll thumb. - * - * @param position The relative position in the rang [0..1]; - */ -- (void) setVerticalScrollPosition: (float) position -{ - [mVerticalScroller setFloatValue: position]; -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Called by the backend to adjust the horizontal scroller (range and page). - * - * @param range Determines the total size of the scroll area used in the editor. - * @param page Determines how many pixels a page is. - * @result Returns YES if anything changed, otherwise NO. - */ -- (BOOL) setHorizontalScrollRange: (int) range page: (int) page -{ - BOOL result = NO; - BOOL hideScroller = (page >= range) || - (mBackend->WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE); - - if ([mHorizontalScroller isHidden] != hideScroller) - { - result = YES; - [mHorizontalScroller setHidden: hideScroller]; - [self layout]; - } - - if (!hideScroller) - { - [mHorizontalScroller setEnabled: YES]; - - CGFloat currentProportion = [mHorizontalScroller knobProportion]; - CGFloat newProportion = page / (CGFloat) range; - if (currentProportion != newProportion) - { - result = YES; - [mHorizontalScroller setKnobProportion: newProportion]; - } - } - - return result; -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Used to set the position of the vertical scroll thumb. - * - * @param position The relative position in the rang [0..1]; - */ -- (void) setHorizontalScrollPosition: (float) position -{ - [mHorizontalScroller setFloatValue: position]; } //-------------------------------------------------------------------------------------------------- @@ -1050,8 +1202,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa */ - (void) scrollerAction: (id) sender { - float position = [sender doubleValue]; - mBackend->DoScroll(position, [sender hitPart], sender == mHorizontalScroller); + mBackend->UpdateForScroll(); } //-------------------------------------------------------------------------------------------------- @@ -1061,8 +1212,12 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa */ - (void) setFrame: (NSRect) newFrame { + NSRect previousFrame = [self frame]; [super setFrame: newFrame]; - [self layout]; + [self positionSubViews]; + if (!NSEqualRects(previousFrame, newFrame)) { + mBackend->Resize(); + } } //-------------------------------------------------------------------------------------------------- @@ -1075,23 +1230,18 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa { NSString *result = @""; - char *buffer(0); - const int length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); + const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); if (length > 0) { - buffer = new char[length + 1]; + std::string buffer(length + 1, '\0'); try { - mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) buffer); - mBackend->WndProc(SCI_SETSAVEPOINT, 0, 0); + mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) &buffer[0]); - result = [NSString stringWithUTF8String: buffer]; - delete[] buffer; + result = [NSString stringWithUTF8String: buffer.c_str()]; } catch (...) { - delete[] buffer; - buffer = 0; } } @@ -1108,23 +1258,18 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa { NSString *result = @""; - char *buffer(0); - const int length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); + const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); if (length > 0) { - buffer = new char[length + 1]; + std::string buffer(length + 1, '\0'); try { - mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) buffer); - mBackend->WndProc(SCI_SETSAVEPOINT, 0, 0); + mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) &buffer[0]); - result = [NSString stringWithUTF8String: buffer]; - delete[] buffer; + result = [NSString stringWithUTF8String: buffer.c_str()]; } catch (...) { - delete[] buffer; - buffer = 0; } } @@ -1184,6 +1329,21 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa return ScintillaCocoa::DirectFunction(sender->mBackend, message, wParam, lParam); } +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam +{ + return mBackend->WndProc(message, wParam, lParam); +} + +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam +{ + return mBackend->WndProc(message, wParam, 0); +} + +- (sptr_t) message: (unsigned int) message +{ + return mBackend->WndProc(message, 0, 0); +} + //-------------------------------------------------------------------------------------------------- /** @@ -1326,7 +1486,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa */ - (NSColor*) getColorProperty: (int) property parameter: (long) parameter { - int color = mBackend->WndProc(property, parameter, 0); + long color = mBackend->WndProc(property, parameter, 0); float red = (color & 0xFF) / 255.0; float green = ((color >> 8) & 0xFF) / 255.0; float blue = ((color >> 16) & 0xFF) / 255.0; @@ -1439,7 +1599,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa mInitialInfoBarWidth = [mInfoBar frame].size.width; } - [self layout]; + [self positionSubViews]; } } @@ -1465,55 +1625,198 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa - (void)insertText: (NSString*)text { - [mContent insertText: text]; + mBackend->InsertText(text); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * For backwards compatibility. + */ +- (BOOL) findAndHighlightText: (NSString*) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap +{ + return [self findAndHighlightText: searchText + matchCase: matchCase + wholeWord: wholeWord + scrollTo: scrollTo + wrap: wrap + backwards: NO]; } //-------------------------------------------------------------------------------------------------- /** * Searches and marks the first occurance of the given text and optionally scrolls it into view. + * + * @result YES if something was found, NO otherwise. */ -- (void) findAndHighlightText: (NSString*) searchText +- (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap + backwards: (BOOL) backwards { - // The current position is where we start searching. That is either the end of the current - // (main) selection or the caret position. That ensures we do proper "search next" too. - int currentPosition = [self getGeneralProperty: SCI_GETCURRENTPOS parameter: 0]; - int length = [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]; - int searchFlags= 0; if (matchCase) searchFlags |= SCFIND_MATCHCASE; if (wholeWord) searchFlags |= SCFIND_WHOLEWORD; - Sci_TextToFind ttf; - ttf.chrg.cpMin = currentPosition; - ttf.chrg.cpMax = length; - ttf.lpstrText = (char*) [searchText UTF8String]; - int position = mBackend->WndProc(SCI_FINDTEXT, searchFlags, (sptr_t) &ttf); + int selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + int selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; - if (position < 0 && wrap) + // Sets the start point for the comming search to the begin of the current selection. + // For forward searches we have therefore to set the selection start to the current selection end + // for proper incremental search. This does not harm as we either get a new selection if something + // is found or the previous selection is restored. + if (!backwards) + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + sptr_t result; + const char* textToSearch = [searchText UTF8String]; + + // The following call will also set the selection if something was found. + if (backwards) { - ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = currentPosition; - position = mBackend->WndProc(SCI_FINDTEXT, searchFlags, (sptr_t) &ttf); + result = [ScintillaView directCall: self + message: SCI_SEARCHPREV + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) + { + // Try again from the end of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } } - - if (position >= 0) + else + { + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) + { + // Try again from the start of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } + } + + if (result >= 0) { - // Highlight the found text. - [self setGeneralProperty: SCI_SETSELECTIONSTART - value: position]; - [self setGeneralProperty: SCI_SETSELECTIONEND - value: position + [searchText length]]; - if (scrollTo) [self setGeneralProperty: SCI_SCROLLCARET value: 0]; } + else + { + // Restore the former selection if we did not find anything. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; + } + return (result >= 0) ? YES : NO; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Searches the given text and replaces + * + * @result Number of entries replaced, 0 if none. + */ +- (int) findAndReplaceText: (NSString*) searchText + byText: (NSString*) newText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + doAll: (BOOL) doAll +{ + // The current position is where we start searching for single occurences. Otherwise we start at + // the beginning of the document. + int startPosition; + if (doAll) + startPosition = 0; // Start at the beginning of the text if we replace all occurrences. + else + // For a signle replacement we start at the current caret position. + startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; + int endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; + + int searchFlags= 0; + if (matchCase) + searchFlags |= SCFIND_MATCHCASE; + if (wholeWord) + searchFlags |= SCFIND_WHOLEWORD; + [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; + [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; + [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; + + const char* textToSearch = [searchText UTF8String]; + int sourceLength = strlen(textToSearch); // Length in bytes. + const char* replacement = [newText UTF8String]; + int targetLength = strlen(replacement); // Length in bytes. + sptr_t result; + + int replaceCount = 0; + if (doAll) + { + while (true) + { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + if (result < 0) + break; + + replaceCount++; + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // The replacement changes the target range to the replaced text. Continue after that til the end. + // The text length might be changed by the replacement so make sure the target end is the actual + // text end. + [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; + [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; + } + } + else + { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + replaceCount = (result < 0) ? 0 : 1; + + if (replaceCount > 0) + { + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // For a single replace we set the new selection to the replaced text. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; + } + } + + return replaceCount; } //-------------------------------------------------------------------------------------------------- @@ -1523,7 +1826,7 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa bold: (BOOL) bold italic: (BOOL) italic { - for (int i = 0; i < 32; i++) + for (int i = 0; i < 128; i++) { [self setGeneralProperty: SCI_STYLESETFONT parameter: i diff --git a/scintilla/cocoa/checkbuildosx.sh b/scintilla/cocoa/checkbuildosx.sh new file mode 100644 index 00000000..f6b56328 --- /dev/null +++ b/scintilla/cocoa/checkbuildosx.sh @@ -0,0 +1,75 @@ +# Script to build Scintilla for OS X with most supported build files. +# Current directory should be scintilla/cocoa before running. + +cd ../.. + +# ************************************************************ +# Target 1: build framework and test app with Xcode targetting OS X 10.7 +# Clean both then build both -- if perform clean in ScintillaTest, also cleans ScintillaFramework +# which can cause double build +cd scintilla/cocoa/ScintillaFramework +xcodebuild clean +cd ../ScintillaTest +xcodebuild clean +cd ../ScintillaFramework +xcodebuild -sdk macosx10.7 +cd ../ScintillaTest +xcodebuild -sdk macosx10.7 +cd ../../.. + +# ************************************************************ +# Target 2: build framework and test app with Xcode targetting OS X 10.6 +cd scintilla/cocoa/ScintillaFramework +xcodebuild clean +cd ../ScintillaTest +xcodebuild clean +cd ../ScintillaFramework +xcodebuild -sdk macosx10.6 +cd ../ScintillaTest +xcodebuild -sdk macosx10.6 +cd ../../.. + +# ************************************************************ +# Target 3: build framework and test app with Xcode targetting OS X 10.5 +cd scintilla/cocoa/ScintillaFramework +xcodebuild clean +cd ../ScintillaTest +xcodebuild clean +cd ../ScintillaFramework +xcodebuild -sdk macosx10.5 +cd ../ScintillaTest +xcodebuild -sdk macosx10.5 +cd ../../.. + +# ************************************************************ +# Target 4: Qt builds +# Requires Qt development libraries and qmake to be installed +cd scintilla/qt +cd ScintillaEditBase +qmake +xcodebuild clean +xcodebuild +cd .. + +cd ScintillaEdit +python WidgetGen.py +qmake +xcodebuild clean +xcodebuild +cd .. + +cd ScintillaEditPy +python sepbuild.py +cd .. +cd ../.. + +# ************************************************************ +# Target 5: build framework and test app with make +cd scintilla/cocoa + +make -f Framework.mk clean +make -f Framework.mk all + +make -f SciTest.mk all + +cd ../.. diff --git a/scintilla/delbin.bat b/scintilla/delbin.bat index 8d29322f..3636b987 100644 --- a/scintilla/delbin.bat +++ b/scintilla/delbin.bat @@ -1 +1 @@ -del /S /Q *.a *.aps *.bsc *.dll *.dsw *.exe *.idb *.ilc *.ild *.ilf *.ilk *.ils *.lib *.map *.ncb *.obj *.o *.opt *.pdb *.plg *.res *.sbr *.tds *.exp >NUL: +del /S /Q *.a *.aps *.bsc *.dll *.dsw *.exe *.idb *.ilc *.ild *.ilf *.ilk *.ils *.lib *.map *.ncb *.obj *.o *.opt *.pdb *.plg *.res *.sbr *.tds *.exp *.tlog >NUL: diff --git a/scintilla/doc/ScintillaDoc.html b/scintilla/doc/ScintillaDoc.html index 86fe3740..8c111b1b 100644 --- a/scintilla/doc/ScintillaDoc.html +++ b/scintilla/doc/ScintillaDoc.html @@ -61,6 +61,9 @@ color: #000000; font-size: 10pt; } + .provisional { + background: #FFB000; + } /*]]>*/ --> @@ -79,7 +82,7 @@

Scintilla Documentation

-

Last edited 18/June/2011 NH

+

Last edited 29/June/2013 NH

There is an overview of the internal design of Scintilla.
@@ -112,6 +115,9 @@

The GTK+ version also uses messages in a similar way to the Windows version. This is different to normal GTK+ practice but made it easier to implement rapidly.

+

Scintilla also builds with Cocoa on OS X and with Qt, and follows the conventions of + those platforms.

+

Scintilla does not properly support right-to-left languages like Arabic and Hebrew. While text in these languages may appear correct, it is not possible to interact with this text as is normal with other editing components.

@@ -291,32 +297,42 @@ + o Background loading and saving + o Folding o Line wrapping - - o Zooming + o Zooming + o Long lines o Lexer - - o Lexer objects + o Lexer objects + o Notifications + o Images + + + o GTK+ + o Provisional messages + o Deprecated messages + o Edit messages never supported by Scintilla + o Building Scintilla @@ -380,6 +396,7 @@ SCI_APPENDTEXT(int length, const char *s)
SCI_INSERTTEXT(int pos, const char *text)
SCI_CLEARALL
+ SCI_DELETERANGE(int pos, int deleteLength)
SCI_CLEARDOCUMENTSTYLE
SCI_GETCHARAT(int position)
SCI_GETSTYLEAT(int position)
@@ -387,6 +404,8 @@ *tr)
SCI_SETSTYLEBITS(int bits)
SCI_GETSTYLEBITS
+ SCI_RELEASEALLEXTENDEDSTYLES
+ SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles)
SCI_TARGETASUTF8(<unused>, char *s)
SCI_ENCODEDFROMUTF8(const char *utf8, char *encoded)
SCI_SETLENGTHFORENCODE(int bytes)
@@ -512,6 +531,9 @@

SCI_CLEARALL
Unless the document is read-only, this deletes all the text.

+

SCI_DELETERANGE(int pos, int deleteLength)
+ Deletes a range of text in the document.

+

SCI_CLEARDOCUMENTSTYLE
When wanting to completely restyle the document, for example after choosing a lexer, the SCI_CLEARDOCUMENTSTYLE can be used to clear all styling information and reset the @@ -533,6 +555,18 @@ The number of styling bits needed by the current lexer can be found with SCI_GETSTYLEBITSNEEDED.

+

SCI_RELEASEALLEXTENDEDSTYLES
+ SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles)
+ Extended styles are used for features like textual margins and annotations as well as internally by Scintilla. + They are outside the range 0..255 used for the styles bytes associated with document bytes. + These functions manage the use of extended styles to ensures that components cooperate in defining styles. + SCI_RELEASEALLEXTENDEDSTYLES releases any extended styles allocated by the container. + SCI_ALLOCATEEXTENDEDSTYLES allocates a range of style numbers after the byte style values and returns + the number of the first allocated style. + Ranges for margin and annotation styles should be allocated before calling + SCI_MARGINSETSTYLEOFFSET or + SCI_ANNOTATIONSETSTYLEOFFSET.

+

Sci_TextRange and Sci_CharacterRange
These structures are defined to be exactly the same shape as the Win32 TEXTRANGE and CHARRANGE, so that older code that treats Scintilla as a RichEdit will @@ -657,7 +691,8 @@ struct Sci_TextRange { Where n is 1 through 9 refers to the first through ninth tagged region when replacing. For example, if the search string was Fred\([1-9]\)XXX and the replace string was Sam\1YYY, when applied to Fred2XXX this - would generate Sam2YYY. + would generate Sam2YYY. + \0 refers to all of the matching text. @@ -854,7 +889,7 @@ struct Sci_TextToFind { text is a zero terminated string, otherwise length is the number of characters to use. The replacement string is formed from the text string with any sequences of \1 through \9 replaced by tagged matches from the most recent regular - expression search. + expression search. \0 is replaced with all the matched text from the most recent search. After replacement, the target range refers to the replacement text. The return value is the length of the replacement string.

@@ -899,8 +934,8 @@ struct Sci_TextToFind { pasting from the clipboard into the document, and clearing the document. SCI_CANPASTE returns non-zero if the document isn't read-only and if the selection doesn't contain protected text. If you need a "can copy" or "can cut", use - SCI_GETSELECTIONSTART()-SCI_GETSELECTIONEND(), which will be non-zero if you can - copy or cut to the clipboard.

+ SCI_GETSELECTIONEMPTY(), which will be zero if there are any non-empty + selection ranges implying that a copy or cut to the clipboard should work.

GTK+ does not really support SCI_CANPASTE and always returns TRUE unless the document is read-only.

@@ -1110,6 +1145,7 @@ struct Sci_TextToFind { onlyWordCharacters)
SCI_POSITIONBEFORE(int position)
SCI_POSITIONAFTER(int position)
+ SCI_COUNTCHARACTERS(int startPos, int endPos)
SCI_TEXTWIDTH(int styleNumber, const char *text)
SCI_TEXTHEIGHT(int line)
SCI_CHOOSECARETX
@@ -1311,7 +1347,7 @@ struct Sci_TextToFind {

SCI_GETLINESELSTARTPOSITION(int line)
SCI_GETLINESELENDPOSITION(int line)
Retrieve the position of the start and end of the selection at the given line with - INVALID_POSITION returned if no selection on this line.

+ INVALID_POSITION returned if no selection on this line.

SCI_MOVECARETINSIDEVIEW
If the caret is off the top or bottom of the view, it is moved to the nearest line that is @@ -1411,6 +1447,9 @@ struct Sci_TextToFind { If called with a position within a multi byte character will return the position of the start/end of that character.

+

SCI_COUNTCHARACTERS(int startPos, int endPos)
+ Returns the number of whole characters between two positions..

+

SCI_TEXTWIDTH(int styleNumber, const char *text)
This returns the pixel width of a string drawn in the given styleNumber which can be used, for example, to decide how wide to make the line number margin in order to display a @@ -1488,6 +1527,7 @@ struct Sci_TextToFind {
SCI_GETSELECTIONS
+ SCI_GETSELECTIONEMPTY
SCI_CLEARSELECTIONS
SCI_SETSELECTION(int caret, int anchor)
SCI_ADDSELECTION(int caret, int anchor)
@@ -1598,6 +1638,10 @@ struct Sci_TextToFind { SCI_GETSELECTIONS
Return the number of selections currently active.

+

+ SCI_GETSELECTIONEMPTY
+ Return 1 if every selected range is empty else 0.

+

SCI_CLEARSELECTIONS
Set a single empty selection at 0 as the only selection.

@@ -1689,6 +1733,7 @@ struct Sci_TextToFind {

Scrolling and automatic scrolling

SCI_LINESCROLL(int column, int line)
SCI_SCROLLCARET
+ SCI_SCROLLRANGE(int secondary, int primary)
SCI_SETXCARETPOLICY(int caretPolicy, int caretSlop)
SCI_SETYCARETPOLICY(int caretPolicy, int @@ -1725,6 +1770,14 @@ struct Sci_TextToFind { If the current position (this is the caret if there is no selection) is not visible, the view is scrolled to make it visible according to the current caret policy.

+

SCI_SCROLLRANGE(int secondary, int primary)
+ Scroll the argument positions and the range between them into view giving + priority to the primary position then the secondary position. + The behaviour is similar to
SCI_SCROLLCARET + with the primary position used instead of the caret. An effort is then made to ensure that the secondary + position and range between are also visible. + This may be used to make a search match visible.

+

SCI_SETXCARETPOLICY(int caretPolicy, int caretSlop)
SCI_SETYCARETPOLICY(int caretPolicy, int caretSlop)
These set the caret policy. The value of caretPolicy is a combination of @@ -2155,17 +2208,36 @@ struct Sci_TextToFind {

Line endings

-

Scintilla can interpret any of the three major line end conventions, Macintosh (\r), Unix - (\n) and CP/M / DOS / Windows (\r\n). When the user presses the Enter key, one of these line +

Scintilla can handle the major line end conventions and, depending on settings and + the current lexer also support additional Unicode line ends.

+ +

Scintilla can interpret any of the Macintosh (\r), Unix (\n) and Windows (\r\n) + line ends. + When the user presses the Enter key, one of these line end strings is inserted into the buffer. The default is \r\n in Windows and \n in Unix, but this can be changed with the SCI_SETEOLMODE message. You can also convert the entire document to one of these line endings with SCI_CONVERTEOLS. Finally, you can choose to display the line endings with SCI_SETVIEWEOL.

+ +
+

For the UTF-8 encoding, three additional Unicode line ends, + Next Line (NEL=U+0085), Line Separator (LS=U+2028), and Paragraph Separator (PS=U+2029) + may optionally be interpreted when Unicode line ends is turned on and the current lexer also supports + Unicode line ends.

+
+ SCI_SETEOLMODE(int eolMode)
SCI_GETEOLMODE
SCI_CONVERTEOLS(int eolMode)
SCI_SETVIEWEOL(bool visible)
SCI_GETVIEWEOL
+ +

SCI_SETEOLMODE(int eolMode)
@@ -2188,6 +2260,27 @@ struct Sci_TextToFind { (CR), (LF), or (CR)(LF). SCI_GETVIEWEOL returns the current state.

+
+ These features are provisional
+ +

SCI_GETLINEENDTYPESSUPPORTED
+ SCI_GETLINEENDTYPESSUPPORTED reports the different types of line ends supported + by the current lexer. This is a bit set although there is currently only a single choice + with either SC_LINE_END_TYPE_DEFAULT (0) or SC_LINE_END_TYPE_UNICODE (1). + These values are also used by the other messages concerned with Unicode line ends.

+ +

SCI_SETLINEENDTYPESALLOWED(int lineEndBitSet)
+ SCI_GETLINEENDTYPESALLOWED
+ By default, only the ASCII line ends are interpreted. Unicode line ends may be requested with + SCI_SETLINEENDTYPESALLOWED(SC_LINE_END_TYPE_UNICODE) + but this will be ineffective unless the lexer also allows you Unicode line ends. + SCI_GETLINEENDTYPESALLOWED returns the current state.

+ +

SCI_GETLINEENDTYPESACTIVE
+ SCI_GETLINEENDTYPESACTIVE reports the set of line ends currently interpreted + by Scintilla. It is SCI_GETLINEENDTYPESSUPPORTED & SCI_GETLINEENDTYPESALLOWED.

+
+

Styling

The styling messages allow you to assign styles to text. The standard Scintilla settings @@ -2389,9 +2482,15 @@ struct Sci_TextToFind { SCI_STYLESETSIZE(int styleNumber, int sizeInPoints)
SCI_STYLEGETSIZE(int styleNumber)
+ SCI_STYLESETSIZEFRACTIONAL(int styleNumber, int + sizeInHundredthPoints)
+ SCI_STYLEGETSIZEFRACTIONAL(int styleNumber)
SCI_STYLESETBOLD(int styleNumber, bool bold)
SCI_STYLEGETBOLD(int styleNumber)
+ SCI_STYLESETWEIGHT(int styleNumber, int + weight)
+ SCI_STYLEGETWEIGHT(int styleNumber)
SCI_STYLESETITALIC(int styleNumber, bool italic)
SCI_STYLEGETITALIC(int styleNumber)
@@ -2440,8 +2539,12 @@ struct Sci_TextToFind { SCI_STYLEGETFONT(int styleNumber, char *fontName)
SCI_STYLESETSIZE(int styleNumber, int sizeInPoints)
SCI_STYLEGETSIZE(int styleNumber)
+ SCI_STYLESETSIZEFRACTIONAL(int styleNumber, int sizeInHundredthPoints)
+ SCI_STYLEGETSIZEFRACTIONAL(int styleNumber)
SCI_STYLESETBOLD(int styleNumber, bool bold)
SCI_STYLEGETBOLD(int styleNumber)
+ SCI_STYLESETWEIGHT(int styleNumber, int weight)
+ SCI_STYLEGETWEIGHT(int styleNumber)
SCI_STYLESETITALIC(int styleNumber, bool italic)
SCI_STYLEGETITALIC(int styleNumber)
These messages (plus fontName
is a zero terminated string holding the name of a font. Under Windows, only the first 32 characters of the name are used and the name is not case sensitive. For internal caching, Scintilla tracks fonts by name and does care about the casing of font names, - so please be consistent. On GTK+ 2.x, either GDK or Pango can be used to display text. - Pango antialiases text, works well with Unicode and is better supported in recent versions of GTK+ - but GDK is faster. - Prepend a '!' character to the font name to use Pango.

+ so please be consistent. On GTK+, Pango is used to display text.

+

Sizes can be set to a whole number of points with SCI_STYLESETSIZE + or to a fractional point size in hundredths of a point with SCI_STYLESETSIZEFRACTIONAL + by multiplying the size by 100 (SC_FONT_SIZE_MULTIPLIER). + For example, a text size of 9.4 points is set with SCI_STYLESETSIZEFRACTIONAL(<style>, 940). +

+

The weight or boldness of a font can be set with SCI_STYLESETBOLD + or SCI_STYLESETWEIGHT. The weight is a number between 1 and 999 with 1 being very light + and 999 very heavy. While any value can be used, fonts often only support between 2 and 4 weights with three weights + being common enough to have symbolic names: + SC_WEIGHT_NORMAL (400), + SC_WEIGHT_SEMIBOLD (600), and + SC_WEIGHT_BOLD (700). + The SCI_STYLESETBOLD message takes a boolean argument with 0 choosing SC_WEIGHT_NORMAL + and 1 SC_WEIGHT_BOLD. +

SCI_STYLESETUNDERLINE(int styleNumber, bool underline)
@@ -2560,6 +2675,8 @@ struct Sci_TextToFind {
SCI_GETCARETLINEBACK
SCI_SETCARETLINEBACKALPHA(int alpha)
SCI_GETCARETLINEBACKALPHA
+ SCI_SETCARETLINEVISIBLEALWAYS(bool alwaysVisible)
+ SCI_GETCARETLINEVISIBLEALWAYS
SCI_SETCARETPERIOD(int milliseconds)
SCI_GETCARETPERIOD
SCI_SETCARETSTYLE(int style)
@@ -2624,6 +2741,12 @@ struct Sci_TextToFind { the caret line is drawn after all other features so will affect the colour of all other features.

+

SCI_SETCARETLINEVISIBLEALWAYS(bool alwaysVisible)
+ SCI_GETCARETLINEVISIBLEALWAYS
+ Choose to make the caret line always visible even when the window is not in focus. + Default behaviour SCI_SETCARETLINEVISIBLEALWAYS(false) the caret line is only visible when the window is in focus. +

+

SCI_SETCARETPERIOD(int milliseconds)
SCI_GETCARETPERIOD
The rate at which the caret blinks can be set with SCI_SETCARETPERIOD which @@ -2703,9 +2826,12 @@ struct Sci_TextToFind {

Margins

-

There may be up to five margins to the left of the text display, plus a gap either side of - the text. Each margin can be set to display either symbols or line numbers with SCI_SETMARGINTYPEN. The markers +

There may be up to five margins, numbered 0 to SC_MAX_MARGIN (4) + to the left of the text display, plus a gap either side of + the text. Each margin can be set to display only symbols, line numbers, or text with SCI_SETMARGINTYPEN. + Textual margins may also display symbols. + The markers that can be displayed in each margin are set with SCI_SETMARGINMASKN. Any markers not associated with a visible margin will be displayed as changes in background colour in the text. A width in @@ -2858,6 +2984,9 @@ struct Sci_TextToFind { SC_MOD_CHANGEMARGIN notification to be sent.

+

+ Only some style attributes are active in text margins: font, size/sizeFractional, bold/weight, italics, fore, back, and characterSet. +

SCI_MARGINSETSTYLEOFFSET(int style)
SCI_MARGINGETSTYLEOFFSET
@@ -2866,13 +2995,17 @@ struct Sci_TextToFind { 256 upto 511 so they do not overlap styles set by lexers. Each style number set with SCI_MARGINSETSTYLE or SCI_MARGINSETSTYLES has the offset added before looking up the style.

+

+ Always call SCI_ALLOCATEEXTENDEDSTYLES + before SCI_MARGINSETSTYLEOFFSET and use the result as the argument to SCI_MARGINSETSTYLEOFFSET. +

SCI_SETMARGINOPTIONS(int marginOptions)
SCI_GETMARGINOPTIONS
- Define margin options by enabling appropriate bit flags. At the moment, only one flag is available - SC_MARGINOPTION_SUBLINESELECT=1, which controls how wrapped lines are selected when clicking - on margin in front of them. If SC_MARGINOPTION_SUBLINESELECT is set only sub line of wrapped - line is selected, otherwise whole wrapped line is selected. Margin options are set to + Define margin options by enabling appropriate bit flags. At the moment, only one flag is available + SC_MARGINOPTION_SUBLINESELECT=1, which controls how wrapped lines are selected when clicking + on margin in front of them. If SC_MARGINOPTION_SUBLINESELECT is set only sub line of wrapped + line is selected, otherwise whole wrapped line is selected. Margin options are set to SC_MARGINOPTION_NONE=0 by default.

@@ -2882,6 +3015,9 @@ struct Sci_TextToFind { An annotation may consist of multiple lines separated by '\n'. Annotations can be used to display an assembler version of code for debugging or to show diagnostic messages inline or to line up different versions of text in a merge tool.

+

Annotations count as display lines for the methods + SCI_VISIBLEFROMDOCLINE and + SCI_DOCLINEFROMVISIBLE

Annotations used for inline diagnostics:

Annotations used for inline diagnostics

@@ -2925,6 +3061,9 @@ struct Sci_TextToFind { All the lines can be cleared of annotations with SCI_ANNOTATIONCLEARALL which is equivalent to clearing each line (setting to 0) and then deleting other memory used for this feature.

+

+ Only some style attributes are active in annotations: font, size/sizeFractional, bold/weight, italics, fore, back, and characterSet. +

SCI_ANNOTATIONSETVISIBLE(int visible)
SCI_ANNOTATIONGETVISIBLE
@@ -2969,6 +3108,10 @@ struct Sci_TextToFind { Each style number set with SCI_ANNOTATIONSETSTYLE or SCI_ANNOTATIONSETSTYLES has the offset added before looking up the style.

+

+ Always call SCI_ALLOCATEEXTENDEDSTYLES + before SCI_ANNOTATIONSETSTYLEOFFSET and use the result as the argument to SCI_ANNOTATIONSETSTYLEOFFSET. +

Other settings

SCI_SETUSEPALETTE(bool @@ -2978,41 +3121,26 @@ struct Sci_TextToFind { SCI_GETBUFFEREDDRAW
SCI_SETTWOPHASEDRAW(bool twoPhase)
SCI_GETTWOPHASEDRAW
+ SCI_SETTECHNOLOGY(int technology)
+ SCI_GETTECHNOLOGY
SCI_SETFONTQUALITY(int fontQuality)
SCI_GETFONTQUALITY
SCI_SETCODEPAGE(int codePage)
SCI_GETCODEPAGE
SCI_SETKEYSUNICODE(bool keysUnicode)
SCI_GETKEYSUNICODE
- SCI_SETWORDCHARS(<unused>, const char - *chars)
- SCI_SETWHITESPACECHARS(<unused>, const char - *chars)
+ SCI_SETWORDCHARS(<unused>, const char *characters)
+ SCI_GETWORDCHARS(<unused>, char *characters)
+ SCI_SETWHITESPACECHARS(<unused>, const char *characters)
+ SCI_GETWHITESPACECHARS(<unused>, char *characters)
+ SCI_SETPUNCTUATIONCHARS(<unused>, const char *characters)
+ SCI_GETPUNCTUATIONCHARS(<unused>, char *characters)
SCI_SETCHARSDEFAULT
SCI_GRABFOCUS
SCI_SETFOCUS(bool focus)
SCI_GETFOCUS
-

SCI_SETUSEPALETTE(bool allowPaletteUse)
- SCI_GETUSEPALETTE
- On 8 bit displays, which can only display a maximum of 256 colours, the graphics environment - mediates between the colour needs of applications through the use of palettes. On GTK+, - Scintilla always uses a palette.

- -

On Windows, there are some problems with visual flashing when switching between applications - with palettes and it is also necessary for the application containing the Scintilla control to - forward some messages to Scintilla for its palette code to work. Because of this, by default, - the palette is not used and the application must tell Scintilla to use one. If Scintilla is not - using a palette, it will only display in those colours already available, which are often the - 20 Windows system colours.

- -

To see an example of how to enable palette support in Scintilla, search the text of SciTE - for WM_PALETTECHANGED, WM_QUERYNEWPALETTE and - SCI_SETUSEPALETTE. The Windows messages to forward are:
- WM_SYSCOLORCHANGE, WM_PALETTECHANGED, - WM_QUERYNEWPALETTE (should return TRUE).

-

To forward a message (WM_XXXX, WPARAM, LPARAM) to Scintilla, you can use SendMessage(hScintilla, WM_XXXX, WPARAM, LPARAM) where hScintilla is the handle to the Scintilla window you created as your editor.

@@ -3041,6 +3169,15 @@ struct Sci_TextToFind { transparent mode. Two phase drawing may flicker more than single phase unless buffered drawing is on. The default is for drawing to be two phase.

+

SCI_SETTECHNOLOGY(int technology)
+ SCI_GETTECHNOLOGY
+ The technology property allows choosing between different drawing APIs and options. + On most platforms, the only choice is SC_TECHNOLOGY_DEFAULT (0). + On Windows Vista or later, SC_TECHNOLOGY_DIRECTWRITE (1) + can be chosen to use the Direct2D and DirectWrite APIs for higher quality antialiased drawing. + Since Direct2D buffers drawing, Scintilla's buffering can be turned off with + SCI_SETBUFFEREDDRAW(0).

+

SCI_SETFONTQUALITY(int fontQuality)
SCI_GETFONTQUALITY
Manage font quality (antialiasing method). Currently, the following values are available on Windows: @@ -3079,7 +3216,7 @@ struct Sci_TextToFind { or narrow character window with character messages treated as Unicode when wide and as 8 bit otherwise. Set this property to always treat as Unicode. This option is needed for Delphi.

-

SCI_SETWORDCHARS(<unused>, const char *chars)
+

SCI_SETWORDCHARS(<unused>, const char *characters)
Scintilla has several functions that operate on words, which are defined to be contiguous sequences of characters from a particular set of characters. This message defines which characters are members of that set. The character sets are set to default values before processing this @@ -3088,13 +3225,28 @@ struct Sci_TextToFind { use:
SCI_SETWORDCHARS(0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

-

SCI_SETWHITESPACECHARS(<unused>, const char *chars)
+

SCI_GETWORDCHARS(<unused>, char *characters)
+ This fills the characters parameter with all the characters included in words. + The characters parameter must be large enough to hold all of the characters. + If the characters parameter is 0 then the length that should be allocated + to store the entire set is returned.

+ +

SCI_SETWHITESPACECHARS(<unused>, const char *characters)
+ SCI_GETWHITESPACECHARS(<unused>, char *characters)
Similar to SCI_SETWORDCHARS, this message allows the user to define which chars Scintilla considers as whitespace. Setting the whitespace chars allows the user to fine-tune Scintilla's behaviour doing such things as moving the cursor to the start or end of a word; for example, by defining punctuation chars as whitespace, they will be skipped over when the user presses ctrl+left or ctrl+right. This function should be called after SCI_SETWORDCHARS as it will - reset the whitespace characters to the default set.

+ reset the whitespace characters to the default set. + SCI_GETWHITESPACECHARS behaves similarly to SCI_GETWORDCHARS.

+ +

SCI_SETPUNCTUATIONCHARS(<unused>, const char *characters)
+ SCI_GETPUNCTUATIONCHARS(<unused>, char *characters)
+ Similar to SCI_SETWORDCHARS and SCI_SETWHITESPACECHARS, this message + allows the user to define which chars Scintilla considers as punctuation. + SCI_GETPUNCTUATIONCHARS behaves similarly to SCI_GETWORDCHARS.

+

SCI_SETCHARSDEFAULT
Use the default sets of word and whitespace characters. This sets whitespace to space, tab and other characters with codes less than 0x20, with word characters set to alphanumeric and '_'. @@ -3303,6 +3455,11 @@ struct Sci_TextToFind { markerSymbols)
SCI_MARKERDEFINEPIXMAP(int markerNumber, const char *xpm)
+ SCI_RGBAIMAGESETWIDTH(int width)
+ SCI_RGBAIMAGESETHEIGHT(int height)
+ SCI_RGBAIMAGESETSCALE(int scalePercent)
+ SCI_MARKERDEFINERGBAIMAGE(int markerNumber, + const char *pixels)
SCI_MARKERSYMBOLDEFINED(int markerNumber)
SCI_MARKERSETFORE(int markerNumber, int @@ -3483,16 +3640,28 @@ struct Sci_TextToFind {

SCI_MARKERDEFINEPIXMAP(int markerNumber, const char *xpm)
- Markers can be set to pixmaps with this message. The XPM format is used for the pixmap and it - is limited to pixmaps that use one character per pixel with no named colours. - The transparent colour may be named 'None'. - The data should be null terminated. - Pixmaps use the SC_MARK_PIXMAP marker symbol. You can find descriptions of - the XPM format
from here.

+ Markers can be set to pixmaps with this message. The + XPM format is used for the pixmap. + Pixmaps use the SC_MARK_PIXMAP marker symbol.

+ +

+ SCI_RGBAIMAGESETWIDTH(int width)
+ SCI_RGBAIMAGESETHEIGHT(int height)
+ SCI_RGBAIMAGESETSCALE(int scalePercent)
+ SCI_MARKERDEFINERGBAIMAGE(int markerNumber, const char *pixels)
+ Markers can be set to translucent pixmaps with this message. The + RGBA format is used for the pixmap. + The width and height must previously been set with the SCI_RGBAIMAGESETWIDTH and + SCI_RGBAIMAGESETHEIGHT messages.

+

A scale factor in percent may be set with SCI_RGBAIMAGESETSCALE. This is useful on OS X with + a retina display where each display unit is 2 pixels: use a factor of 200 so that each image pixel is dsplayed using a screen pixel. + The default scale, 100, will stretch each image pixel to cover 4 screen pixels on a retina display.

+

Pixmaps use the SC_MARK_RGBAIMAGE marker symbol.

SCI_MARKERSYMBOLDEFINED(int markerNumber)
Returns the symbol defined for a markerNumber with SCI_MARKERDEFINE - or SC_MARK_PIXMAP if defined with SCI_MARKERDEFINEPIXMAP.

+ or SC_MARK_PIXMAP if defined with SCI_MARKERDEFINEPIXMAP + or SC_MARK_RGBAIMAGE if defined with SCI_MARKERDEFINERGBAIMAGE.

SCI_MARKERSETFORE(int markerNumber, int colour)
@@ -3595,6 +3764,21 @@ struct Sci_TextToFind { SCI_INDICGETOUTLINEALPHA(int indicatorNumber)
SCI_INDICSETUNDER(int indicatorNumber, bool under)
SCI_INDICGETUNDER(int indicatorNumber)
+ + SCI_SETINDICATORCURRENT(int indicator)
+ SCI_GETINDICATORCURRENT
+ SCI_SETINDICATORVALUE(int value)
+ SCI_GETINDICATORVALUE
+ SCI_INDICATORFILLRANGE(int position, int fillLength)
+ SCI_INDICATORCLEARRANGE(int position, int clearLength)
+ SCI_INDICATORALLONFOR(int position)
+ SCI_INDICATORVALUEAT(int indicator, int position)
+ SCI_INDICATORSTART(int indicator, int position)
+ SCI_INDICATOREND(int indicator, int position)
+ + SCI_FINDINDICATORSHOW(int start, int end)
+ SCI_FINDINDICATORFLASH(int start, int end)
+ SCI_FINDINDICATORHIDE

SCI_INDICSETSTYLE(int indicatorNumber, int @@ -3720,6 +3904,40 @@ struct Sci_TextToFind { so will fit under small fonts. + + INDIC_DOTBOX + + 12 + + A dotted rectangle around the text using translucent drawing. + Translucency alternates between the alpha and outline alpha settings with the top-left pixel using the alpha setting. + SCI_INDICSETALPHA and + SCI_INDICSETOUTLINEALPHA + control the alpha transparency values. The default values are 30 for alpha and 50 for outline alpha. + To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels. + + + + INDIC_SQUIGGLEPIXMAP + + 13 + + A version of INDIC_SQUIGGLE that draws using a pixmap instead of + as a series of line segments for performance. + Measured to be between 3 and 6 times faster than INDIC_SQUIGGLE on GTK+. + Apperance will not be as good as INDIC_SQUIGGLE on OS X in HiDPI mode. + + + + INDIC_COMPOSITIONTHICK + + 14 + + A 2-pixel thick underline located at the bottom of the line to try to avoid touching the character base. + Each side is inset 1 pixel so that different indicators in this style covering a range appear isolated. + This is similar to an appearance used for Asian language input composition. + + @@ -3802,6 +4020,29 @@ struct Sci_TextToFind { Can be used to iterate through the document to discover all the indicator positions.

+

OS X Find Indicator

+ +

On OS X search matches are highlighted with an animated gold rounded rectangle. + The indicator shows, then briefly grows 25% and shrinks to the original size to draw the user's attention. + While this feature is currently only implemented on OS X, it may be implemented on other platforms + in the future.

+ +

SCI_FINDINDICATORSHOW(int start, int end)
+ SCI_FINDINDICATORFLASH(int start, int end)
+ These two messages show and animate the find indicator. The indicator remains visible with + SCI_FINDINDICATORSHOW and fades out after showing for half a second with + SCI_FINDINDICATORFLASH. + SCI_FINDINDICATORSHOW behaves similarly to the OS X TextEdit and Safari applications + and is best suited to editing documentation where the search target is often a word. + SCI_FINDINDICATORFLASH is similar to Xcode and is suited to editing source code + where the match will often be located next to operators which would otherwise be hidden under the indicator's + padding. +

+ +

SCI_FINDINDICATORHIDE
+ This message hides the find indicator. +

+

Style Byte Indicators (deprecated)

By default, Scintilla organizes the style byte associated with each text byte as 5 bits of style information (for 32 styles) and 3 bits of indicator information for 3 independent @@ -3877,12 +4118,17 @@ struct Sci_TextToFind { SCI_AUTOCSETIGNORECASE(bool ignoreCase)
SCI_AUTOCGETIGNORECASE
+ SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR(int behaviour)
+ SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR
+ SCI_AUTOCSETORDER(int order)
+ SCI_AUTOCGETORDER
SCI_AUTOCSETAUTOHIDE(bool autoHide)
SCI_AUTOCGETAUTOHIDE
SCI_AUTOCSETDROPRESTOFWORD(bool dropRestOfWord)
SCI_AUTOCGETDROPRESTOFWORD
- SCI_REGISTERIMAGE
+ SCI_REGISTERIMAGE(int type, const char *xpmData)
+ SCI_REGISTERRGBAIMAGE(int type, const char *pixels)
SCI_CLEARREGISTEREDIMAGES
SCI_AUTOCSETTYPESEPARATOR(char separatorCharacter)
SCI_AUTOCGETTYPESEPARATOR
@@ -3900,10 +4146,13 @@ struct Sci_TextToFind { and SCI_AUTOCGETSEPARATOR.

-

The list of words should be in sorted order. If set to ignore case mode with SCI_AUTOCSETIGNORECASE, then +

With default settings, the list of words should be in sorted order. + If set to ignore case mode with SCI_AUTOCSETIGNORECASE, then strings are matched after being converted to upper case. One result of this is that the list should be sorted with the punctuation characters '[', '\', ']', '^', '_', and '`' sorted after - letters.

+ letters. + Alternative handling of list order may be specified with SCI_AUTOCSETORDER +

SCI_AUTOCCANCEL
This message cancels any displayed autocompletion list. When in autocompletion mode, the list @@ -3961,7 +4210,7 @@ struct Sci_TextToFind { SCI_AUTOCGETCANCELATSTART
The default behavior is for the list to be cancelled if the caret moves to the location it was at when the list was displayed. By calling this message with a false argument, - the list is not cancelled until the caret moves before the first character of the word being + the list is not cancelled until the caret moves at least one character before the word being completed.

SCI_AUTOCSETFILLUPS(<unused>, const char *chars)
@@ -3981,6 +4230,27 @@ struct Sci_TextToFind { By default, matching of characters to list members is case sensitive. These messages let you set and get case sensitivity.

+

SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR(int behaviour)
+ SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR
+ When autocompletion is set to ignore case (SCI_AUTOCSETIGNORECASE), by default it will + nonetheless select the first list member that matches in a case sensitive way to entered characters. + This corresponds to a behaviour property of SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE (0). + If you want autocompletion to ignore case at all, choose SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE (1).

+ +

SCI_AUTOCSETORDER(int order)
+ SCI_AUTOCGETORDER
+ The default setting SC_ORDER_PRESORTED (0) requires that the list be provided in alphabetical sorted order. +

+

Sorting the list can be done by Scintilla instead of the application with SC_ORDER_PERFORMSORT (1). + This will take additional time. +

+

Applications that wish to prioritize some values and show the list in order of priority instead + of alphabetical order can use SC_ORDER_CUSTOM (2). + This requires extra processing in SCI_AUTOCSHOW to create a sorted index. +

+

Setting the order should be done before calling SCI_AUTOCSHOW. +

+

SCI_AUTOCSETAUTOHIDE(bool autoHide)
SCI_AUTOCGETAUTOHIDE
By default, the list is cancelled if there are no viable matches (the user has typed @@ -3995,6 +4265,7 @@ struct Sci_TextToFind {

SCI_REGISTERIMAGE(int type, const char *xpmData)
+ SCI_REGISTERRGBAIMAGE(int type, const char *pixels)
SCI_CLEARREGISTEREDIMAGES
SCI_AUTOCSETTYPESEPARATOR(char separatorCharacter)
SCI_AUTOCGETTYPESEPARATOR
@@ -4002,8 +4273,11 @@ struct Sci_TextToFind { Autocompletion list items may display an image as well as text. Each image is first registered with an integer type. Then this integer is included in the text of the list separated by a '?' from the text. For example, "fclose?2 fopen" displays image 2 before the string "fclose" and no image before "fopen". - The images are in XPM format as is described for - SCI_MARKERDEFINEPIXMAP + The images are in either the XPM format (SCI_REGISTERIMAGE) or + RGBA format (SCI_REGISTERRGBAIMAGE). + For SCI_REGISTERRGBAIMAGE the width and height must previously been set with + the SCI_RGBAIMAGESETWIDTH and + SCI_RGBAIMAGESETHEIGHT messages. The set of registered images can be cleared with SCI_CLEARREGISTEREDIMAGES and the '?' separator changed with SCI_AUTOCSETTYPESEPARATOR.

@@ -4095,6 +4369,7 @@ struct Sci_TextToFind { SCI_CALLTIPSETFORE(int colour)
SCI_CALLTIPSETFOREHLT(int colour)
SCI_CALLTIPUSESTYLE(int tabsize)
+ SCI_CALLTIPSETPOSITION(bool above)

SCI_CALLTIPSHOW(int posStart, const char *definition)
@@ -4158,6 +4433,10 @@ struct Sci_TextToFind { less than 1, Tab characters are not treated specially. Once this call has been used, the call tip foreground and background colours are also taken from the style.

+

SCI_CALLTIPSETPOSITION(bool above)
+ By default the calltip is displayed below the text, setting above to true + (1) will display it above the text.

+

Keyboard commands

@@ -4249,7 +4528,7 @@ struct Sci_TextToFind { SCI_HOMEEXTEND - [SCI_HOMERECTEXTEND] + SCI_HOMERECTEXTEND @@ -4274,6 +4553,10 @@ struct Sci_TextToFind { SCI_VCHOMEWRAP SCI_VCHOMEWRAPEXTEND + + SCI_VCHOMEDISPLAY + + SCI_VCHOMEDISPLAYEXTEND @@ -4397,6 +4680,12 @@ struct Sci_TextToFind { SCI_MOVESELECTEDLINESDOWN + + + SCI_SCROLLTOSTART + + SCI_SCROLLTOEND + @@ -4409,7 +4698,7 @@ struct Sci_TextToFind { capitalisation (aCamelCaseIdentifier) or underscores (an_under_bar_ident).

The SCI_HOME* commands move the caret to the start of the line, while the - SCI_VCHOME*commands move the caret to the first non-blank character of the line + SCI_VCHOME* commands move the caret to the first non-blank character of the line (ie. just after the indentation) unless it is already there; in this case, it acts as SCI_HOME*.

The SCI_[HOME|LINEEND]DISPLAY* commands are used when in line wrap mode to @@ -4423,6 +4712,12 @@ struct Sci_TextToFind { as appropriate for SCI_[[VC]HOME|LINEEND]*.

+

The SCI_SCROLLTO[START|END] commands scroll the document to the start + or end without changing the selection. These commands match OS X platform conventions for the behaviour of the + home and end keys. Scintilla can be made to match OS X applications + by binding the home and end keys to these commands. +

+

Key bindings

There is a default binding of keys to commands that is defined in the Scintilla source in @@ -4456,7 +4751,7 @@ struct Sci_TextToFind {

The modifiers are a combination of zero or more of SCMOD_ALT, SCMOD_CTRL, SCMOD_SHIFT, and SCMOD_META. - On OS X, the Command key is mapped to SCMOD_CTRL and the Control key to + On OS X, the Command key is mapped to SCMOD_CTRL and the Control key to SCMOD_META. If you are building a table, you might want to use SCMOD_NORM, which has the value 0, to mean no modifiers.

@@ -4501,10 +4796,15 @@ struct Sci_TextToFind {

Printing

-

On Windows SCI_FORMATRANGE can be used to draw the text onto a display context - which can include a printer display context. Printed output shows text styling as on the +

SCI_FORMATRANGE can be used to draw the text onto a display surface + which can include a printer display surface. Printed output shows text styling as on the screen, but it hides all margins except a line number margin. All special marker effects are removed and the selection and caret are hidden.

+ +

Different platforms use different display surface ID types to print on. On Windows, these are + HDCs., on GTK+ 3.x cairo_t *, + and on Cocoa CGContextRef is used.

+ SCI_FORMATRANGE(bool bDraw, Sci_RangeToFormat *pfr)
SCI_SETPRINTMAGNIFICATION(int @@ -4517,7 +4817,7 @@ struct Sci_TextToFind {

SCI_FORMATRANGE(bool bDraw, Sci_RangeToFormat *pfr)
- This call allows Windows users to render a range of text into a device context. If you use + This call renders a range of text into a device context. If you use this for printing, you will probably want to arrange a page header and footer; Scintilla does not do this for you. See SciTEWin::Print() in SciTEWinDlg.cxx for an example. Each use of this message renders a range of text into a rectangular area and returns @@ -4530,15 +4830,15 @@ struct Sci_TextToFind { struct Sci_Rectangle { int left; int top; int right; int bottom; }; struct Sci_RangeToFormat { - Sci_SurfaceID hdc; // The HDC (device context) we print to - Sci_SurfaceID hdcTarget; // The HDC we use for measuring (may be same as hdc) + Sci_SurfaceID hdc; // The Surface ID we print to + Sci_SurfaceID hdcTarget; // The Surface ID we use for measuring (may be same as hdc) Sci_Rectangle rc; // Rectangle in which to print Sci_Rectangle rcPage; // Physically printable page size Sci_CharacterRange chrg; // Range of characters to print }; -

hdc and hdcTarget should both be set to the device context handle +

On Windows, hdc and hdcTarget should both be set to the device context handle of the output device (usually a printer). If you print to a metafile these will not be the same as Windows metafiles (unlike extended metafiles) do not implement the full API for returning information. In this case, set hdcTarget to the screen DC.
@@ -4549,6 +4849,17 @@ struct Sci_RangeToFormat { chrg.cpMin and chrg.cpMax define the start position and maximum position of characters to output. All of each line within this character range is drawn.

+

On Cocoa, the surface IDs for printing (bDraw=1) should be the graphics port of the current context + ((CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]) when the view's drawRect method is called. + The Surface IDs are not really used for measurement (bDraw=0) but can be set + to a bitmap context (created with CGBitmapContextCreate) to avoid runtime warnings.

+ +

On GTK+, the surface IDs to use can be found from the printing context with + gtk_print_context_get_cairo_context(context).

+ + chrg.cpMin and chrg.cpMax define the start position and maximum + position of characters to output. All of each line within this character range is drawn.

+

When printing, the most tedious part is always working out what the margins should be to allow for the non-printable area of the paper and printing a header and footer. If you look at the printing code in SciTE, you will find that most of it is taken up with this. The loop that @@ -4644,6 +4955,8 @@ struct Sci_RangeToFormat { SCI_GETDIRECTFUNCTION
SCI_GETDIRECTPOINTER
SCI_GETCHARACTERPOINTER
+ SCI_GETRANGEPOINTER(int position, int rangeLength)
+ SCI_GETGAPPOSITION

On Windows, the message-passing scheme used to communicate between the container and @@ -4689,8 +5002,13 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ pass in the direct pointer associated with the target window.

SCI_GETCHARACTERPOINTER
- Move the gap within Scintilla so that the text of the document is stored consecutively - and ensure there is a NUL character after the text, then return a pointer to the first character. + SCI_GETRANGEPOINTER(int position, int rangeLength)
+ SCI_GETGAPPOSITION
+ Grant temporary direct read-only access to the memory used by Scintilla to store + the document.

+

SCI_GETCHARACTERPOINTER moves the gap within Scintilla so that the + text of the document is stored consecutively + and ensure there is a NUL character after the text, then returns a pointer to the first character. Applications may then pass this to a function that accepts a character pointer such as a regular expression search or a parser. The pointer should not be written to as that may desynchronize the internal state of Scintilla.

@@ -4707,6 +5025,15 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ each replacement then the operation will become O(n^2) rather than O(n). Instead, all matches should be found and remembered, then all the replacements performed.

+

SCI_GETRANGEPOINTER provides direct access to just the + range requested. The gap is not moved unless it is within the requested range so this call + can be faster than SCI_GETCHARACTERPOINTER. + This can be used by application code that is able to act on blocks of text or ranges of lines.

+ +

SCI_GETGAPPOSITION returns the current gap position. + This is a hint that applications can use to avoid calling SCI_GETRANGEPOINTER + with a range that contains the gap and consequent costs of moving the gap.

+

Multiple views

A Scintilla window and the document that it displays are separate entities. When you create @@ -4771,6 +5098,59 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ world spinning in its orbit you must balance each call to SCI_CREATEDOCUMENT or SCI_ADDREFDOCUMENT with a call to SCI_RELEASEDOCUMENT.

+

Background loading and saving

+ +

To ensure a responsive user interface, applications may decide to load and save documents using a separate thread + from the user interface.

+ +

Loading in the background

+ +

An application can load all of a file into a buffer it allocates on a background thread and then add the data in that buffer + into a Scintilla document on the user interface thread. That technique uses extra memory to store a complete copy of the + file and also means that the time that Scintilla takes to perform initial line end discovery blocks the user interface.

+ +

To avoid these issues, a loader object may be created and used to load the file. The loader object supports the ILoader interface.

+ +

SCI_CREATELOADER(int bytes)
+ Create an object that supports the ILoader interface which can be used to load data and then + be turned into a Scintilla document object for attachment to a view object. + The bytes argument determines the initial memory allocation for the document as it is more efficient + to allocate once rather than rely on the buffer growing as data is added. + If SCI_CREATELOADER fails then 0 is returned.

+ +

ILoader

+ +
+class ILoader {
+public:
+        virtual int SCI_METHOD Release() = 0;
+        // Returns a status code from SC_STATUS_*
+        virtual int SCI_METHOD AddData(char *data, int length) = 0;
+        virtual void * SCI_METHOD ConvertToDocument() = 0;
+};
+
+ +

The application should call the AddData method with each block of data read from the file. + AddData will return SC_STATUS_OK unless a failure, such as memory exhaustion occurs. + If a failure occurs in AddData or in a file reading call then loading can be abandoned and the loader released with + the Release call. + When the whole file has been read, the ConvertToDocument method should be called to produce a Scintilla + document pointer which can be used in the same way as a document pointer returned from + SCI_CREATEDOCUMENT. + There is no need to call Release after ConvertToDocument.

+ +

Saving in the background

+ +

An application that wants to save in the background should lock the document with SCI_SETREADONLY(1) + to prevent modifications and retrieve a pointer to the unified document contents with + SCI_GETCHARACTERPOINTER. + The buffer of a locked document will not move so the pointer is valid until the application calls SCI_SETREADONLY(0).

+ +

If the user tries to performs a modification while the document is locked then a SCN_MODIFYATTEMPTRO notification is sent to the application. + The application may then decide to ignore the modification or to terminate the background saving thread and reenable + modification before returning from the notification.

+

Folding

The fundamental operation in folding is making lines invisible or visible. Line visibility @@ -4795,8 +5175,11 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ SCI_SHOWLINES(int lineStart, int lineEnd)
SCI_HIDELINES(int lineStart, int lineEnd)
SCI_GETLINEVISIBLE(int line)
+ SCI_GETALLLINESVISIBLE
SCI_SETFOLDLEVEL(int line, int level)
SCI_GETFOLDLEVEL(int line)
+ SCI_SETAUTOMATICFOLD(int automaticFold)
+ SCI_GETAUTOMATICFOLD
SCI_SETFOLDFLAGS(int flags)
SCI_GETLASTCHILD(int line, int level)
SCI_GETFOLDPARENT(int line)
@@ -4805,22 +5188,29 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ SCI_GETFOLDEXPANDED(int line)
SCI_CONTRACTEDFOLDNEXT(int lineStart)
SCI_TOGGLEFOLD(int line)
+ SCI_FOLDLINE(int line, int action)
+ SCI_FOLDCHILDREN(int line, int action)
+ SCI_FOLDALL(int action)
+ SCI_EXPANDCHILDREN(int line, int level)
SCI_ENSUREVISIBLE(int line)
SCI_ENSUREVISIBLEENFORCEPOLICY(int line)

SCI_VISIBLEFROMDOCLINE(int docLine)
- When some lines are folded, then a particular line in the document may be displayed at a - different position to its document position. If no lines are folded, this message returns + When some lines are hidden and/or annotations are displayed, then a particular line in the + document may be displayed at a + different position to its document position. If no lines are hidden and there are no annotations, + this message returns docLine. Otherwise, this returns the display line (counting the very first visible line as 0). The display line of an invisible line is the same as the previous visible line. The - display line number of the first line in the document is 0. If there is folding and + display line number of the first line in the document is 0. If lines are hidden and docLine is outside the range of lines in the document, the return value is -1. Lines can occupy more than one display line if they wrap.

SCI_DOCLINEFROMVISIBLE(int displayLine)
- When some lines are hidden, then a particular line in the document may be displayed at a + When some lines are hidden and/or annotations are displayed, then a particular line in the + document may be displayed at a different position to its document position. This message returns the document line number that corresponds to a display line (counting the display line of the first line in the document as 0). If displayLine is less than or equal to 0, the result is 0. If @@ -4830,9 +5220,14 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){

SCI_SHOWLINES(int lineStart, int lineEnd)
SCI_HIDELINES(int lineStart, int lineEnd)
SCI_GETLINEVISIBLE(int line)
+ SCI_GETALLLINESVISIBLE
The first two messages mark a range of lines as visible or invisible and then redraw the - display. The third message reports on the visible state of a line and returns 1 if it is - visible and 0 if it is not visible. These messages have no effect on fold levels or fold + display. + SCI_GETLINEVISIBLE reports on the visible state of a line and returns 1 if it is + visible and 0 if it is not visible. + SCI_GETALLLINESVISIBLE returns 1 if all lines are visible and 0 + if some lines are hidden. + These messages have no effect on fold levels or fold flags. The first line can not be hidden.

SCI_SETFOLDLEVEL(int line, int level)
@@ -4954,6 +5349,102 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ until you had finished. See SciTEBase::FoldAll() and SciTEBase::Expand() for examples of the use of these messages.

+

SCI_FOLDLINE(int line, int action)
+ SCI_FOLDCHILDREN(int line, int action)
+ SCI_FOLDALL(int action)
+ These messages provide a higher-level approach to folding instead of setting expanded flags and showing + or hiding individual lines.

+

An individual fold can be contracted/expanded/toggled with SCI_FOLDLINE. + To affect all child folds as well call SCI_FOLDCHILDREN.

+

To affect the entire document call SCI_FOLDALL. With SC_FOLDACTION_TOGGLE + the first fold header in the document is examined to decide whether to expand or contract. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolValueEffect
SC_FOLDACTION_CONTRACT0Contract.
SC_FOLDACTION_EXPAND1Expand.
SC_FOLDACTION_TOGGLE2Toggle between contracted and expanded.
+

+ +

SCI_EXPANDCHILDREN(int line, int level)
+ This is used to respond to a change to a line causing its fold level or whether it is a header to change, + perhaps when adding or removing a '{'.

+

By the time the container has received the notification that the line has changed, + the fold level has already been set, so the container has to use the previous level in this call + so that any range hidden underneath this line can be shown. +

+ +

SCI_SETAUTOMATICFOLD(int automaticFold)
+ SCI_GETAUTOMATICFOLD
+ Instead of implementing all the logic for handling folding in the container, Scintilla can provide behaviour + that is adequate for many applications. The automaticFold argument is a bit set defining + which of the 3 pieces of folding implementation should be enabled. Most applications should be able to use the + SC_AUTOMATICFOLD_SHOW and SC_AUTOMATICFOLD_CHANGE + flags unless they wish to implement quite different behavious such as defining their own fold structure. + SC_AUTOMATICFOLD_CLICK is more likely to be set off when an application would + like to add or change click behaviour such as showing method headers only when Shift+Alt is used in + conjunction with a click. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolValueEffect
SC_AUTOMATICFOLD_SHOW1Automatically show lines as needed. + This avoids sending the SCN_NEEDSHOWN notification.
SC_AUTOMATICFOLD_CLICK2Handle clicks in fold margin automatically. + This avoids sending the SCN_MARGINCLICK notification for folding margins.
SC_AUTOMATICFOLD_CHANGE4Show lines as needed when fold structure is changed. + The SCN_MODIFIED notification is still sent unless it is disabled by the + container.
+

SCI_CONTRACTEDFOLDNEXT(int lineStart)
Search efficiently for lines that are contracted fold headers. This is useful when saving the user's folding when switching documents or saving folding with a file. @@ -5064,6 +5555,12 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ Subline is indented by at least 1 to make room for the flag.
+ + + SC_WRAPVISUALFLAG_MARGIN + 4 + Visual flag in line number margin. + @@ -5352,8 +5849,18 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ SCI_DESCRIBEKEYWORDSETS(<unused>, char *descriptions)
SCI_SETKEYWORDS(int keyWordSet, const char *keyWordList)
- SCI_GETSTYLEBITSNEEDED -
+ SCI_GETSTYLEBITSNEEDED
+ +

+

SCI_SETLEXER(int lexer)
@@ -5499,6 +6006,37 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ to SCI_SETSTYLEBITS.

+
+

Substyles

+ These features are provisional
+

Lexers may support several different sublanguages and each sublanguage may want to style some number of + sets of identifiers (or similar lexemes such as documentation keywords) uniquely. Preallocating a large number for each + purpose would exhaust the number of allowed styles quickly. + This is alleviated by substyles which allow the application to determine how many sets of identifiers to allocate for + each purpose. + Lexers have to explicitly support this feature by implementing the methods in ILexerWithSubStyles.

+ +

SCI_GETSUBSTYLEBASES(<unused>, char *styles)
+ Fill styles with a byte for each style that can be split into substyles.

+ +

SCI_DISTANCETOSECONDARYSTYLES
+ Returns the distance between a primary style and its corresponding secondary style.

+ +

SCI_ALLOCATESUBSTYLES(int styleBase, int numberStyles)
+ Allocate some number of substyles for a particular base style returning the first substyle number allocated. + Substyles are allocated contiguously.

+ +

SCI_FREESUBSTYLES
+ Free all allocated substyles.

+ +

SCI_GETSUBSTYLESSTART(int styleBase)
+ SCI_GETSUBSTYLESLENGTH(int styleBase)
+ Return the start and length of the substyles allocated for a base style.

+ +

SCI_SETIDENTIFIERS(int style, const char *identifiers)
+ Similar to SCI_SETKEYWORDS but for substyles.

+
+

Lexer Objects

Lexers are programmed as objects that implement the ILexer interface and that interact @@ -5613,6 +6151,27 @@ needs to be folded as this allowed fixing up the last line from the previous fol The new approach allows the lexer to decide whether to backtrack or to handle this more efficiently.

+

ILexerWithSubStyles

+ +

+To allow lexers to report which line ends they support, and to support substyles, +Ilexer is extended to ILexerWithSubStyles. +

+ +
+class ILexerWithSubStyles : public ILexer {
+public:
+        virtual int SCI_METHOD LineEndTypesSupported() = 0;
+        virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0;
+        virtual int SCI_METHOD SubStylesStart(int styleBase) = 0;
+        virtual int SCI_METHOD SubStylesLength(int styleBase) = 0;
+        virtual void SCI_METHOD FreeSubStyles() = 0;
+        virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0;
+        virtual int SCI_METHOD DistanceToSecondaryStyles() = 0;
+        virtual const char * SCI_METHOD GetSubStyleBases() = 0;
+};
+
+

IDocument

@@ -5761,7 +6320,32 @@ exceptions. Exceptions should not be thrown over build boundaries as the two sides may be built with different compilers or incompatible exception options.

-

The ILexer and IDocument interfaces may be +

IDocumentWithLineEnd

+ +

+To allow lexers to determine the end position of a line and thus more easily support Unicode line ends +IDocument is extended to IDocumentWithLineEnd.

+

GetRelativePosition navigates the document by whole characters, +returning INVALID_POSITION for movement beyond the start and end of the document.

+

GetCharacterAndWidth provides a standard +conversion from UTF-8 bytes to a UTF-32 character or from DBCS to a 16 bit value. +Bytes in invalid UTF-8 are reported individually with values 0xDC80+byteValue, which are +not valid Unicode code points. +The pWidth argument can be NULL if the caller does not need to know the number of +bytes in the character. +

+ +
+class IDocumentWithLineEnd : public IDocument {
+public:
+        virtual int SCI_METHOD LineEnd(int line) const = 0;
+        virtual int SCI_METHOD GetRelativePosition(int positionStart, int characterOffset) const = 0;
+        virtual int SCI_METHOD GetCharacterAndWidth(int position, int *pWidth) const = 0;
+};
+
+ +

The ILexer, ILexerWithSubStyles, IDocument, and +IDocumentWithLineEnd interfaces may be expanded in the future with extended versions (ILexer2...). The Version method indicates which interface is implemented and thus which methods may be called.

@@ -5865,11 +6449,11 @@ struct SCNotification {

SCI_SETIDENTIFIER(int identifier)
SCI_GETIDENTIFIER
- These two messages set and get the identifier of the Scintilla instance which is included in notifications as the - idFrom field. + These two messages set and get the identifier of the Scintilla instance which is included in notifications as the + idFrom field. When an application creates multiple Scintilla widgets, this allows the source of each notification to be found. - On Windows, this value is initialised in the CreateWindow call and stored as the - GWLP_ID attribute of the window. + On Windows, this value is initialised in the CreateWindow call and stored as the + GWLP_ID attribute of the window. The value should be small, preferrably less than 16 bits, rather than a pointer as some of the functions will only transmit 16 or 32 bits.

@@ -6031,9 +6615,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(lineNumber); Valid for text changes, not for style changes. If we are collecting undo information this holds a pointer to the text that is handed to the Undo system, otherwise - it is zero. For user performed SC_MOD_BEFOREDELETE the text field is 0 and - for user performed SC_MOD_BEFOREINSERT the text field points to an array of cells, - not bytes and the length is the number of cells. + it is zero. For user performed SC_MOD_BEFOREDELETE the text field is 0. @@ -6595,6 +7177,54 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next The user deleted a character while autocompletion list was active. There is no other information in SCNotification.

+

Images

+ +

Two formats are supported for images used in margin markers and autocompletion lists, RGBA and XPM.

+ +

RGBA

+ +

The RGBA format allows translucency with an alpha + value for each pixel. It is simpler than + XPM and more capable.

+ +

The data is a sequence of 4 byte pixel values starting with the pixels for the top line, with the + leftmost pixel first, then continuing with the pixels for subsequent lines. There is no gap between + lines for alignment reasons.

+ +

Each pixel consists of, in order, a red byte, a green byte, a blue byte and an alpha byte. + The colour bytes are not premultiplied by the alpha value. That is, a fully red pixel that is + 25% opaque will be [FF, 00, 00, 3F]

+ +

Since the RGBA pixel data does not include any size information the + width and height must previously been set with the + SCI_RGBAIMAGESETWIDTH and + SCI_RGBAIMAGESETHEIGHT messages.

+ +

GUI platforms often include functions for reading image file formats like PNG into memory + in the RGBA form or a similar form. + If there is no suitable platform support, the LodePNG and picoPNG libraries are small libraries + for loading and decoding PNG files available under a BSD-style license.

+ +

RGBA format is supported on Windows, GTK+ and OS X Cocoa.

+ +

XPM

+ +

The XPM format is + described here. + Scintilla is only able to handle XPM pixmaps that use one character per pixel with no named colours. + There may be a completely transparent colour named "None".

+

There are two forms of data structure used for XPM images, the first "lines form" format is well suited + to embedding an image inside C source code and the "text form" is suited to reading from a file. + In the lines form, an array of strings is used with the first string indicating the dimensions and number of colours + used. This is followed by a string for each colour and that section is followed by the image with one string per line. + The text form contains the same data as one null terminated block formatted as C source code starting + with a "/* XPM */" comment to mark the format.

+

Either format may be used with Scintilla APIs with the bytes at the location pointed to examined + to determine which format: if the bytes start with "/* XPM */" then it is treated as text form, + otherwise it is treated as lines form.

+ +

XPM format is supported on on all platforms.

+

GTK+

On GTK+, the following functions create a Scintilla widget, communicate with it and allow resources to be released after all Scintilla widgets have been destroyed.

@@ -6619,6 +7249,17 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next

void scintilla_release_resources()
Call this to free any remaining resources after all the Scintilla widgets have been destroyed.

+

Provisional messages

+ +

Complex new features may be added as 'provisional' to allow further changes to the API. + Provisional features may even be removed if experience shows they are a mistake.

+ +

Provisional features are displayed in this document with a distinctive background colour.

+ +

Some developers may want to only use features that are stable and have graduated from + provisional status. To avoid using provisional messages compile with the symbol + SCI_DISABLE_PROVISIONAL defined.

+

Deprecated messages and notifications

The following messages are currently supported to emulate existing Windows controls, but @@ -6672,15 +7313,14 @@ EM_FORMATRANGE INCLUDE_DEPRECATED_FEATURES in Scintilla.h. To ensure future compatibility you should change them as indicated.

-

SCN_POSCHANGED() Deprecated
- Fired when the user moves the cursor to a different position in the text. Use SCN_UPDATEUI instead.

+

SC_CP_DBCS Deprecated
+ This was used to set a DBCS (Double Byte Character Set) mode on GTK+. + An explicit DBCS code page should be used when calling SCI_SETCODEPAGE

-

SCN_CHECKBRACE Deprecated
- Either the text or styling of the document has changed or the selection range has changed. - This is replaced by SCN_UPDATEUI. You - can also use SCN_MODIFIED for more - detailed information on text and styling changes,

+

SCI_SETUSEPALETTE(bool allowPaletteUse) Deprecated
+ SCI_GETUSEPALETTE Deprecated
+ Scintilla no longer supports palette mode. The last version to support palettes was 2.29. + Any calls to these methods should be removed.

Edit messages never supported by Scintilla

@@ -6720,11 +7360,10 @@ EM_SETTARGETDEVICE
     

Building Scintilla

To build Scintilla or SciTE, see the README file present in both the Scintilla and SciTE - directories. For Windows, GCC 3.2, Borland C++ or Microsoft Visual Studio .NET can be used - for building. There is a make file for building Scintilla but not SciTE with Visual C++ 6 at - scintilla/win32/scintilla_vc6.mak. For GTK+, GCC 3.1 should be used. GTK+ 1.2x and 2.0x are + directories. For Windows, GCC 4.7 or Microsoft Visual C++ 2010 can be used + for building. For GTK+, GCC 4.1 or newer should be used. GTK+ 2.8+ and 3.x are supported. The version of GTK+ installed should be detected automatically. - When both GTK+ 1 and GTK+ 2 are present, building for GTK+ 1.x requires defining GTK1 + When both GTK+ 2 and GTK+ 3 are present, building for GTK+ 3.x requires defining GTK3 on the command line.

Static linking

diff --git a/scintilla/doc/ScintillaDownload.html b/scintilla/doc/ScintillaDownload.html index 176acf22..17e30fb7 100644 --- a/scintilla/doc/ScintillaDownload.html +++ b/scintilla/doc/ScintillaDownload.html @@ -25,9 +25,9 @@ @@ -41,7 +41,7 @@ containing very few restrictions.

- Release 2.27 + Release 3.3.4

Source Code @@ -49,8 +49,8 @@ The source code package contains all of the source code for Scintilla but no binary executable code and is available in
    -
  • zip format (1200K) commonly used on Windows
  • -
  • tgz format (1080K) commonly used on Linux and compatible operating systems
  • +
  • zip format (1250K) commonly used on Windows
  • +
  • tgz format (1100K) commonly used on Linux and compatible operating systems
Instructions for building on both Windows and Linux are included in the readme file.

diff --git a/scintilla/doc/ScintillaHistory.html b/scintilla/doc/ScintillaHistory.html index 93d444ff..c7911bfd 100644 --- a/scintilla/doc/ScintillaHistory.html +++ b/scintilla/doc/ScintillaHistory.html @@ -378,6 +378,55 @@

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- + Windows   - + GTK+/Linux  
Jaime Gimeno Thomas Linder PulsArtyom ZuikovGerrit
Occam's RazorBen BluemelDavid WolfendaleChris Angelico
Marat DukhanStefan WeilRex ConnRoss McKay
Bruno BarbieriGordon SmithdimitarSébastien Granjoux
zenikoJames RibeMarkus NißlMartin Panter
Mark YenPhilippe ElsassDimitar ZhekovFan Yang
Denis ShelomovskijdarmarJohn VellaChinh Nguyen
Sakshi VermaJoel B. MohlerIsiledhelVidya Wasi
G. HuByron HawkinsAlphaJohn Donoghue
kudahIgor ShaulaPavel BulochkinYosef Or Boczko
Brian Griffin

@@ -389,6 +438,1615 @@ Icons Copyright(C) 1998 by Dean S. Jones
+

+ Release 3.3.4 +

+
    +
  • + Released 19 July 2013. +
  • +
  • + Handling of UTF-8 and DBCS text in lexers improved with methods ForwardBytes and + GetRelativeCharacter added to StyleContext. + Bug #1483. +
  • +
  • + For Unicode text, case-insensitive searching and making text upper or lower case is now + compliant with Unicode standards on all platforms and is much faster for non-ASCII characters. +
  • +
  • + A CategoriseCharacter function was added to return the Unicode general category of a character + which can be useful in lexers. +
  • +
  • + On Cocoa, the LCD Optimized font quality level turns font smoothing on. +
  • +
  • + SciTE 'immediate' subsystem added to allow scripts that work while tools are executed. +
  • +
  • + Font quality exposed in SciTE as font.quality setting. +
  • +
  • + On Cocoa, message:... methods simplify direct access to Scintilla and avoid call layers.. +
  • +
  • + A68K lexer updated. +
  • +
  • + CoffeeScript lexer fixes a bug with comment blocks. + Feature #1495. +
  • +
  • + ECL lexer regular expression code fixed. + Bug #1491. +
  • +
  • + errorlist lexer only recognises Perl diagnostics when there is a filename between + "at" and "line". Had been triggering for MSVC errors containing "at line". +
  • +
  • + Haskell lexer fixed to avoid unnecessary full redraws. + Don't highlight CPP inside comments when styling.within.preprocessor is on. + Bug #1459. +
  • +
  • + Lua lexer fixes bug in labels with UTF-8 text. + Bug #1483. +
  • +
  • + Perl lexer fixes bug in string interpolation with UTF-8 text. + Bug #1483. +
  • +
  • + Fixed bugs with case conversion when the result was longer or shorter than the original text. + Could access past end of string potentially crashing. + Selection now updated to result length. +
  • +
  • + Fixed bug where data being inserted and removed was not being reported in + notification messages. Bug was introduced in 3.3.2. +
  • +
  • + Word wrap bug fixed where the last line could be shown twice. +
  • +
  • + Word wrap bug fixed for lines wrapping too short on Windows and GTK+. +
  • +
  • + Word wrap performance improved. +
  • +
  • + Minor memory leak fixed. + Bug #1487. +
  • +
  • + On Cocoa, fixed insertText: method which was broken when implementing a newer protocol. +
  • +
  • + On Cocoa, fixed a crash when performing string folding for bytes that do not represent a character + in the current encoding. +
  • +
  • + On Qt, fixed layout problem when QApplication construction delayed. +
  • +
  • + On Qt, find_text reports failure with -1 as first element of return value. +
  • +
  • + Fixed SciTE on GTK+ bug where a tool command could be performed using the keyboard while one was + already running leading to confusion and crashes. + Bug #1486. +
  • +
  • + Fixed SciTE bug in Copy as RTF which was limited to first 32 styles. + Bug #1011. +
  • +
  • + Fixed SciTE on Windows user strip height when the system text scaling factor is 125% or 150%. +
  • +
  • + Compile time checks for Digital Mars C++ removed. +
  • +
  • + Visual C++ 2013 supported. + Bug #1492. +
  • +
  • + Python scripts used for building and maintenance improved and moved into scripts directory. +
  • +
  • + Testing scripts now work on Linux using Qt and PySide. +
  • +
  • + Tk platform defined. + Implementation for Tk will be available separately from main Scintilla distribution. +
  • +
+

+ Release 3.3.3 +

+
    +
  • + Released 2 June 2013. +
  • +
  • + Lexer and folder added for Structured Text language. + Feature #959. +
  • +
  • + Out of bounds access fixed for GTK+. + Bug #1480. +
  • +
  • + Crash fixed for GTK+ on Windows paste. +
  • +
  • + Bug fixed with incorrect event copying on GTK+ 3.x. + Bug #1481. +
  • +
  • + Bug fixed with right to left locales, like Hebrew, on GTK+. + Bug #1477. +
  • +
  • + Bug fixed with undo grouping of tab and backtab commands. + Bug #1478. +
  • +
+

+ Release 3.3.2 +

+
    +
  • + Released 22 May 2013. +
  • +
  • + Basic implementations of common folding methods added to Scintilla to make it + easier for containers to implement folding. +
  • +
  • + Add indicator INDIC_COMPOSITIONTHICK, a thick low underline, to mimic an + appearance used for Asian language input composition. +
  • +
  • + On Cocoa, implement font quality setting. + Feature #988. +
  • +
  • + On Cocoa, implement automatic enabling of commands and added clear command. + Feature #987. +
  • +
  • + C++ lexer adds style for preprocessor doc comment. + Feature #990. +
  • +
  • + Haskell lexer and folder improved. Separate mode for literate Haskell "literatehaskell" SCLEX_LITERATEHASKELL. + Bug #1459 . +
  • +
  • + LaTeX lexer bug fixed for Unicode character following '\'. + Bug #1468 . +
  • +
  • + PowerShell lexer recognises here strings and doccomment keywords. + #region folding added. + Feature #985. +
  • +
  • + Fix multi-typing when two carets are located in virtual space on one line so that spaces + are preserved. +
  • +
  • + Fixes to input composition on Cocoa and implementation of accented character input through + press and hold. Set selection correctly so that changes to pieces of composition text are easier to perform. + Restore undo collection after a sequence of composition actions. + Composition popups appear near input. +
  • +
  • + Fix lexer problem where no line end was seen at end of document. +
  • +
  • + Fix crash on Cocoa when view deallocated. + Bug #1466. +
  • +
  • + Fix Qt window positioning to not assume the top right of a monitor is at 0, 0. +
  • +
  • + Fix Qt to not track mouse when widget is hidden. +
  • +
  • + Qt now supports Qt 5.0. + Bug #1448. +
  • +
  • + Fix drawing on Windows with Direct2D when returning from lock screen. + The render target had to be recreated and an area would be black since the drawing was not retried. +
  • +
  • + Fix display of DBCS documents on Windows Direct2D/DirectWrite with default character set. +
  • +
  • + For SciTE on Windows, fixed most-recently-used menu when files opened through check.if.already.opened. +
  • +
  • + In SciTE, do not call OnSave twice when files saved asynchronously. +
  • +
  • + Scintilla no longer builds with Visual C++ 6.0. +
  • +
+

+ Release 3.3.1 +

+
    +
  • + Released 11 April 2013. +
  • +
  • + Autocompletion lists can now appear in priority order or be sorted by Scintilla. + Feature #981. +
  • +
  • + Most lexers now lex an extra NUL byte at the end of the + document which makes it more likely they will classify keywords at document end correctly. + Bug #574, + Bug #588. +
  • +
  • + Haskell lexer improved in several ways. + Bug #1459. +
  • +
  • + Matlab/Octave lexer recognises block comments and ... comments. + Bug #1414. +
  • +
  • + Ruby lexer crash fixed with keyword at start of document. +
  • +
  • + The PLAT_NCURSES platform now called PLAT_CURSES as may work on other implementations. +
  • +
  • + Bug on Cocoa fixed where input composition with multiple selection or virtual space selection + could make undo stop working. +
  • +
  • + Direct2D/DirectWrite mode on Windows now displays documents in non-Latin1 8-bit encodings correctly. +
  • +
  • + Character positioning corrected in Direct2D/DirectWrite mode on Windows to avoid text moving and cutting off + lower parts of characters. +
  • +
  • + Position of calltip and autocompletion lists fixed on Cocoa. +
  • +
  • + While regular expression search in DBCS text is still not working, matching partial characters is now avoided + by moving end of match to end of character. +
  • +
+

+ Release 3.3.0 +

+
    +
  • + Released 30 March 2013. +
  • +
  • + Overlay scrollers and kinetic scrolling implemented on Cocoa. +
  • +
  • + To improve display smoothness, styling and UI Update notifications will, when possible, be performed in + a high-priority idle task on Cocoa instead of during painting. + Performing these jobs inside painting can cause paints to be abandoned and a new paint scheduled. + On GTK+, the high-priority idle task is used in more cases. +
  • +
  • + SCI_SCROLLRANGE added to scroll the view to display a range of text. + If the whole range can not be displayed, priority is given to one end. +
  • +
  • + C++ lexer no longer recognises raw (R"") strings when the first character after " + is invalid. + Bug #1454. +
  • +
  • + HTML lexer recognises JavaScript RegEx literals in more contexts. + Bug #1412. +
  • +
  • + Fixed automatic display of folded text when return pressed at end of fold header and + first folded line was blank. + Bug #1455. +
  • +
  • + SCI_VISIBLEFROMDOCLINE fixed to never return a line beyond the document end. +
  • +
  • + SCI_LINESCROLL fixed for a negative column offset. + Bug #1450. +
  • +
  • + On GTK+, fix tab markers so visible if indent markers are visible. + Bug #1453. +
  • +
+

+ Release 3.2.5 +

+
    +
  • + Released 26 February 2013. +
  • +
  • + To allow cooperation between different uses of extended (beyond 255) styles they should be allocated + using SCI_ALLOCATEEXTENDEDSTYLES. +
  • +
  • + For Unicode documents, lexers that use StyleContext will retrieve whole characters + instead of bytes. + LexAccessor provides a LineEnd method which can be a more efficient way to + handle line ends and can enable Unicode line ends. +
  • +
  • + The C++ lexer understands the #undef directive when determining preprocessor definitions. + Feature #978. +
  • +
  • + The errorlist lexer recognises gcc include path diagnostics that appear before an error. +
  • +
  • + Folding implemented for GetText (PO) translation language. + Bug #1437. +
  • +
  • + HTML lexer does not interrupt comment style for processing instructions. + Bug #1447. +
  • +
  • + Fix SciTE forgetting caret x-position when switching documents. + Bug #1442. +
  • +
  • + Fixed bug where vertical scrollbar thumb appeared at beginning of document when + scrollbar shown. + Bug #1446. +
  • +
  • + Fixed brace-highlighting bug on OS X 10.8 where matching brace is on a different line. +
  • +
  • + Provisional features + are new features that may change or be removed if they cause problems but should become + permanent if they work well. + For this release Unicode line ends and + substyles + are provisional features. +
  • +
+

+ Release 3.2.4 +

+
    +
  • + Released 17 January 2013. +
  • +
  • + Caret line highlight can optionally remain visible when window does not have focus. + Feature #964. +
  • +
  • + Delegate mechanism for notifications added on Cocoa. +
  • +
  • + NUL characters in selection are copied to clipboard as spaces to avoid truncating + at the NUL. + Bug #1289. +
  • +
  • + C++ lexer fixes problem with showing inactive sections when preprocessor lines contain trailing comment. + Bug #1413. +
  • +
  • + C++ lexer fixes problem with JavaScript regular expressions with '/' in character ranges. + Bug #1415. +
  • +
  • + LaTeX folder added. + Feature #970. +
  • +
  • + LaTeX lexer improves styling of math environments. + Feature #970. +
  • +
  • + MySQL lexer implements hidden commands. +
  • +
  • + Only produce a single undo step when autocompleting a single word. + Bug #1421. +
  • +
  • + Fixed crash when printing lines longer than 8000 characters. + Bug #1430. +
  • +
  • + Fixed problem in character movement extends selection mode where reversing + direction collapsed the selection. +
  • +
  • + Memory issues fixed on Cocoa, involving object ownership, + lifetime of timers, and images held by the info bar. + Bug #1436. +
  • +
  • + Cocoa key binding for Alt+Delete changed to delete previous word to be more compatible with + platform standards. +
  • +
  • + Fixed crash on Cocoa with scrollbar when there is no scrolling possible. + Bug #1416. +
  • +
  • + On Cocoa with retina display fixed positioning of autocompletion lists. +
  • +
  • + Fixed SciTE on Windows failure to run a batch file with a name containing a space by + quoting the path in the properties file. + Bug #1423. +
  • +
  • + Fixed scaling bug when printing on GTK+. + Bug #1427. +
  • +
  • + SciTE on GTK toolbar.detachable feature removed. +
  • +
  • + Fixed some background saving bugs in SciTE. + Bug #1366. + Bug #1339. +
  • +
+

+ Release 3.2.3 +

+
    +
  • + Released 21 October 2012. +
  • +
  • + Improve speed when performing multiple searches. +
  • +
  • + SciTE adds definition of PLAT_UNIX for both PLAT_GTK and PLAT_MAC to allow consolidation of + settings valid on all Unix variants. +
  • +
  • + Signal autoCompleteCancelled added on Qt. +
  • +
  • + Bash lexer supports nested delimiter pairs. + Feature #3569352. + Bug #1515556. + Bug #3008483. + Bug #3512208. + Bug #3515392. +
  • +
  • + For C/C++, recognise exponent in floating point hexadecimal literals. + Bug #3576454. +
  • +
  • + For C #include statements, do not treat // in the path as a comment. + Bug #3519260. +
  • +
  • + Lexer for GetText translations (PO) improved with additional styles and single instance limitation fixed. +
  • +
  • + Ruby for loop folding fixed. + Bug #3240902. + Bug #3567391. +
  • +
  • + Ruby recognition of here-doc after class or instance variable fixed. + Bug #3567809. +
  • +
  • + SQL folding of loop and case fixed. + Bug #3567905. +
  • +
  • + SQL folding of case with assignment fixed. + Bug #3571820. +
  • +
  • + Fix hang when removing all characters from indicator at end of document. +
  • +
  • + Fix failure of \xhh in regular expression search for values greater than 0x79. +
  • +
  • + On Cocoa on OS X 10.8, fix inverted drawing of find indicator. +
  • +
  • + On Cocoa, fix double drawing when horizontal scroll range small and user swipes horizontally. +
  • +
  • + On Cocoa, remove incorrect setting of save point when reading information through 'string' and 'selectedString'. +
  • +
  • + On Cocoa, fix incorrect memory managment of infoBar. +
  • +
  • + On GTK+ 3 Ubuntu, fix crash when drawing margin. +
  • +
  • + On ncurses, fix excessive spacing with italics line end. +
  • +
  • + On Windows, search for D2D1.DLL and DWRITE.DLL in system directory to avoid loading from earlier + in path where could be planted by malware. +
  • +
+

+ Release 3.2.2 +

+
    +
  • + Released 31 August 2012. +
  • +
  • + Retina display support for Cocoa. Text size fixed. + Scale factor for images implemented so they can be displayed in high definition. +
  • +
  • + Implement INDIC_SQUIGGLEPIXMAP as a faster version of INDIC_SQUIGGLE. + Avoid poor drawing at right of INDIC_SQUIGGLE. + Align INDIC_DOTBOX to pixel grid for full intensity. +
  • +
  • + Implement SCI_GETSELECTIONEMPTY API. + Bug #3543121. +
  • +
  • + Added SCI_VCHOMEDISPLAY and SCI_VCHOMEDISPLAYEXTEND key commands. + Feature #3561433. +
  • +
  • + Allow specifying SciTE Find in Files directory with find.in.directory property. + Feature #3558594. +
  • +
  • + Override SciTE global strip.trailing.spaces with strip.trailing.spaces by pattern files. + Feature #3556320. +
  • +
  • + Fix long XML script tag handling in XML lexer. + Bug #3534190. +
  • +
  • + Fix rectangular selection range after backspace. + Bug #3543097. +
  • +
  • + Send SCN_UPDATEUI with SC_UPDATE_SELECTION for backspace in virtual space. + Bug #3543121. +
  • +
  • + Avoid problems when calltip highlight range is negative. + Bug #3545938. +
  • +
  • + On Cocoa, fix image drawing code so that image is not accessed after being freed + and is drawn in the correct location. +
  • +
  • + On Cocoa, limit horizontal touch scrolling to existing established width. +
  • +
  • + On Cocoa, decrease sensitivity of pinch-zoom. +
  • +
  • + Fix Cocoa drawing where style changes were not immediately visible. +
  • +
  • + Fix Cocoa memory leak due to reference cycle. +
  • +
  • + Fix Cocoa bug where notifications were sent after Scintilla was freed. +
  • +
  • + SciTE on OS X user shortcuts treats "Ctrl+D" as equivalent to "Ctrl+d". +
  • +
  • + On Windows, saving SciTE's Lua startup script causes it to run. +
  • +
  • + Limit time allowed to highlight current word in SciTE to 0.25 seconds to remain responsive. +
  • +
  • + Fixed SciTE read-only mode to stick with buffer. +
  • +
  • + For SciTE on Windows, enable Ctrl+Z, Ctrl+X, and Ctrl+C (Undo, Cut, and Copy) in the + editable fields of find and replace strips +
  • +
  • + Remove limit on logical line length in SciTE .properties files. + Bug #3544312. +
  • +
  • + Improve performance of SciTE Save As command. +
  • +
  • + Fix SciTE crash with empty .properties files. Bug #3545938. + Bug #3555308. +
  • +
  • + Fix repeated letter in SciTE calltips. + Bug #3545938. +
  • +
  • + Refine build time checking for Direct2D and DirectWrite. +
  • +
  • + Avoid potential build problems on Windows with MultiMon.h by explicitly checking for multi-monitor APIs. +
  • +
  • + Automatically disable themed drawing in SciTE when building on Windows 2000. + Reenable building for Windows NT 4 on NT 4 . +
  • +
  • + Added ncurses platform definitions. Implementation is maintained separately as + Scinterm. +
  • +
+

+ Release 3.2.1 +

+
    +
  • + Released 14 July 2012. +
  • +
  • + In Scintilla.iface, specify features as properties instead of functions where possible and fix some enumerations. +
  • +
  • + In SciTE Lua scripts, string properties in Scintilla API can be retrieved as well as set using property notation. +
  • +
  • + Added character class APIs: SCI_SETPUNCTUATIONCHARS, SCI_GETWORDCHARS, SCI_GETWHITESPACECHARS, + and SCI_GETPUNCTUATIONCHARS. + Feature #3529805. +
  • +
  • + Less/Hss support added to CSS lexer. + Feature #3532413. +
  • +
  • + C++ lexer style SCE_C_PREPROCESSORCOMMENT added for stream comments in preprocessor. + Bug #3487406. +
  • +
  • + Fix incorrect styling of inactive code in C++ lexer. + Bug #3533036. +
  • +
  • + Fix incorrect styling by C++ lexer after empty lines in preprocessor style. +
  • +
  • + C++ lexer option "lexer.cpp.allow.dollars" fixed so can be turned off after being on. + Bug #3541461. +
  • +
  • + Fortran fixed format lexer fixed to style comments from column 73. + Bug #3540486. +
  • +
  • + Fortran folder folds CRITICAL .. END CRITICAL. + Bug #3540486. +
  • +
  • + Fortran lexer fixes styling after comment line ending with '&'. + Bug #3087226. +
  • +
  • + Fortran lexer styles preprocessor lines so they do not trigger incorrect folding. + Bug #2906275. +
  • +
  • + Fortran folder fixes folding of nested ifs. + Bug #2809176. +
  • +
  • + HTML folder fixes folding of CDATA when fold.html.preprocessor=0. + Bug #3540491. +
  • +
  • + On Cocoa, fix autocompletion font lifetime issue and row height computation. +
  • +
  • + In 'choose single' mode, autocompletion will close an existing list if asked to display a single entry list. +
  • +
  • + Fixed SCI_MARKERDELETE to only delete one marker per call. + Bug #3535806. +
  • +
  • + Properly position caret after undoing coalesced delete operations. + Bug #3523326. +
  • +
  • + Ensure margin is redrawn when SCI_MARGINSETSTYLE called. +
  • +
  • + Fix clicks in first pixel of margins to send SCN_MARGINCLICK. +
  • +
  • + Fix infinite loop when drawing block caret for a zero width space character at document start. +
  • +
  • + Crash fixed for deleting negative range. +
  • +
  • + For characters that overlap the beginning of their space such as italics descenders and bold serifs, allow start + of text to draw 1 pixel into margin. + Bug #699587. + Bug #3537799. +
  • +
  • + Fixed problems compiling Scintilla for Qt with GCC 4.7.1 x64. +
  • +
  • + Fixed problem with determining GTK+ sub-platform caused when adding Qt support in 3.2.0. +
  • +
  • + Fix incorrect measurement of untitled file in SciTE on Linux leading to message "File ...' is 2147483647 bytes long". + Bug #3537764. +
  • +
  • + In SciTE, fix open of selected filename with line number to go to that line. +
  • +
  • + Fix problem with last visible buffer closing in SciTE causing invisible buffers to be active. +
  • +
  • + Avoid blinking of SciTE's current word highlight when output pane changes. +
  • +
  • + SciTE properties files can be longer than 60K. +
  • +
+

+ Release 3.2.0 +

+
    +
  • + Released 1 June 2012. +
  • +
  • + Platform layer added for the Qt open-source cross-platform application and user interface framework + for development in C++ or in Python with the PySide bindings for Qt. +
  • +
  • + Direct access provided to the document bytes for ranges within Scintilla. + This is similar to the existing SCI_GETCHARACTERPOINTER API but allows for better performance. +
  • +
  • + Ctrl+Double Click and Ctrl+Triple Click add the word or line to the set of selections. + Feature #3520037. +
  • +
  • + A SCI_DELETERANGE API was added for deleting a range of text. +
  • +
  • + Line wrap markers may now be drawn in the line number margin. + Feature #3518198. +
  • +
  • + SciTE on OS X adds option to hide hidden files in the open dialog box. +
  • +
  • + Lexer added for OScript language. + Feature #3523197. +
  • +
  • + Lexer added for Visual Prolog language. + Feature #3523018. +
  • +
  • + UTF-8 validity is checked more stringently and consistently. All 66 non-characters are now treated as invalid. +
  • +
  • + HTML lexer bug fixed with inconsistant highlighting for PHP when attribute on separate line from tag. + Bug #3520027. +
  • +
  • + HTML lexer bug fixed for JavaScript block comments. + Bug #3520032. +
  • +
  • + Annotation drawing bug fixed when box displayed with different colours on different lines. + Bug #3519872. +
  • +
  • + On Windows with Direct2D, fix drawing with 125% and 150% DPI system settings. +
  • +
  • + Virtual space selection bug fixed for rectangular selections. + Bug #3519246. +
  • +
  • + Replacing multiple selection with newline changed to only affect main selection. + Bug #3522251. +
  • +
  • + Replacing selection with newline changed to group deletion and insertion as a single undo action. + Bug #3522250. +
  • +
  • + Auto-completion lists on GTK+ 3 set height correctly instead of showing too few lines. +
  • +
  • + Mouse wheel scrolling changed to avoid GTK+ bug in recent distributions. +
  • +
  • + IME bug on Windows fixed for horizontal jump. + Bug #3529728. +
  • +
  • + SciTE case-insensitive autocompletion filters equal identifiers better. + Calltip arrows work with bare word identifiers. + Bug #3517810. +
  • +
  • + SciTE bug fixed where shbang lines not setting file type when switching + to file loaded in background. +
  • +
  • + SciTE on GTK+ shows open and save dialogs with the directory of the current file displayed. +
  • +
+

+ Release 3.1.0 +

+
    +
  • + Released 20 April 2012. +
  • +
  • + Animated find indicator added on Cocoa. +
  • +
  • + Buttons can be made default in SciTE user strips. +
  • +
  • + SciTE allows find and replace histories to be saved in session. +
  • +
  • + Option added to allow case-insensitive selection in auto-completion lists. + Bug #3516538. +
  • +
  • + Replace \0 by complete found text in regular expressions. + Feature #3510979. +
  • +
  • + Fixed single quoted strings in bash lexer. + Bug #3512208. +
  • +
  • + Incorrect highlighting fixed in C++ lexer for continued lines. + Bug #3509317. +
  • +
  • + Hang fixed in diff lexer. + Bug #3508602. +
  • +
  • + Folding improved for SQL CASE/MERGE statement. + Bug #3503277. +
  • +
  • + Fix extra drawing of selection inside word wrap indentation. + Bug #3515555. +
  • +
  • + Fix problem with determining the last line that needs styling when drawing. + Bug #3514882. +
  • +
  • + Fix problems with drawing in margins. + Bug #3514882. +
  • +
  • + Fix printing crash when using Direct2D to display on-screen. + Bug #3513946. +
  • +
  • + Fix SciTE bug where background.*.size disabled restoration of bookmarks and positions from session. + Bug #3514885. +
  • +
  • + Fixed the Move Selected Lines command when last line does not end with a line end character. + Bug #3511023. +
  • +
  • + Fix word wrap indentation printing to use printer settings instead of screen settings. + Bug #3512961. +
  • +
  • + Fix SciTE bug where executing an empty command prevented executing further commands + Bug #3512976. +
  • +
  • + Fix SciTE bugs with focus in user strips and made strips more robust with invalid definitions. +
  • +
  • + Suppress SciTE regular expression option when searching with find next selection. + Bug #3510985. +
  • +
  • + SciTE Find in Files command matches empty pattern to all files. + Feature #3495918. +
  • +
  • + Fix scroll with mouse wheel on GTK+. + Bug #3501321. +
  • +
  • + Fix column finding method so that tab is counted correctly. + Bug #3483713. +
  • +
+

+ Release 3.0.4 +

+
    +
  • + Released 8 March 2012. +
  • +
  • + SciTE scripts can create user interfaces as strips. +
  • +
  • + SciTE can save files automatically in the background. +
  • +
  • + Pinch zoom implemented on Cocoa. +
  • +
  • + ECL lexer added. + Feature #3488209. +
  • +
  • + CPP lexer fixes styling after document comment keywords. + Bug #3495445. +
  • +
  • + Pascal folder improves handling of some constructs. + Feature #3486385. +
  • +
  • + XML lexer avoids entering a bad mode due to complex preprocessor instructions. + Bug #3488060. +
  • +
  • + Duplicate command is always remembered as a distinct command for undo. + Bug #3495836. +
  • +
  • + SciTE xml.auto.close.tags no longer closes with PHP code similar to <a $this-> + Bug #3488067. +
  • +
  • + Fix bug where setting an indicator for the whole document would fail. + Bug #3487440. +
  • +
  • + Crash fixed for SCI_MOVESELECTEDLINESDOWN with empty vertical selection. + Bug #3496403. +
  • +
  • + Differences between buffered and unbuffered mode on Direct2D eliminated. + Bug #3495791. +
  • +
  • + Font leading implemented for Direct2D to improve display of character blobs. + Bug #3494744. +
  • +
  • + Fractional widths used for line numbers, character markers and other situations. + Bug #3494492. +
  • +
  • + Translucent rectangles drawn using Direct2D with sharper corners. + Bug #3494492. +
  • +
  • + RGBA markers drawn sharper when centred using Direct2D. + Bug #3494202. +
  • +
  • + RGBA markers are drawn centred when taller than line. + Bug #3494184. +
  • +
  • + Image marker drawing problem fixed for markers taller than line. + Bug #3493503. +
  • +
  • + Markers are drawn horizontally off-centre based on margin type instead of dimensions. + Bug #3488696. +
  • +
  • + Fold tail markers drawn vertically centred. + Feature #3488289. +
  • +
  • + On Windows, Scintilla is more responsive in wrap mode. + Bug #3487397. +
  • +
  • + Unimportant "Gdk-CRITICAL" messages are no longer displayed. + Bug #3488481. +
  • +
  • + SciTE on Windows Find in Files sets focus to dialog when already created; allows opening dialog when a job is running. + Bug #3480635. + Bug #3486657. +
  • +
  • + Fixed problems with multiple clicks in margin and with mouse actions combined with virtual space. + Bug #3484370. +
  • +
  • + Fixed bug with using page up and down and not returning to original line. + Bug #3485669. +
  • +
  • + Down arrow with wrapped text no longer skips lines. + Bug #1776560. +
  • +
  • + Fix problem with dwell ending immediately due to word wrap. + Bug #3484416. +
  • +
  • + Wrapped lines are rewrapped more consistently while resizing window. + Bug #3484179. +
  • +
  • + Selected line ends are highlighted more consistently. + Bug #3484330. +
  • +
  • + Fix grey background on files that use shbang to choose language. + Bug #3482777. +
  • +
  • + Fix failure messages from empty commands in SciTE. + Bug #3480645. +
  • +
  • + Redrawing reduced for some marker calls. + Feature #3493530. +
  • +
  • + Match brace and select brace commands work in SciTE output pane. + Feature #3486598. +
  • +
  • + Performing SciTE "Show Calltip" command when a calltip is already visible shows the next calltip. + Feature #3487017. +
  • +
  • + SciTE allows saving file even when file unchanged. + Feature #3486654. +
  • +
  • + SciTE allows optional use of character escapes in calltips. + Feature #3495239. +
  • +
  • + SciTE can open file:// URLs with Ctrl+Shift+O. + Feature #3495389. +
  • +
  • + Key modifiers updated for GTK+ on OS X to match upstream changes. +
  • +
  • + SciTE hang when marking all occurrences of regular expressions fixed. +
  • +
+

+ Release 3.0.3 +

+
    +
  • + Released 28 January 2012. +
  • +
  • + Printing works on GTK+ version 2.x as well as 3.x. +
  • +
  • + Lexer added for the AviSynth language. + Feature #3475611. +
  • +
  • + Lexer added for the Take Command / TCC scripting language. + Feature #3462462. +
  • +
  • + CSS lexer gains support for SCSS. + Feature #3268017. +
  • +
  • + CPP lexer fixes problems in the preprocessor structure caused by continuation lines. + Bug #3458508. +
  • +
  • + Errorlist lexer handles column numbers for GCC format diagnostics. + In SciTE, Next Message goes to column where this can be decoded from GCC format diagnostics. + Feature #3453075. +
  • +
  • + HTML folder fixes spurious folds on some tags. + Bug #3459262. +
  • +
  • + Ruby lexer fixes bug where '=' at start of file caused whole file to appear as a comment. + Bug #3452488. +
  • +
  • + SQL folder folds blocks of single line comments. + Feature #3467425. +
  • +
  • + On Windows using Direct2D, defer invalidation of render target until completion of painting to avoid failures. +
  • +
  • + Further support of fractional positioning. Spaces, tabs, and single character tokens can take fractional space + and wrapped lines are positioned taking fractional positions into account. + Bug #3471998. +
  • +
  • + On Windows using Direct2D, fix extra carets appearing. + Bug #3471998. +
  • +
  • + For autocompletion lists Page Up and Down move by the list height instead of by 5 lines. + Bug #3455493. +
  • +
  • + For SCI_LINESCROLLDOWN/UP don't select into virtual space. + Bug #3451681. +
  • +
  • + Fix fold highlight not being fully drawn. + Bug #3469936. +
  • +
  • + Fix selection margin appearing black when starting in wrap mode. +
  • +
  • + Fix crash when changing end of document after adding an annotation. + Bug #3476637. +
  • +
  • + Fix problems with building to make RPMs. + Bug #3476149. +
  • +
  • + Fix problem with building on GTK+ where recent distributions could not find gmodule. + Bug #3469056. +
  • +
  • + Fix problem with installing SciTE on GTK+ due to icon definition in .desktop file including an extension. + Bug #3476117. +
  • +
  • + Fix SciTE bug where new buffers inherited some properties from previously opened file. + Bug #3457060. +
  • +
  • + Fix focus when closing tab in SciTE with middle click. Focus moves to edit pane instead of staying on tab bar. + Bug #3440142. +
  • +
  • + For SciTE on Windows fix bug where Open Selected Filename for URL would append a file extension. + Feature #3459185. +
  • +
  • + For SciTE on Windows fix key handling of control characters in Parameters dialog so normal editing (Ctrl+C, ...) works. + Bug #3459345. +
  • +
  • + Fix SciTE bug where files became read-only after saving. Drop the "*" dirty marker after save completes. + Bug #3467432. +
  • +
  • + For SciTE handling of diffs with "+++" and "---" lines, also handle case where not followed by tab. + Go to correct line for diff "+++" message. + Bug #3467143. + Bug #3467178. +
  • +
  • + SciTE on GTK+ now performs threaded actions even on GTK+ versions before 2.12. +
  • +
+

+ Release 3.0.2 +

+
    +
  • + Released 9 December 2011. +
  • +
  • + SciTE saves files in the background without blocking the user interface. +
  • +
  • + Printing implemented in SciTE on GTK+ 3.x. +
  • +
  • + ILoader interface for background loading finalised and documented. +
  • +
  • + CoffeeScript lexer added. +
  • +
  • + C++ lexer fixes crash with "#if defined( XXX 1". +
  • +
  • + Crash with Direct2D on Windows fixed. +
  • +
  • + Backspace removing protected range fixed. + Bug #3445911. +
  • +
  • + Cursor setting failure on Windows when screen saver on fixed. + Bug #3438780. +
  • +
  • + SciTE on GTK+ hang fixed with -open:file option. + Bug #3441980. +
  • +
  • + Failure to evaluate shbang fixed in SciTE. + Bug #3441801. +
  • +
  • + SciTE failure to treat files starting with "<?xml" as XML fixed. + Bug #3440718. +
  • +
  • + Made untitled tab saveable when created by closing all files. + Bug #3440244. +
  • +
  • + SciTE crash fixed when using Scintillua. +
  • +
  • + SciTE revert command fixed so that undo works on individual actions instead of undoing to revert point. +
  • +
  • + Focus loss in SciTE when opening a recent file fixed. + Bug #3440142. +
  • +
  • + Fixed SciTE SelLength property to measure characters instead of bytes. + Bug #3283519. +
  • +
+

+ Release 3.0.1 +

+
    +
  • + Released 15 November 2011. +
  • +
  • + SciTE on Windows now runs Lua scripts directly on the main thread instead of starting them on a + secondary thread and then moving back to the main thread. +
  • +
  • + Highlight "else" as a keyword for TCL in the same way as other languages. + Bug #1836954. +
  • +
  • + Fix problems with setting fonts for autocompletion lists on Windows where + font handles were copied and later deleted causing a system default font to be used. +
  • +
  • + Fix font size used on Windows for Asian language input methods which sometimes led to IME not being visible. + Bug #3436753. +
  • +
  • + Fixed polygon drawing on Windows so fold symbols are visible again. + Bug #3433558. +
  • +
  • + Changed background drawing on GTK+ to allow for fractional character positioning as occurs on OS X + as this avoids faint lines at lexeme boundaries. +
  • +
  • + Ensure pixmaps allocated before painting as there was a crash when Scintilla drew without common initialisation calls. + Bug #3432354. +
  • +
  • + Fixed SciTE on Windows bug causing wrong caret position after indenting a selection. + Bug #3433433. +
  • +
  • + Fixed SciTE session saving to store buffer position matching buffer. + Bug #3434372. +
  • +
  • + Fixed leak of document objects in SciTE. +
  • +
  • + Recognise URL characters '?' and '%' for Open Selected command in SciTE. + Bug #3429409. +
  • +
+

+ Release 3.0.0 +

+
    +
  • + Released 1 November 2011. +
  • +
  • + Carbon platform support removed. OS X applications should switch to Cocoa. +
  • +
  • + On Windows Vista or newer, drawing may be performed with Direct2D and DirectWrite instead of GDI. +
  • +
  • + Cairo is now used for all drawing on GTK+. GDK drawing was removed. +
  • +
  • + Paletted display support removed. +
  • +
  • + Fractional font sizes can be specified. +
  • +
  • + Different weights of text supported on some platforms instead of just normal and bold. +
  • +
  • + Sub-pixel character positioning supported. +
  • +
  • + SciTE loads files in the background without blocking the user interface. +
  • +
  • + SciTE can display diagnostic messages interleaved with the text of files immediately after the + line referred to by the diagnostic. +
  • +
  • + New API to see if all lines are visible which can be used to optimize processing fold structure notifications. +
  • +
  • + Scrolling optimized by avoiding invalidation of fold margin when redrawing whole window. +
  • +
  • + Optimized SCI_MARKERNEXT. +
  • +
  • + C++ lexer supports Pike hash quoted strings when turned on with lexer.cpp.hashquoted.strings. +
  • +
  • + Fixed incorrect line height with annotations in wrapped mode when there are multiple views. + Bug #3388159. +
  • +
  • + Calltips may be displayed above the text as well as below. + Bug #3410830. +
  • +
  • + For huge files SciTE only examines the first megabyte for newline discovery. +
  • +
  • + SciTE on GTK+ removes the fileselector.show.hidden property and check box as this was buggy and GTK+ now + supports an equivalent feature. + Bug #3413630. +
  • +
  • + SciTE on GTK+ supports mnemonics in dynamic menus. +
  • +
  • + SciTE on GTK+ displays the user's home directory as '~' in menus to make them shorter. +
  • +
+

+ Release 2.29 +

+
    +
  • + Released 16 September 2011. +
  • +
  • + To automatically discover the encoding of a file when opening it, SciTE can run a program set with command.discover.properties. + Feature #3324341. +
  • +
  • + Cairo always used for drawing on GTK+. +
  • +
  • + The set of properties files imported by SciTE can be controlled with the properties imports.include and imports.exclude. + The import statement has been extended to allow "import *". + The properties files for some languages are no longer automatically loaded by default. The properties files affected are + avenue, baan, escript, lot, metapost, and mmixal. +
  • +
  • + C++ lexer fixed a bug with raw strings being recognised too easily. + Bug #3388122. +
  • +
  • + LaTeX lexer improved with more states and fixes to most outstanding bugs. + Bug #1493111. + Bug #1856356. + Bug #3081692. +
  • +
  • + Lua lexer updates for Lua 5.2 beta with goto labels and "\z" string escape. + Feature #3386330. +
  • +
  • + Perl string styling highlights interpolated variables. + Feature #3394258. + Bug #3076629. +
  • +
  • + Perl lexer updated for Perl 5.14.0 with 0X and 0B numeric literal prefixes, break keyword and "+" supported in subroutine prototypes. + Feature #3388802. +
  • +
  • + Perl bug fixed with CRLF line endings. +
  • +
  • + Markdown lexer fixed to not change state with "_" in middle of word. + Bug #3398184. +
  • +
  • + Cocoa restores compatibility with OS X 10.5. +
  • +
  • + Mouse pointer changes over selection to an arrow near start when scrolled horizontally. + Bug #3389055. +
  • +
  • + Indicators that finish at the end of the document no longer expand when text is appended. + Bug #3378718. +
  • +
  • + SparseState merge fixed to check if other range is empty. + Bug #3387053. +
  • +
  • + On Windows, autocompletion lists will scroll instead of document when mouse wheel spun. + Feature #3403600. +
  • +
  • + SciTE performs more rapid polling for command completion so will return faster and report more accurate times. +
  • +
  • + SciTE resizes panes proportionally when switched between horizontal and vertical layout. + Feature #3376784. +
  • +
  • + SciTE on GTK+ opens multiple files into a single instance more reliably. + Bug #3363754. +
  • +
+

+ Release 2.28 +

+
    +
  • + Released 1 August 2011. +
  • +
  • + GTK+ Cairo support works back to GTK+ version 2.8. Requires changing Scintilla source code to enable before GTK+ 2.22. + Bug #3322351. +
  • +
  • + Translucent images in RGBA format can be used for margin markers and in autocompletion lists. +
  • +
  • + INDIC_DOTBOX added as a translucent dotted rectangular indicator. +
  • +
  • + Asian text input using IME works for GTK+ 3.x and GTK+ 2.x with Cairo. +
  • +
  • + On GTK+, IME works for Ctrl+Shift+U Unicode input in Scintilla. For SciTE, Ctrl+Shift+U is still Make Selection Uppercase. +
  • +
  • + Key bindings for GTK+ on OS X made compatible with Cocoa port and platform conventions. +
  • +
  • + Cocoa port supports different character encodings, improves scrolling performance and drag image appearance. + The control ID is included in WM_COMMAND notifications. Text may be deleted by dragging to the trash. + ScrollToStart and ScrollToEnd key commands added to simplify implementation of standard OS X Home and End + behaviour. +
  • +
  • + SciTE on GTK+ uses a paned widget to contain the edit and output panes instead of custom code. + This allows the divider to be moved easily on GTK+ 3 and its appearance follows GTK+ conventions more closely. +
  • +
  • + SciTE builds and installs on BSD. + Bug #3324644. +
  • +
  • + Cobol supports fixed format comments. + Bug #3014850. +
  • +
  • + Mako template language block syntax extended and ## comments recognised. + Feature #3325178. + Bug #3318818. +
  • +
  • + Folding of Mako template language within HTML fixed. + Bug #3324563. +
  • +
  • + Python lexer has lexer.python.keywords2.no.sub.identifiers option to avoid highlighting second set of + keywords following '.'. + Bug #3325333. +
  • +
  • + Python folder fixes bug where fold would not extend to final line. + Bug #3349157. +
  • +
  • + SciTE treats LPEG lexers the same as script lexers by setting all 8 style bits. +
  • +
  • + For Cocoa, crashes with unsupported font variants and memory leaks for colour objects fixed. +
  • +
  • + Shift-JIS lead byte ranges modified to match Windows. +
  • +
  • + Mouse pointer changes over selection to an arrow more consistently. + Bug #3315756. +
  • +
  • + Bug fixed with annotations beyond end of document. + Bug #3347268. +
  • +
  • + Incorrect drawing fixed for combination of background colour change and translucent selection. + Bug #3377116. +
  • +
  • + Lexers initialized correctly when started at position other than start of line. + Bug #3377148. +
  • +
  • + Fold highlight drawing fixed for some situations. + Bug #3323015. + Bug #3323805. +
  • +
  • + Case insensitive search fixed for cases where folded character uses fewer bytes than base character. + Bug #3362038. +
  • +
  • + SciTE bookmark.alpha setting fixed. + Bug #3373907. +
  • +

Release 2.27

@@ -826,7 +2484,7 @@ Performance improved when creating large rectangular selections.
  • - PHP folder recognizes #region and #endregion comments. + PHP folder recognises #region and #endregion comments. Feature #3101624.
  • @@ -835,7 +2493,7 @@ Feature #3098071.
  • - SQL folder recognizes case statements and understands the fold.at.else property. + SQL folder recognises case statements and understands the fold.at.else property. Bug #3104091. Bug #3107362.
  • @@ -929,7 +2587,7 @@ Bug #3058924.
  • - JavaScript lexer recognize regexes following return keyword.‎ + JavaScript lexer recognise regexes following return keyword.‎ Bug #3062287.
  • @@ -1392,7 +3050,7 @@
  • Erlang lexer extended set of numeric bases recognised; separate style for module:function_name; detects - built-in functions, known module attributes, and known preprocessor instructions; recognizes EDoc and EDoc macros; + built-in functions, known module attributes, and known preprocessor instructions; recognises EDoc and EDoc macros; separates types of comments. Bug #2942448.
  • @@ -2345,7 +4003,7 @@ Style changes may be made during text modification events.
  • - Regular expressions recognize \d, \D, \s, \S, \w, \W, and \xHH. + Regular expressions recognise \d, \D, \s, \S, \w, \W, and \xHH.
  • Support for cmake language added. diff --git a/scintilla/doc/ScintillaRelated.html b/scintilla/doc/ScintillaRelated.html index f060ce0f..956f8055 100644 --- a/scintilla/doc/ScintillaRelated.html +++ b/scintilla/doc/ScintillaRelated.html @@ -28,6 +28,18 @@

    Ports and Bindings of Scintilla

    +

    + Scinterm + is an implementation of Scintilla for the ncurses platform. +

    +

    + Scintilla.mcc + is a port to MorphOS. +

    +

    + Wx::Scintilla + is a Perl Binding for Scintilla on wxWidgets. +

    GtkScintilla is a GTK+ widget which enables easily adding a powerful @@ -114,6 +126,40 @@

    Projects using Scintilla

    +

    + SciTECO + is an advanced TECO dialect and interactive screen editor based on Scintilla. +

    +

    + Quantum GIS + is a user friendly Open Source Geographic Information System (GIS). +

    +

    + QGrinUI + searches for a regex within all relevant files in a directory and shows matches using + SciTE through the director interface. +

    +

    + Textadept + is a ridiculously extensible cross-platform text editor for programmers written (mostly) in + Lua using LPeg to handle the lexers. +

    +

    + Scribble + is a text editor included in MorphOS. +

    +

    + MySQL Workbench + is a cross-platform, visual database design, sql coding and administration tool. +

    +

    + LIVEditor + is for web front end coders editing html/css/js code. +

    +

    + Padre + is a wxWidgets-based Perl IDE. +

    CoderStudio is an IDE for Assembly programming similar to Visual Studio 6.0. @@ -148,7 +194,7 @@ is a basic Lisp editor for Windows 2000, XP and Vista.

    - FlexEdit + FlexEdit is Free Text/Hex Editor for Windows.

    @@ -408,6 +454,10 @@

    Editing Components

    +

    + UniCodeEditor + is a Unicode aware syntax editor control for Delphi and C++ Builder. +

    GtkSourceView is a text widget that extends the standard GTK+ 2.x text widget and improves it diff --git a/scintilla/doc/ScintillaToDo.html b/scintilla/doc/ScintillaToDo.html index 972d95c4..17b93077 100644 --- a/scintilla/doc/ScintillaToDo.html +++ b/scintilla/doc/ScintillaToDo.html @@ -29,31 +29,15 @@ Feedback

    - Issues can be reported on the Bug Tracker - and features requested on the Feature Request Tracker. + Issues can be reported on the Bug Tracker + and features requested on the Feature Request Tracker.

    Scintilla Bugs

    -

    - At the end of italics style runs characters can be chopped off. An example - is using Verdana 12 point italics for strings makes an ending double quote - half visible and an ending single quote invisible. This is hard to solve - completely, may be better to avoid these situations by, for example, - choosing a font like Times New Roman for strings. There is a specific kluge - for the end of line which adds some room for italics but this does not - work elsewhere. -

    -

    - Dragging over bold text in some fonts will ripple because of the difference in - size between drawing all of a string at once and drawing it in parts. -

    Automatic scrolling when text dragged near edge of window.

    -

    - GTK+ Version Bugs -

    Scintilla To Do

    @@ -72,16 +56,9 @@ Composition of lexing for mixed languages (such as ASP+ over COBOL) by combining lexers.

    -

    - Printing support on GTK+. Maybe Postscript output or use Gnome? -

    Stream folding which could be used to fold up the contents of HTML elements.

    -

    - Persisting view state such as current folding into a stream or blob so it is easy - to restore. -

    Printing of highlight lines and folding margin.

    @@ -89,12 +66,6 @@ Flow diagrams inside editor similar to GRASP.

    -

    - A VCL component wrapper around Scintilla so it can be used with Delphi or - Borland C++ Builder. - There is some work - on this available. -

    More lexers for other languages.

    diff --git a/scintilla/doc/index.html b/scintilla/doc/index.html index 03830294..357fc489 100644 --- a/scintilla/doc/index.html +++ b/scintilla/doc/index.html @@ -9,7 +9,7 @@ - +