From 10dc4e06d749a167ec4562f86030ff3686fdd296 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Sun, 17 Jul 2011 22:30:49 +0000 Subject: [PATCH] [UPDATE] Update Scintilla to 2.27. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@791 f5eea248-9336-0410-98b8-ebc06183d4e3 --- scintilla/cocoa/InfoBar.mm | 2 +- scintilla/cocoa/PlatCocoa.h | 6 +- scintilla/cocoa/PlatCocoa.mm | 1456 ++++++++--------- scintilla/cocoa/QuartzTextLayout.h | 150 +- scintilla/cocoa/QuartzTextStyle.h | 112 +- scintilla/cocoa/QuartzTextStyleAttribute.h | 145 +- scintilla/cocoa/ScintillaCallTip.h | 63 - scintilla/cocoa/ScintillaCallTip.mm | 117 -- scintilla/cocoa/ScintillaCocoa.h | 11 +- scintilla/cocoa/ScintillaCocoa.mm | 379 +++-- .../project.pbxproj | 4 + scintilla/cocoa/ScintillaListBox.h | 64 - scintilla/cocoa/ScintillaListBox.mm | 110 -- .../ScintillaTest.xcodeproj/project.pbxproj | 16 +- scintilla/cocoa/ScintillaView.h | 2 + scintilla/cocoa/ScintillaView.mm | 71 +- scintilla/doc/SciCoding.html | 88 +- scintilla/doc/ScintillaDoc.html | 245 ++- scintilla/doc/ScintillaDownload.html | 10 +- scintilla/doc/ScintillaHistory.html | 255 +++ scintilla/doc/ScintillaRelated.html | 15 +- scintilla/doc/index.html | 14 +- scintilla/gtk/PlatGTK.cxx | 181 +- scintilla/gtk/ScintillaGTK.cxx | 583 +++++-- scintilla/gtk/makefile | 16 +- scintilla/include/Platform.h | 9 +- scintilla/include/Scintilla.h | 40 +- scintilla/include/Scintilla.iface | 62 +- scintilla/lexers/LexCPP.cxx | 43 +- scintilla/lexers/LexHTML.cxx | 65 +- scintilla/lexers/LexInno.cxx | 11 +- scintilla/lexers/LexLua.cxx | 43 +- scintilla/lexers/LexMatlab.cxx | 12 +- scintilla/lexers/LexOthers.cxx | 10 +- scintilla/lexers/LexPerl.cxx | 979 ++++++----- scintilla/lexers/LexPython.cxx | 14 +- scintilla/lexers/LexSQL.cxx | 22 +- scintilla/lexers/LexVerilog.cxx | 30 +- scintilla/lexlib/CharacterSet.h | 1 - scintilla/lexlib/SparseState.h | 4 +- scintilla/macosx/PlatMacOSX.cxx | 33 +- scintilla/macosx/makefile | 2 +- scintilla/src/CallTip.cxx | 2 +- scintilla/src/ContractionState.cxx | 8 + scintilla/src/ContractionState.h | 1 + scintilla/src/Decoration.cxx | 2 +- scintilla/src/Document.cxx | 169 +- scintilla/src/Document.h | 45 +- scintilla/src/Editor.cxx | 482 ++++-- scintilla/src/Editor.h | 19 +- scintilla/src/Indicator.cxx | 29 +- scintilla/src/Indicator.h | 3 +- scintilla/src/LineMarker.cxx | 140 +- scintilla/src/LineMarker.h | 11 +- scintilla/src/PositionCache.cxx | 74 +- scintilla/src/PositionCache.h | 23 +- scintilla/src/RESearch.cxx | 6 +- scintilla/src/RunStyles.cxx | 34 +- scintilla/src/RunStyles.h | 8 +- scintilla/src/ScintillaBase.cxx | 7 +- scintilla/src/Style.cxx | 146 +- scintilla/src/Style.h | 64 +- scintilla/src/ViewStyle.cxx | 132 +- scintilla/src/ViewStyle.h | 20 + scintilla/version.txt | 2 +- scintilla/win32/PlatWin.cxx | 5 +- scintilla/win32/ScintRes.rc | 8 +- scintilla/win32/ScintillaWin.cxx | 47 +- 68 files changed, 4317 insertions(+), 2665 deletions(-) delete mode 100644 scintilla/cocoa/ScintillaCallTip.h delete mode 100644 scintilla/cocoa/ScintillaCallTip.mm delete mode 100644 scintilla/cocoa/ScintillaListBox.h delete mode 100644 scintilla/cocoa/ScintillaListBox.mm diff --git a/scintilla/cocoa/InfoBar.mm b/scintilla/cocoa/InfoBar.mm index 27b9aa12..dccafa7e 100644 --- a/scintilla/cocoa/InfoBar.mm +++ b/scintilla/cocoa/InfoBar.mm @@ -46,7 +46,7 @@ //-------------------------------------------------------------------------------------------------- - (void) selectWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj - delegate:(id) anObject start: (int) selStart length: (int) selLength + delegate:(id) anObject start: (NSInteger) selStart length: (NSInteger) selLength { aRect = [self drawingRectForBounds: aRect]; mIsEditingOrSelecting = YES; diff --git a/scintilla/cocoa/PlatCocoa.h b/scintilla/cocoa/PlatCocoa.h index a85462e8..f84e3ff6 100644 --- a/scintilla/cocoa/PlatCocoa.h +++ b/scintilla/cocoa/PlatCocoa.h @@ -23,6 +23,7 @@ NSRect PRectangleToNSRect(Scintilla::PRectangle& rc); Scintilla::PRectangle NSRectToPRectangle(NSRect& rc); +CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet); @interface ScintillaContextMenu : NSMenu { @@ -47,6 +48,9 @@ private: /** The text layout instance */ QuartzTextLayout* textLayout; + int codePage; + int verticalDeviceResolution; + /** If the surface is a bitmap context, contains a reference to the bitmap data. */ uint8_t* bitmapData; /** If the surface is a bitmap context, stores the dimensions of the bitmap. */ @@ -111,7 +115,7 @@ public: void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); - void SetDBCSMode(int codePage); + void SetDBCSMode(int codePage_); }; // SurfaceImpl class } // Scintilla namespace diff --git a/scintilla/cocoa/PlatCocoa.mm b/scintilla/cocoa/PlatCocoa.mm index ffaa48fe..f777a0db 100644 --- a/scintilla/cocoa/PlatCocoa.mm +++ b/scintilla/cocoa/PlatCocoa.mm @@ -22,6 +22,7 @@ #include #include #include +#include #include "XPM.h" @@ -156,23 +157,15 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b int extraFontFlag) { // TODO: How should I handle the characterSet request? - Release(); - - QuartzTextStyle* style = new QuartzTextStyle(); - fid = style; - - // Find the font - QuartzFont font(faceName, strlen(faceName)); - - // We set Font, Size, Bold, Italic - QuartzTextSize textSize(size); - QuartzTextBold isBold(bold); - QuartzTextItalic isItalic(italic); - - // Actually set the attributes - QuartzTextStyleAttribute* attributes[] = { &font, &textSize, &isBold, &isItalic }; - style->setAttributes(attributes, sizeof(attributes) / sizeof(*attributes)); - style->setFontFeature(kLigaturesType, kCommonLigaturesOffSelector); + Release(); + + QuartzTextStyle* style = new QuartzTextStyle(); + fid = style; + + // Create the font with attributes + QuartzFont font(faceName, strlen(faceName), size, bold, italic); + CTFontRef fontRef = font.getFontID(); + style->setFontRef(fontRef); } //-------------------------------------------------------------------------------------------------- @@ -188,9 +181,19 @@ void Font::Release() SurfaceImpl::SurfaceImpl() { - bitmapData = NULL; // Release will try and delete bitmapData if != NULL + unicodeMode = true; + x = 0; + y = 0; gc = NULL; + textLayout = new QuartzTextLayout(NULL); + codePage = 0; + verticalDeviceResolution = 0; + + bitmapData = NULL; // Release will try and delete bitmapData if != NULL + bitmapWidth = 0; + bitmapHeight = 0; + Release(); } @@ -391,9 +394,13 @@ CGImageRef SurfaceImpl::GetImage() */ int SurfaceImpl::LogPixelsY() { - NSSize deviceResolution = [[[[NSScreen mainScreen] deviceDescription] - objectForKey: NSDeviceResolution] sizeValue]; - return (int) deviceResolution.height; + if (verticalDeviceResolution == 0) + { + NSSize deviceResolution = [[[[NSScreen mainScreen] deviceDescription] + objectForKey: NSDeviceResolution] sizeValue]; + verticalDeviceResolution = (int) deviceResolution.height; + } + return verticalDeviceResolution; } //-------------------------------------------------------------------------------------------------- @@ -542,7 +549,7 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) // Unlike the documentation, you MUST pass in a "components" parameter: // For coloured patterns it is the alpha value. - const float alpha = 1.0; + const CGFloat alpha = 1.0; CGContextSetFillPattern( gc, pattern, &alpha ); CGContextFillRect( gc, PRectangleToCGRect( rc ) ); CGContextRestoreGState( gc ); @@ -771,81 +778,109 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const c //-------------------------------------------------------------------------------------------------- +CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet) +{ + if (unicode) + return kCFStringEncodingUTF8; + + // Unsupported -> Latin1 as reasonably safe + enum { notSupported = kCFStringEncodingISOLatin1}; + + switch (characterSet) + { + case SC_CHARSET_ANSI: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_DEFAULT: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_BALTIC: + return kCFStringEncodingWindowsBalticRim; + case SC_CHARSET_CHINESEBIG5: + return kCFStringEncodingBig5; + case SC_CHARSET_EASTEUROPE: + return kCFStringEncodingWindowsLatin2; + case SC_CHARSET_GB2312: + return kCFStringEncodingGB_18030_2000; + case SC_CHARSET_GREEK: + return kCFStringEncodingWindowsGreek; + case SC_CHARSET_HANGUL: + return kCFStringEncodingEUC_KR; + case SC_CHARSET_MAC: + return kCFStringEncodingMacRoman; + case SC_CHARSET_OEM: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_RUSSIAN: + return kCFStringEncodingKOI8_R; + case SC_CHARSET_CYRILLIC: + return kCFStringEncodingWindowsCyrillic; + case SC_CHARSET_SHIFTJIS: + return kCFStringEncodingShiftJIS; + case SC_CHARSET_SYMBOL: + return kCFStringEncodingMacSymbol; + case SC_CHARSET_TURKISH: + return kCFStringEncodingWindowsLatin5; + case SC_CHARSET_JOHAB: + return kCFStringEncodingWindowsKoreanJohab; + case SC_CHARSET_HEBREW: + return kCFStringEncodingWindowsHebrew; + case SC_CHARSET_ARABIC: + return kCFStringEncodingWindowsArabic; + case SC_CHARSET_VIETNAMESE: + return kCFStringEncodingWindowsVietnamese; + case SC_CHARSET_THAI: + return kCFStringEncodingISOLatinThai; + case SC_CHARSET_8859_15: + return kCFStringEncodingISOLatin1; + default: + return notSupported; + } +} + void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore) { - textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); - - // The Quartz RGB fill color influences the ATSUI color - FillColour(fore); - - // Draw text vertically flipped as OS X uses a coordinate system where +Y is upwards. - textLayout->draw(rc.left, ybase, true); + ColourDesired colour(fore.AsLong()); + CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0,colour.GetGreen()/255.0,colour.GetBlue()/255.0,1.0); + + QuartzTextStyle* style = reinterpret_cast(font_.GetID()); + style->setCTStyleColor(color); + + textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + textLayout->draw(rc.left, ybase); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { - // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html - // sample includes use of ATSUGetGlyphInfo which would be better for older - // OSX systems. We should expand to using that on older systems as well. - for (int i = 0; i < len; i++) - positions [i] = 0; - - // We need the right X coords, so we have to append a char to get the left coord of thast extra char - char* buf = (char*) malloc (len+1); - if (!buf) - return; - - memcpy (buf, s, len); - buf [len] = '.'; - - textLayout->setText (reinterpret_cast(buf), len+1, *reinterpret_cast(font_.GetID())); - ATSUGlyphInfoArray* theGlyphInfoArrayPtr; - ByteCount theArraySize; - - // Get the GlyphInfoArray - ATSUTextLayout layout = textLayout->getLayout(); - if ( noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, NULL)) - { - theGlyphInfoArrayPtr = (ATSUGlyphInfoArray *) malloc (theArraySize + sizeof(ItemCount) + sizeof(ATSUTextLayout)); - if (theGlyphInfoArrayPtr) - { - if (noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, theGlyphInfoArrayPtr)) - { - // do not count the first item, which is at the beginning of the line - for ( UniCharCount unicodePosition = 1, i = 0; i < len && unicodePosition < theGlyphInfoArrayPtr->numGlyphs; unicodePosition ++ ) - { - // The ideal position is the x coordinate of the glyph, relative to the beginning of the line - int position = (int)( theGlyphInfoArrayPtr->glyphs[unicodePosition].idealX + 0.5 ); // These older APIs return float values - unsigned char uch = s[i]; - positions[i++] = position; - - // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters, - // as 1 unicode character can map to multiple UTF8 characters. - // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF - // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html - if ( unicodeMode ) - { - unsigned char mask = 0xc0; - int count = 1; - // Add one additonal byte for each extra high order one in the byte - while ( uch >= mask && count < 8 ) - { - positions[i++] = position; - count ++; - mask = mask >> 1 | 0x80; // add an additional one in the highest order position - } - } - } - } - - // Free the GlyphInfoArray - free (theGlyphInfoArrayPtr); - } - } - free (buf); + for (int i = 0; i < len; i++) + positions [i] = 0; + textLayout->setText (reinterpret_cast(s), len, *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 + } + } + positions[i] = (int)(advance+0.5); + unicodeCharStart++; + } } int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { @@ -853,19 +888,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { { textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); - // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? - unsigned long actualNumberOfBounds = 0; - ATSTrapezoid glyphBounds; - - // We get a single bound, since the text should only require one. If it requires more, there is an issue - if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) - { - Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" ); - return 0; - } - - //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) ); - return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + return textLayout->MeasureStringWidth(); } return 1; } @@ -876,32 +899,12 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) { { textLayout->setText (reinterpret_cast(str), 1, *reinterpret_cast(font_.GetID())); - // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? - unsigned long actualNumberOfBounds = 0; - ATSTrapezoid glyphBounds; - - // We get a single bound, since the text should only require one. If it requires more, there is an issue - if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) - { - Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" ); - return 0; - } - - return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + return textLayout->MeasureStringWidth(); } else return 1; } -// Three possible strategies for determining ascent and descent of font: -// 1) Call ATSUGetGlyphBounds with string containing all letters, numbers and punctuation. -// 2) Use the ascent and descent fields of the font. -// 3) Call ATSUGetGlyphBounds with string as 1 but also including accented capitals. -// Smallest values given by 1 and largest by 3 with 2 in between. -// Techniques 1 and 2 sometimes chop off extreme portions of ascenders and -// descenders but are mostly OK except for accented characters which are -// rarely used in code. - // This string contains a good range of characters to test for size. const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -910,16 +913,18 @@ int SurfaceImpl::Ascent(Font &font_) { if (!font_.GetID()) return 1; - ATSUTextMeasurement ascent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUAscentTag ); - return Fix2Long( ascent ); + float ascent = reinterpret_cast( font_.GetID() )->getAscent(); + return ascent + 0.5; + } int SurfaceImpl::Descent(Font &font_) { if (!font_.GetID()) return 1; - ATSUTextMeasurement descent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUDescentTag ); - return Fix2Long( descent ); + float descent = reinterpret_cast( font_.GetID() )->getDescent(); + return descent + 0.5; + } int SurfaceImpl::InternalLeading(Font &) { @@ -932,12 +937,15 @@ int SurfaceImpl::ExternalLeading(Font &font_) { if (!font_.GetID()) return 1; - ATSUTextMeasurement lineGap = reinterpret_cast( font_.GetID() )->getAttribute( kATSULeadingTag ); - return Fix2Long( lineGap ); + float leading = reinterpret_cast( font_.GetID() )->getLeading(); + return leading + 0.5; + } int SurfaceImpl::Height(Font &font_) { - return Ascent(font_) + Descent(font_); + + int ht = Ascent(font_) + Descent(font_); + return ht; } int SurfaceImpl::AverageCharWidth(Font &font_) { @@ -949,29 +957,6 @@ int SurfaceImpl::AverageCharWidth(Font &font_) { int width = WidthText( font_, sizeString, sizeStringLength ); return (int) ((width / (float) sizeStringLength) + 0.5); - - /* - ATSUStyle textStyle = reinterpret_cast( font_.GetID() )->getATSUStyle(); - ATSUFontID fontID; - - ByteCount actualSize = 0; - if ( ATSUGetAttribute( textStyle, kATSUFontTag, sizeof( fontID ), &fontID, &actualSize ) != noErr ) - { - Platform::DebugDisplay( "ATSUGetAttribute failed" ); - return 1; - } - - ATSFontMetrics metrics; - memset( &metrics, 0, sizeof( metrics ) ); - if ( ATSFontGetHorizontalMetrics( fontID, kATSOptionFlagsDefault, &metrics ) != noErr ) - { - Platform::DebugDisplay( "ATSFontGetHorizontalMetrics failed in AverageCharWidth" ); - return 1; - } - - printf( "%f %f %f\n", metrics.avgAdvanceWidth * 32, metrics.ascent * 32, metrics.descent * 32 ); - - return (int) (metrics.avgAdvanceWidth + 0.5);*/ } int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) { @@ -991,8 +976,9 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { unicodeMode = unicodeMode_; } -void SurfaceImpl::SetDBCSMode(int codePage) { - // TODO: Implement this for code pages != UTF-8 +void SurfaceImpl::SetDBCSMode(int codePage_) { + if (codePage_ && (codePage_ != SC_CP_UTF8)) + codePage = codePage_; } Surface *Surface::Allocate() @@ -1002,16 +988,26 @@ Surface *Surface::Allocate() //----------------- Window ------------------------------------------------------------------------- -Window::~Window() { +// Cocoa uses different types for windows and views, so a Window may +// be either an NSWindow or NSView and the code will check the type +// before performing an action. + +Window::~Window() +{ } //-------------------------------------------------------------------------------------------------- void Window::Destroy() { - if (windowRef) + if (wid) { - // not used + id idWin = reinterpret_cast(wid); + if ([idWin isKindOfClass: [NSWindow class]]) + { + NSWindow* win = reinterpret_cast(idWin); + [win release]; + } } wid = 0; } @@ -1026,62 +1022,85 @@ bool Window::HasFocus() //-------------------------------------------------------------------------------------------------- +static int ScreenMax(NSWindow* win) +{ + NSScreen* screen = [win screen]; + NSRect frame = [screen frame]; + return frame.origin.y + frame.size.height; +} + PRectangle Window::GetPosition() { - NSRect rect= [reinterpret_cast(wid) frame]; - - return PRectangle(NSMinX(rect), NSMinY(rect), NSMaxX(rect), NSMaxY(rect)); + if (wid) + { + NSRect rect; + id idWin = reinterpret_cast(wid); + NSWindow* win; + if ([idWin isKindOfClass: [NSView class]]) + { + // NSView + NSView* view = reinterpret_cast(idWin); + win = [view window]; + rect = [view bounds]; + rect = [view convertRectToBase: rect]; + rect.origin = [win convertBaseToScreen:rect.origin]; + } + else + { + // NSWindow + win = reinterpret_cast(idWin); + rect = [win frame]; + } + int screenHeight = ScreenMax(win); + // Invert screen positions to match Scintilla + return PRectangle( + NSMinX(rect), screenHeight - NSMaxY(rect), + NSMaxX(rect), screenHeight - NSMinY(rect)); + } + else + { + return PRectangle(0, 0, 1, 1); + } } //-------------------------------------------------------------------------------------------------- void Window::SetPosition(PRectangle rc) { - // Moves this view inside the parent view - if ( wid ) + if (wid) { - // Set the frame on the view, the function handles the rest - // CGRect r = PRectangleToCGRect( rc ); - // HIViewSetFrame( reinterpret_cast( wid ), &r ); + id idWin = reinterpret_cast(wid); + if ([idWin isKindOfClass: [NSView class]]) + { + // NSView + // Moves this view inside the parent view + NSRect nsrc = NSMakeRect(rc.left, rc.bottom, rc.Width(), rc.Height()); + NSView* view = reinterpret_cast(idWin); + nsrc.origin = [[view window] convertScreenToBase:nsrc.origin]; + [view setFrame: nsrc]; + } + else + { + // NSWindow + NSWindow* win = reinterpret_cast(idWin); + int screenHeight = ScreenMax(win); + NSRect nsrc = NSMakeRect(rc.left, screenHeight - rc.bottom, + rc.Width(), rc.Height()); + [win setFrame: nsrc display:YES]; + } } } //-------------------------------------------------------------------------------------------------- -void Window::SetPositionRelative(PRectangle rc, Window window) { - // // used to actually move child windows (ie. listbox/calltip) so we have to move - // // the window, not the hiview - // if (windowRef) { - // // we go through some contortions here to get an accurate location for our - // // child windows. This is necessary due to the multiple ways an embedding - // // app may be setup. See SciTest/main.c (GOOD && BAD) for test case. - // WindowRef relativeWindow = GetControlOwner(reinterpret_cast( window.GetID() )); - // WindowRef thisWindow = reinterpret_cast( windowRef ); - // - // Rect portBounds; - // ::GetWindowBounds(relativeWindow, kWindowStructureRgn, &portBounds); - // //fprintf(stderr, "portBounds %d %d %d %d\n", portBounds.left, portBounds.top, portBounds.right, portBounds.bottom); - // PRectangle hbounds = window.GetPosition(); - // //fprintf(stderr, "hbounds %d %d %d %d\n", hbounds.left, hbounds.top, hbounds.right, hbounds.bottom); - // HIViewRef parent = HIViewGetSuperview(reinterpret_cast( window.GetID() )); - // Rect pbounds; - // GetControlBounds(parent, &pbounds); - // //fprintf(stderr, "pbounds %d %d %d %d\n", pbounds.left, pbounds.top, pbounds.right, pbounds.bottom); - // - // PRectangle bounds; - // bounds.top = portBounds.top + pbounds.top + hbounds.top + rc.top; - // bounds.bottom = bounds.top + rc.Height(); - // bounds.left = portBounds.left + pbounds.left + hbounds.left + rc.left; - // bounds.right = bounds.left + rc.Width(); - // //fprintf(stderr, "bounds %d %d %d %d\n", bounds.left, bounds.top, bounds.right, bounds.bottom); - // - // MoveWindow(thisWindow, bounds.left, bounds.top, false); - // SizeWindow(thisWindow, bounds.Width(), bounds.Height(), true); - // - // SetPosition(PRectangle(0,0,rc.Width(),rc.Height())); - // } else { - // SetPosition(rc); - // } +void Window::SetPositionRelative(PRectangle rc, Window window) +{ + PRectangle rcOther = window.GetPosition(); + rc.left += rcOther.left; + rc.right += rcOther.left; + rc.top += rcOther.top; + rc.bottom += rcOther.top; + SetPosition(rc); } //-------------------------------------------------------------------------------------------------- @@ -1096,30 +1115,46 @@ PRectangle Window::GetClientPosition() void Window::Show(bool show) { - // if ( wid ) { - // HIViewSetVisible( reinterpret_cast( wid ), show ); - // } - // // this is necessary for calltip/listbox - // if (windowRef) { - // WindowRef thisWindow = reinterpret_cast( windowRef ); - // if (show) { - // ShowWindow( thisWindow ); - // DrawControls( thisWindow ); - // } else - // HideWindow( thisWindow ); - // } + if (wid) + { + id idWin = reinterpret_cast(wid); + if ([idWin isKindOfClass: [NSWindow class]]) + { + NSWindow* win = reinterpret_cast(idWin); + if (show) + { + [win orderFront:nil]; + } + else + { + [win orderOut:nil]; + } + } + } } //-------------------------------------------------------------------------------------------------- /** - * Invalidates the entire window (here an NSView) so it is completely redrawn. + * Invalidates the entire window or view so it is completely redrawn. */ void Window::InvalidateAll() { if (wid) { - NSView* container = reinterpret_cast(wid); + id idWin = reinterpret_cast(wid); + NSView* container; + if ([idWin isKindOfClass: [NSView class]]) + { + container = reinterpret_cast(idWin); + } + else + { + // NSWindow + NSWindow* win = reinterpret_cast(idWin); + container = reinterpret_cast([win contentView]); + container.needsDisplay = YES; + } container.needsDisplay = YES; } } @@ -1127,22 +1162,33 @@ void Window::InvalidateAll() //-------------------------------------------------------------------------------------------------- /** - * Invalidates part of the window (here an NSView) so only this part redrawn. + * Invalidates part of the window or view so only this part redrawn. */ void Window::InvalidateRectangle(PRectangle rc) { if (wid) { - NSView* container = reinterpret_cast(wid); + id idWin = reinterpret_cast(wid); + NSView* container; + if ([idWin isKindOfClass: [NSView class]]) + { + container = reinterpret_cast(idWin); + } + else + { + // NSWindow + NSWindow* win = reinterpret_cast(idWin); + container = reinterpret_cast([win contentView]); + } [container setNeedsDisplayInRect: PRectangleToNSRect(rc)]; } } //-------------------------------------------------------------------------------------------------- -void Window::SetFont(Font &) +void Window::SetFont(Font&) { - // TODO: Do I need to implement this? MSDN: specifies the font that a control is to use when drawing text. + // Implemented on list subclass on Cocoa. } //-------------------------------------------------------------------------------------------------- @@ -1155,26 +1201,81 @@ void Window::SetCursor(Cursor curs) { if (wid) { - InnerView* container = reinterpret_cast(wid); - [container setCursor: curs]; + id idWin = reinterpret_cast(wid); + if ([idWin isMemberOfClass: [InnerView class]]) + { + InnerView* container = reinterpret_cast(idWin); + [container setCursor: curs]; + } } } //-------------------------------------------------------------------------------------------------- -void Window::SetTitle(const char *s) +void Window::SetTitle(const char* s) { - // WindowRef window = GetControlOwner(reinterpret_cast( wid )); - // CFStringRef title = CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingMacRoman); - // SetWindowTitleWithCFString(window, title); - // CFRelease(title); + if (wid) + { + id idWin = reinterpret_cast(wid); + if ([idWin isKindOfClass: [NSWindow class]]) + { + NSWindow* win = reinterpret_cast(idWin); + NSString* sTitle = [NSString stringWithUTF8String:s]; + [win setTitle:sTitle]; + } + } } //-------------------------------------------------------------------------------------------------- PRectangle Window::GetMonitorRect(Point) { - return PRectangle(); + if (wid) + { + id idWin = reinterpret_cast(wid); + if ([idWin isKindOfClass: [NSWindow class]]) + { + NSWindow* win = reinterpret_cast(idWin); + NSScreen* screen = [win screen]; + NSRect rect = [screen frame]; + int screenHeight = rect.origin.y + rect.size.height; + // Invert screen positions to match Scintilla + return PRectangle( + NSMinX(rect), screenHeight - NSMaxY(rect), + NSMaxX(rect), screenHeight - NSMinY(rect)); + } + } + return PRectangle(); +} + +//----------------- ImageFromXPM ------------------------------------------------------------------- + +// Convert an XPM image into an NSImage for use with Cocoa + +static NSImage* ImageFromXPM(XPM* pxpm) +{ + NSImage* img = nil; + if (pxpm) + { + const int width = pxpm->GetWidth(); + const int height = pxpm->GetHeight(); + PRectangle rcxpm(0, 0, width, height); + Surface* surfaceXPM = Surface::Allocate(); + 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]; + CGImageRef imageRef = surfaceIXPM->GetImage(); + [img initWithCGImage:imageRef size:NSZeroSize]; + CGImageRelease(imageRef); + delete surfaceXPM; + } + } + return img; } //----------------- ListBox ------------------------------------------------------------------------ @@ -1191,655 +1292,483 @@ ListBox::~ListBox() //-------------------------------------------------------------------------------------------------- -static const OSType scintillaListBoxType = 'sclb'; - -enum { - kItemsPerContainer = 1, - kIconColumn = 'icon', - kTextColumn = 'text' +struct RowData +{ + int type; + std::string text; + RowData(int type_, const char* text_) : + type(type_), text(text_) + { + } }; -static SInt32 kScrollBarWidth = 0; -class LineData { - int *types; - CFStringRef *strings; - int len; - int maximum; +class LinesData +{ + std::vector lines; public: - LineData() :types(0), strings(0), len(0), maximum(0) {} - ~LineData() { - Clear(); + LinesData() + { } - void Clear() { - delete []types; - types = 0; - for (int i=0; i= maximum) { - if (index >= len) { - int lenNew = (index+1) * 2; - int *typesNew = new int[lenNew]; - CFStringRef *stringsNew = new CFStringRef[lenNew]; - for (int i=0; i +{ + ListBoxImpl* box; +} + +@end + //----------------- ListBoxImpl -------------------------------------------------------------------- +// Map from icon type to an NSImage* +typedef std::map ImageMap; + class ListBoxImpl : public ListBox { private: ControlRef lb; - XPMSet xset; + ImageMap images; int lineHeight; bool unicodeMode; int desiredVisibleRows; unsigned int maxItemWidth; unsigned int aveCharWidth; + unsigned int maxIconWidth; Font font; int maxWidth; - - void InstallDataBrowserCustomCallbacks(); - void ConfigureDataBrowser(); - - static pascal OSStatus WindowEventHandler(EventHandlerCallRef inCallRef, - EventRef inEvent, - void *inUserData ); - EventHandlerRef eventHandler; - -protected: - WindowRef windowRef; - -public: - LineData ld; + + NSTableView* table; + NSScrollView* scroller; + NSTableColumn* colIcon; + NSTableColumn* colText; + + LinesData ld; CallBackAction doubleClickAction; - void *doubleClickActionData; - + void* doubleClickActionData; + +public: ListBoxImpl() : lb(NULL), lineHeight(10), unicodeMode(false), - desiredVisibleRows(5), maxItemWidth(0), aveCharWidth(8), - doubleClickAction(NULL), doubleClickActionData(NULL) + desiredVisibleRows(5), maxItemWidth(0), aveCharWidth(8), maxIconWidth(0), + doubleClickAction(NULL), doubleClickActionData(NULL) { - if (kScrollBarWidth == 0) - ;//GetThemeMetric(kThemeMetricScrollBarWidth, &kScrollBarWidth); } - ~ListBoxImpl() {}; - void SetFont(Font &font); - void Create(Window &parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_); + + // ListBox methods + void SetFont(Font& font); + void Create(Window& parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_); void SetAverageCharWidth(int width); void SetVisibleRows(int rows); int GetVisibleRows() const; PRectangle GetDesiredRect(); int CaretFromEdge(); void Clear(); - void Append(char *s, int type = -1); + void Append(char* s, int type = -1); int Length(); void Select(int n); int GetSelection(); - int Find(const char *prefix); - void GetValue(int n, char *value, int len); - void Sort(); - void RegisterImage(int type, const char *xpm_data); + int Find(const char* prefix); + void GetValue(int n, char* value, int len); + void RegisterImage(int type, const char* xpm_data); void ClearRegisteredImages(); - void SetDoubleClickAction(CallBackAction action, void *data) { + void SetDoubleClickAction(CallBackAction action, void* data) + { doubleClickAction = action; doubleClickActionData = data; } - - int IconWidth(); - void ShowHideScrollbar(); -#ifdef DB_TABLE_ROW_HEIGHT - void SetRowHeight(DataBrowserItemID itemID); -#endif - - void DrawRow(DataBrowserItemID item, - DataBrowserPropertyID property, - DataBrowserItemState itemState, - const Rect *theRect); - void SetList(const char* list, char separator, char typesep); + + // For access from AutoCompletionDataSource + int Rows(); + NSImage* ImageForRow(int row); + NSString* TextForRow(int row); + void DoubleClick(); }; -ListBox *ListBox::Allocate() { - ListBoxImpl *lb = new ListBoxImpl(); +@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_) { +void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt, + int lineHeight_, bool unicodeMode_) +{ lineHeight = lineHeight_; unicodeMode = unicodeMode_; maxWidth = 2000; - - //WindowClass windowClass = kHelpWindowClass; - //WindowAttributes attributes = kWindowNoAttributes; - Rect contentBounds; - WindowRef outWindow; - - contentBounds.top = contentBounds.left = 0; - contentBounds.right = 100; - contentBounds.bottom = lineHeight * desiredVisibleRows; - - //CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow); - - //InstallStandardEventHandler(GetWindowEventTarget(outWindow)); - - //ControlRef root; - //CreateRootControl(outWindow, &root); - - //CreateDataBrowserControl(outWindow, &contentBounds, kDataBrowserListView, &lb); - -#ifdef DB_TABLE_ROW_HEIGHT - // TODO: does not seem to have any effect - //SetDataBrowserTableViewRowHeight(lb, lineHeight); -#endif - - // get rid of the frame, forces databrowser to the full size - // of the window - //Boolean frameAndFocus = false; - //SetControlData(lb, kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, - // sizeof(frameAndFocus), &frameAndFocus); - - //ListBoxImpl* lbThis = this; - //SetControlProperty( lb, scintillaListBoxType, 0, sizeof( this ), &lbThis ); - - ConfigureDataBrowser(); - InstallDataBrowserCustomCallbacks(); - - // install event handlers - /* - static const EventTypeSpec kWindowEvents[] = - { - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseMoved }, - }; - */ - - eventHandler = NULL; - //InstallWindowEventHandler( outWindow, WindowEventHandler, - // GetEventTypeCount( kWindowEvents ), - // kWindowEvents, this, &eventHandler ); - - wid = lb; - //SetControlVisibility(lb, true, true); - SetControl(lb); - SetWindow(outWindow); + + NSRect lbRect = NSMakeRect(pt.x,pt.y, 120, lineHeight * desiredVisibleRows); + NSWindow* winLB = [[NSWindow alloc] initWithContentRect: lbRect + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + [winLB setLevel:NSFloatingWindowLevel]; + [winLB setHasShadow:YES]; + scroller = [NSScrollView alloc]; + NSRect scRect = NSMakeRect(0, 0, lbRect.size.width, lbRect.size.height); + [scroller initWithFrame: scRect]; + [scroller setHasVerticalScroller:YES]; + table = [NSTableView alloc]; + [table 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]; + [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 setBox:this]; + [table setDataSource: ds]; + [scroller setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [[winLB contentView] addSubview: scroller]; + + [table setTarget:ds]; + [table setDoubleAction:@selector(doubleClick:)]; + wid = winLB; } -pascal OSStatus ListBoxImpl::WindowEventHandler( - EventHandlerCallRef inCallRef, - EventRef inEvent, - void* inUserData ) +void ListBoxImpl::SetFont(Font& font_) { - - switch (kEventClassMouse /* GetEventClass(inEvent) */) { - case kEventClassMouse: - switch (kEventMouseDown /* GetEventKind(inEvent) */ ) - { - case kEventMouseMoved: - { - //SetThemeCursor( kThemeArrowCursor ); - break; - } - case kEventMouseDown: - { - // we cannot handle the double click from the databrowser notify callback as - // calling doubleClickAction causes the listbox to be destroyed. It is - // safe to do it from this event handler since the destroy event will be queued - // until we're done here. - /* - TCarbonEvent event( inEvent ); - EventMouseButton inMouseButton; - event.GetParameter( kEventParamMouseButton, typeMouseButton, &inMouseButton ); - - UInt32 inClickCount; - event.GetParameter( kEventParamClickCount, &inClickCount ); - if (inMouseButton == kEventMouseButtonPrimary && inClickCount == 2) { - // handle our single mouse click now - ListBoxImpl* listbox = reinterpret_cast( inUserData ); - const WindowRef window = GetControlOwner(listbox->lb); - const HIViewRef rootView = HIViewGetRoot( window ); - HIViewRef targetView = NULL; - HIViewGetViewForMouseEvent( rootView, inEvent, &targetView ); - if ( targetView == listbox->lb ) - { - if (listbox->doubleClickAction != NULL) { - listbox->doubleClickAction(listbox->doubleClickActionData); - } - } - } - */ - } - } - } - return eventNotHandledErr; + 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()); + NSFont *pfont = (NSFont *)style->getFontRef(); + [[colText dataCell] setFont: pfont]; + CGFloat itemHeight = lround([pfont ascender] - [pfont descender]); + [table setRowHeight:itemHeight]; } -#ifdef DB_TABLE_ROW_HEIGHT -void ListBoxImpl::SetRowHeight(DataBrowserItemID itemID) +void ListBoxImpl::SetAverageCharWidth(int width) { - // XXX does not seem to have any effect - //SetDataBrowserTableViewItemRowHeight(lb, itemID, lineHeight); -} -#endif - -void ListBoxImpl::DrawRow(DataBrowserItemID item, - DataBrowserPropertyID property, - DataBrowserItemState itemState, - const Rect *theRect) -{ - Rect row = *theRect; - row.left = 0; - - ColourPair fore; - - if (itemState == kDataBrowserItemIsSelected) { - long systemVersion; - Gestalt( gestaltSystemVersion, &systemVersion ); - // Panther DB starts using kThemeBrushSecondaryHighlightColor for inactive browser hilighting - if ( (systemVersion >= 0x00001030) )//&& (IsControlActive( lb ) == false) ) - ;//SetThemePen( kThemeBrushSecondaryHighlightColor, 32, true ); - else - ; //SetThemePen( kThemeBrushAlternatePrimaryHighlightColor, 32, true ); - - PaintRect(&row); - fore = ColourDesired(0xff,0xff,0xff); - } - - int widthPix = xset.GetWidth() + 2; - int pixId = ld.GetType(item - 1); - XPM *pxpm = xset.Get(pixId); - - char s[255]; - GetValue(item - 1, s, 255); - - Surface *surfaceItem = Surface::Allocate(); - if (surfaceItem) { - CGContextRef cgContext; - GrafPtr port; - Rect bounds; - - //GetControlBounds(lb, &bounds); - GetPort( &port ); - QDBeginCGContext( port, &cgContext ); - - CGContextSaveGState( cgContext ); - CGContextTranslateCTM(cgContext, 0, bounds.bottom - bounds.top); - CGContextScaleCTM(cgContext, 1.0, -1.0); - - surfaceItem->Init(cgContext, NULL); - - int left = row.left; - if (pxpm) { - PRectangle rc(left + 1, row.top, - left + 1 + widthPix, row.bottom); - pxpm->Draw(surfaceItem, rc); - } - - // draw the text - PRectangle trc(left + 2 + widthPix, row.top, row.right, row.bottom); - int ascent = surfaceItem->Ascent(font) - surfaceItem->InternalLeading(font); - int ytext = trc.top + ascent + 1; - trc.bottom = ytext + surfaceItem->Descent(font) + 1; - surfaceItem->DrawTextTransparent( trc, font, ytext, s, strlen(s), fore.allocated ); - - CGContextRestoreGState( cgContext ); - QDEndCGContext( port, &cgContext ); - delete surfaceItem; - } -} - - -pascal void ListBoxDrawItemCallback(ControlRef browser, DataBrowserItemID item, - DataBrowserPropertyID property, - DataBrowserItemState itemState, - const Rect *theRect, SInt16 gdDepth, - Boolean colorDevice) -{ - if (property != kIconColumn) return; - ListBoxImpl* lbThis = NULL; - //OSStatus err; - //err = GetControlProperty( browser, scintillaListBoxType, 0, sizeof( lbThis ), NULL, &lbThis ); - // adjust our rect - lbThis->DrawRow(item, property, itemState, theRect); - -} - -void ListBoxImpl::ConfigureDataBrowser() -{ - DataBrowserViewStyle viewStyle; - //DataBrowserSelectionFlags selectionFlags; - //GetDataBrowserViewStyle(lb, &viewStyle); - - //SetDataBrowserHasScrollBars(lb, false, true); - //SetDataBrowserListViewHeaderBtnHeight(lb, 0); - //GetDataBrowserSelectionFlags(lb, &selectionFlags); - //SetDataBrowserSelectionFlags(lb, selectionFlags |= kDataBrowserSelectOnlyOne); - // if you change the hilite style, also change the style in ListBoxDrawItemCallback - //SetDataBrowserTableViewHiliteStyle(lb, kDataBrowserTableViewFillHilite); - - Rect insetRect; - //GetDataBrowserScrollBarInset(lb, &insetRect); - - insetRect.right = kScrollBarWidth - 1; - //SetDataBrowserScrollBarInset(lb, &insetRect); - - switch (viewStyle) - { - case kDataBrowserListView: - { - DataBrowserListViewColumnDesc iconCol; - iconCol.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; - iconCol.headerBtnDesc.minimumWidth = 0; - iconCol.headerBtnDesc.maximumWidth = maxWidth; - iconCol.headerBtnDesc.titleOffset = 0; - iconCol.headerBtnDesc.titleString = NULL; - iconCol.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; - - iconCol.headerBtnDesc.btnFontStyle.flags = kControlUseJustMask; - iconCol.headerBtnDesc.btnFontStyle.just = teFlushLeft; - - iconCol.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; - - iconCol.propertyDesc.propertyID = kIconColumn; - iconCol.propertyDesc.propertyType = kDataBrowserCustomType; - iconCol.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; - - //AddDataBrowserListViewColumn(lb, &iconCol, kDataBrowserListViewAppendColumn); - } break; - - } -} - -void ListBoxImpl::InstallDataBrowserCustomCallbacks() -{ - /* - DataBrowserCustomCallbacks callbacks; - - callbacks.version = kDataBrowserLatestCustomCallbacks; - verify_noerr(InitDataBrowserCustomCallbacks(&callbacks)); - callbacks.u.v1.drawItemCallback = NewDataBrowserDrawItemUPP(ListBoxDrawItemCallback); - callbacks.u.v1.hitTestCallback = NULL;//NewDataBrowserHitTestUPP(ListBoxHitTestCallback); - callbacks.u.v1.trackingCallback = NULL;//NewDataBrowserTrackingUPP(ListBoxTrackingCallback); - callbacks.u.v1.editTextCallback = NULL; - callbacks.u.v1.dragRegionCallback = NULL; - callbacks.u.v1.acceptDragCallback = NULL; - callbacks.u.v1.receiveDragCallback = NULL; - - SetDataBrowserCustomCallbacks(lb, &callbacks); - */ -} - -void ListBoxImpl::SetFont(Font &font_) { - // Having to do this conversion is LAME - QuartzTextStyle *ts = reinterpret_cast( font_.GetID() ); - ControlFontStyleRec style; - ATSUAttributeValuePtr value; - ATSUFontID fontID; - style.flags = kControlUseFontMask | kControlUseSizeMask | kControlAddToMetaFontMask; - ts->getAttribute( kATSUFontTag, sizeof(fontID), &fontID, NULL ); - ATSUFontIDtoFOND(fontID, &style.font, NULL); - ts->getAttribute( kATSUSizeTag, sizeof(Fixed), &value, NULL ); - style.size = ((SInt16)FixRound((SInt32)value)); - //SetControlFontStyle(lb, &style); - -#ifdef DB_TABLE_ROW_HEIGHT - // XXX this doesn't *stick* - ATSUTextMeasurement ascent = ts->getAttribute( kATSUAscentTag ); - ATSUTextMeasurement descent = ts->getAttribute( kATSUDescentTag ); - lineHeight = Fix2Long( ascent ) + Fix2Long( descent ); - //SetDataBrowserTableViewRowHeight(lb, lineHeight + lineLeading); -#endif - - // !@&^#%$ we cant copy Font, but we need one for our custom drawing - Str255 fontName255; - char fontName[256]; - FMGetFontFamilyName(style.font, fontName255); - - CFStringRef fontNameCF = ::CFStringCreateWithPascalString( kCFAllocatorDefault, fontName255, kCFStringEncodingMacRoman ); - ::CFStringGetCString( fontNameCF, fontName, (CFIndex)255, kCFStringEncodingMacRoman ); - - font.Create((const char *)fontName, 0, style.size, false, false); -} - -void ListBoxImpl::SetAverageCharWidth(int width) { aveCharWidth = width; } -void ListBoxImpl::SetVisibleRows(int rows) { +void ListBoxImpl::SetVisibleRows(int rows) +{ desiredVisibleRows = rows; } -int ListBoxImpl::GetVisibleRows() const { - // XXX Windows & GTK do this, but it seems incorrect to me. Other logic - // to do with visible rows is essentially the same across platforms. +int ListBoxImpl::GetVisibleRows() const +{ return desiredVisibleRows; - /* - // This would be more correct - int rows = Length(); - if ((rows == 0) || (rows > desiredVisibleRows)) - rows = desiredVisibleRows; - return rows; - */ } -PRectangle ListBoxImpl::GetDesiredRect() { - PRectangle rcDesired = GetPosition(); - - // XXX because setting the line height on the table doesnt - // *stick*, we'll have to suffer and just use whatever - // the table desides is the correct height. - UInt16 itemHeight;// = lineHeight; - //GetDataBrowserTableViewRowHeight(lb, &itemHeight); - +PRectangle ListBoxImpl::GetDesiredRect() +{ + PRectangle rcDesired; + rcDesired = GetPosition(); + + // There appears to be an extra pixel above and below the row contents + int itemHeight = [table rowHeight] + 2; + int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) rows = desiredVisibleRows; - - rcDesired.bottom = itemHeight * rows; + + rcDesired.bottom = rcDesired.top + itemHeight * rows; rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; - - if (Length() > rows) - rcDesired.right += kScrollBarWidth; - rcDesired.right += IconWidth(); - - // Set the column width - //SetDataBrowserTableViewColumnWidth (lb, UInt16 (rcDesired.right - rcDesired.left)); + + if (Length() > rows) + { + [scroller setHasVerticalScroller:YES]; + rcDesired.right += [NSScroller scrollerWidth]; + } + else + { + [scroller setHasVerticalScroller:NO]; + } + rcDesired.right += maxIconWidth; + rcDesired.right += 6; + return rcDesired; } -void ListBoxImpl::ShowHideScrollbar() { - int rows = Length(); - if (rows > desiredVisibleRows) { - //SetDataBrowserHasScrollBars(lb, false, true); - } else { - //SetDataBrowserHasScrollBars(lb, false, false); +int ListBoxImpl::CaretFromEdge() +{ + if ([colIcon isHidden]) + return 3; + else + return 6 + [colIcon width]; +} + +void ListBoxImpl::Clear() +{ + maxItemWidth = 0; + maxIconWidth = 0; + ld.Clear(); +} + +void ListBoxImpl::Append(char* s, int type) +{ + int count = Length(); + ld.Add(count, type, s); + + Scintilla::SurfaceImpl surface; + unsigned int width = surface.WidthText(font, s, strlen(s)); + if (width > maxItemWidth) + { + maxItemWidth = width; + [colText setWidth: maxItemWidth]; + } + ImageMap::iterator it = images.find(type); + if (it != images.end()) + { + NSImage* img = it->second; + if (img) + { + unsigned int widthIcon = img.size.width; + if (widthIcon > maxIconWidth) + { + [colIcon setHidden: NO]; + maxIconWidth = widthIcon; + [colIcon setWidth: maxIconWidth]; + } + } } } -int ListBoxImpl::IconWidth() { - return xset.GetWidth() + 2; -} - -int ListBoxImpl::CaretFromEdge() { - return 0; -} - -void ListBoxImpl::Clear() { - // passing NULL to "items" arg 4 clears the list - maxItemWidth = 0; - ld.Clear(); - //AddDataBrowserItems (lb, kDataBrowserNoItem, 0, NULL, kDataBrowserItemNoProperty); -} - -void ListBoxImpl::Append(char *s, int type) { - int count = Length(); - CFStringRef r = CFStringCreateWithCString(NULL, s, kTextEncodingMacRoman); - ld.Add(count, type, r); - - Scintilla::SurfaceImpl surface; - unsigned int width = surface.WidthText (font, s, strlen (s)); - if (width > maxItemWidth) - maxItemWidth = width; - - DataBrowserItemID items[1]; - items[0] = count + 1; - //AddDataBrowserItems (lb, kDataBrowserNoItem, 1, items, kDataBrowserItemNoProperty); - ShowHideScrollbar(); -} - -void ListBoxImpl::SetList(const char* list, char separator, char typesep) { - // XXX copied from PlatGTK, should be in base class +void ListBoxImpl::SetList(const char* list, char separator, char typesep) +{ Clear(); int count = strlen(list) + 1; - char *words = new char[count]; - if (words) { + char* words = new char[count]; + if (words) + { memcpy(words, list, count); - char *startword = words; - char *numword = NULL; + char* startword = words; + char* numword = NULL; int i = 0; - for (; words[i]; i++) { - if (words[i] == separator) { + 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) { + } + else if (words[i] == typesep) + { numword = words + i; } } - if (startword) { + if (startword) + { if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); } delete []words; } + [table reloadData]; } -int ListBoxImpl::Length() { - UInt32 numItems = 0; - //GetDataBrowserItemCount(lb, kDataBrowserNoItem, false, kDataBrowserItemAnyState, &numItems); - return (int)numItems; +int ListBoxImpl::Length() +{ + return ld.Length(); } -void ListBoxImpl::Select(int n) { - DataBrowserItemID items[1]; - items[0] = n + 1; - //SetDataBrowserSelectedItems(lb, 1, items, kDataBrowserItemsAssign); - //RevealDataBrowserItem(lb, items[0], kIconColumn, kDataBrowserRevealOnly); - // force update on selection - //Draw1Control(lb); +void ListBoxImpl::Select(int n) +{ + [table selectRowIndexes:[NSIndexSet indexSetWithIndex:n] byExtendingSelection:NO]; + [table scrollRowToVisible:n]; } -int ListBoxImpl::GetSelection() { - Handle selectedItems = NewHandle(0); - //GetDataBrowserItems(lb, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems); - UInt32 numSelectedItems = GetHandleSize(selectedItems)/sizeof(DataBrowserItemID); - if (numSelectedItems == 0) { - return -1; - } - HLock( selectedItems ); - DataBrowserItemID *individualItem = (DataBrowserItemID*)( *selectedItems ); - DataBrowserItemID selected[numSelectedItems]; - selected[0] = *individualItem; - HUnlock( selectedItems ); - return selected[0] - 1; +int ListBoxImpl::GetSelection() +{ + return [table selectedRow]; } -int ListBoxImpl::Find(const char *prefix) { +int ListBoxImpl::Find(const char* prefix) +{ int count = Length(); - char s[255]; - for (int i = 0; i < count; i++) { - GetValue(i, s, 255); - if ((s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) { + for (int i = 0; i < count; i++) + { + const char* s = ld.GetString(i); + if (s && (s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) + { return i; } } return - 1; } -void ListBoxImpl::GetValue(int n, char *value, int len) { - CFStringRef textString = ld.GetString(n); - if (textString == NULL) { +void ListBoxImpl::GetValue(int n, char* value, int len) +{ + const char* textString = ld.GetString(n); + if (textString == NULL) + { value[0] = '\0'; return; } - CFIndex numUniChars = CFStringGetLength( textString ); - - // XXX how do we know the encoding of the listbox? - CFStringEncoding encoding = kCFStringEncodingUTF8; //( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII); - CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1; - char* text = new char[maximumByteLength]; - CFIndex usedBufferLength = 0; - CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding, - '?', false, reinterpret_cast( text ), - maximumByteLength, &usedBufferLength ); - text[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string - - if (text && len > 0) { - strncpy(value, text, len); - value[len - 1] = '\0'; - } else { - value[0] = '\0'; + strncpy(value, textString, len); + value[len - 1] = '\0'; +} + +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); + if (it == images.end()) + { + images[type] = img; + } + else + { + [it->second release]; + it->second = img; } - delete text; } -void ListBoxImpl::Sort() { - // TODO: Implement this - fprintf(stderr, "ListBox::Sort\n"); +void ListBoxImpl::ClearRegisteredImages() +{ + for (ImageMap::iterator it=images.begin(); + it != images.end(); ++it) + { + [it->second release]; + it->second = nil; + } + images.clear(); } -void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { - xset.Add(type, xpm_data); +int ListBoxImpl::Rows() +{ + return ld.Length(); } -void ListBoxImpl::ClearRegisteredImages() { - xset.Clear(); +NSImage* ListBoxImpl::ImageForRow(int row) +{ + ImageMap::iterator it = images.find(ld.GetType(row)); + if (it != images.end()) + { + NSImage* img = it->second; + [img retain]; + return img; + } + else + { + return nil; + } +} + +NSString* ListBoxImpl::TextForRow(int row) +{ + const char* textString = ld.GetString(row); + NSString* sTitle; + if (unicodeMode) + sTitle = [NSString stringWithUTF8String:textString]; + else + sTitle = [NSString stringWithCString:textString encoding:NSWindowsCP1252StringEncoding]; + return sTitle; +} + +void ListBoxImpl::DoubleClick() +{ + if (doubleClickAction) + { + doubleClickAction(doubleClickActionData); + } } //----------------- ScintillaContextMenu ----------------------------------------------------------- @@ -2006,7 +1935,30 @@ long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long bool Platform::IsDBCSLeadByte(int codePage, char ch) { - // No support for DBCS. + // Byte ranges found in Wikipedia articles with relevant search strings in each case + unsigned char uch = static_cast(ch); + switch (codePage) + { + case 932: + // Shift_jis + return ((uch >= 0x81) && (uch <= 0x9F)) || + ((uch >= 0xE0) && (uch <= 0xEF)); + case 936: + // GBK + return (uch >= 0x81) && (uch <= 0xFE); + case 949: + // Korean Wansung KS C-5601-1987 + return (uch >= 0x81) && (uch <= 0xFE); + case 950: + // Big5 + return (uch >= 0x81) && (uch <= 0xFE); + case 1361: + // Korean Johab KS C-5601-1992 + return + ((uch >= 0x84) && (uch <= 0xD3)) || + ((uch >= 0xD8) && (uch <= 0xDE)) || + ((uch >= 0xE0) && (uch <= 0xF9)); + } return false; } diff --git a/scintilla/cocoa/QuartzTextLayout.h b/scintilla/cocoa/QuartzTextLayout.h index c032da99..df09cde2 100644 --- a/scintilla/cocoa/QuartzTextLayout.h +++ b/scintilla/cocoa/QuartzTextLayout.h @@ -15,127 +15,89 @@ #include "QuartzTextStyle.h" + class QuartzTextLayout { public: /** Create a text layout for drawing on the specified context. */ - QuartzTextLayout( CGContextRef context ) : layout( NULL ), unicode_string( NULL ), unicode_length( 0 ) + QuartzTextLayout( CGContextRef context ) { - OSStatus err = ATSUCreateTextLayout( &layout ); - if (0 != err) - layout = NULL; - + mString = NULL; + mLine = NULL; setContext(context); - - ATSUAttributeTag tag = kATSULineLayoutOptionsTag; - ByteCount size = sizeof( ATSLineLayoutOptions ); - ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics; //| kATSLineFractDisable | kATSLineUseQDRendering - ATSUAttributeValuePtr valuePtr = &rendering; - err = ATSUSetLayoutControls( layout, 1, &tag, &size, &valuePtr ); } ~QuartzTextLayout() { - if (NULL != layout) - ATSUDisposeTextLayout( layout ); - layout = NULL; - - if ( unicode_string != NULL ) - { - delete[] unicode_string; - unicode_string = NULL; - unicode_length = 0; - } - } - - /** Assign a string to the text layout object. */ - // TODO: Create a UTF8 version - // TODO: Optimise the ASCII version by not copying so much - OSStatus setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding ) - { - if (NULL == layout) - return -1; - CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); - if (!str) - return -1; - - unicode_length = CFStringGetLength( str ); - if (unicode_string) - delete[] unicode_string; - unicode_string = new UniChar[ unicode_length ]; - CFStringGetCharacters( str, CFRangeMake( 0, unicode_length ), unicode_string ); - - CFRelease( str ); - str = NULL; - - OSStatus err; - err = ATSUSetTextPointerLocation( layout, unicode_string, kATSUFromTextBeginning, kATSUToTextEnd, unicode_length ); - if( err != noErr ) return err; - - // Turn on the default font fallbacks - return ATSUSetTransientFontMatching( layout, true ); + if ( mString != NULL ) + { + CFRelease(mString); + mString = NULL; + } + if ( mLine != NULL ) + { + CFRelease(mLine); + mLine = NULL; + } } inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) { - this->setText( buffer, byteLength, kCFStringEncodingUTF8 ); - ATSUSetRunStyle( layout, r.getATSUStyle(), 0, unicode_length ); + CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, kCFStringEncodingUTF8, false ); + if (!str) + return; + + CFMutableDictionaryRef stringAttribs = r.getCTStyle(); + + if (mString != NULL) + CFRelease(mString); + mString = ::CFAttributedStringCreate(NULL, str, stringAttribs); + + if (mLine != NULL) + CFRelease(mLine); + mLine = ::CTLineCreateWithAttributedString(mString); + + CFRelease( str ); } - /** Apply the specified text style on the entire range of text. */ - void setStyle( const QuartzTextStyle& style ) - { - ATSUSetRunStyle( layout, style.getATSUStyle(), kATSUFromTextBeginning, kATSUToTextEnd ); - } - - /** Draw the text layout into the current CGContext at the specified position, flipping the CGContext's Y axis if required. + /** Draw the text layout into the current CGContext at the specified position. * @param x The x axis position to draw the baseline in the current CGContext. - * @param y The y axis position to draw the baseline in the current CGContext. - * @param flipTextYAxis If true, the CGContext's Y axis will be flipped before drawing the text, and restored afterwards. Use this when drawing in an HIView's CGContext, where the origin is the top left corner. */ - void draw( float x, float y, bool flipTextYAxis = false ) + * @param y The y axis position to draw the baseline in the current CGContext. */ + void draw( float x, float y ) { - if (NULL == layout || 0 == unicode_length) - return; - if ( flipTextYAxis ) - { - CGContextSaveGState( gc ); - CGContextScaleCTM( gc, 1.0, -1.0 ); - y = -y; - } - - OSStatus err; - err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) ); - - if ( flipTextYAxis ) CGContextRestoreGState( gc ); + if (mLine == NULL) + return; + + ::CGContextSetTextMatrix(gc, CGAffineTransformMakeScale(1.0, -1.0)); + + // Set the text drawing position. + ::CGContextSetTextPosition(gc, x, y); + + // And finally, draw! + ::CTLineDraw(mLine, gc); } - - /** Sets a single text layout control on the ATSUTextLayout object. - * @param tag The control to set. - * @param size The size of the parameter pointed to by value. - * @param value A pointer to the new value for the control. - */ - void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) - { - ATSUSetLayoutControls( layout, 1, &tag, &size, &value ); + + float MeasureStringWidth() + { + if (mLine == NULL) + return 0.0f; + + return ::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL); + } + + CTLineRef getCTLine() { + return mLine; } - - ATSUTextLayout getLayout() { - return layout; - } - - inline CFIndex getLength() const { return unicode_length; } + inline void setContext (CGContextRef context) { gc = context; - if (NULL != layout) - setControl( kATSUCGContextTag, sizeof( gc ), &gc ); } private: - ATSUTextLayout layout; - UniChar* unicode_string; - int unicode_length; CGContextRef gc; + CFAttributedStringRef mString; + CTLineRef mLine; }; #endif diff --git a/scintilla/cocoa/QuartzTextStyle.h b/scintilla/cocoa/QuartzTextStyle.h index 58f08491..cd3a9012 100644 --- a/scintilla/cocoa/QuartzTextStyle.h +++ b/scintilla/cocoa/QuartzTextStyle.h @@ -15,75 +15,63 @@ class QuartzTextStyle public: QuartzTextStyle() { - ATSUCreateStyle( &style ); + styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL); } ~QuartzTextStyle() { - if ( style != NULL ) - ATSUDisposeStyle( style ); - style = NULL; - } - - void setAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) - { - ATSUSetAttributes( style, 1, &tag, &size, &value ); - } - - void setAttribute( QuartzTextStyleAttribute& attribute ) - { - setAttribute( attribute.getTag(), attribute.getSize(), attribute.getValuePtr() ); - } - - void getAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value, ByteCount* actualSize ) - { - ATSUGetAttribute( style, tag, size, value, actualSize ); - } - - template - T getAttribute( ATSUAttributeTag tag ) - { - T value; - ByteCount actualSize; - ATSUGetAttribute( style, tag, sizeof( T ), &value, &actualSize ); - return value; - } - - // TODO: Is calling this actually faster than calling setAttribute multiple times? - void setAttributes( QuartzTextStyleAttribute* attributes[], int number ) - { - // Create the parallel arrays and initialize them properly - ATSUAttributeTag* tags = new ATSUAttributeTag[ number ]; - ByteCount* sizes = new ByteCount[ number ]; - ATSUAttributeValuePtr* values = new ATSUAttributeValuePtr[ number ]; - - for ( int i = 0; i < number; ++ i ) - { - tags[i] = attributes[i]->getTag(); - sizes[i] = attributes[i]->getSize(); - values[i] = attributes[i]->getValuePtr(); - } - - ATSUSetAttributes( style, number, tags, sizes, values ); - - // Free the arrays that were allocated - delete[] tags; - delete[] sizes; - delete[] values; - } - - void setFontFeature( ATSUFontFeatureType featureType, ATSUFontFeatureSelector selector ) - { - ATSUSetFontFeatures( style, 1, &featureType, &selector ); - } - - const ATSUStyle& getATSUStyle() const - { - return style; + if (styleDict != NULL) + { + CFRelease(styleDict); + styleDict = NULL; + } } + + CFMutableDictionaryRef getCTStyle() const + { + return styleDict; + } + + 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) + { + fontRef = inRef; + + if (styleDict != NULL) + CFRelease(styleDict); + styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL); + + CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); + } + + CTFontRef getFontRef() + { + return fontRef; + } + private: - ATSUStyle style; + CFMutableDictionaryRef styleDict; + CTFontRef fontRef; }; #endif diff --git a/scintilla/cocoa/QuartzTextStyleAttribute.h b/scintilla/cocoa/QuartzTextStyleAttribute.h index 21f6abc4..c7505818 100644 --- a/scintilla/cocoa/QuartzTextStyleAttribute.h +++ b/scintilla/cocoa/QuartzTextStyleAttribute.h @@ -12,131 +12,54 @@ #ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H #define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H -class QuartzTextStyleAttribute -{ -public: - QuartzTextStyleAttribute() {} - virtual ~QuartzTextStyleAttribute() {} - virtual ByteCount getSize() const = 0; - virtual ATSUAttributeValuePtr getValuePtr() = 0; - virtual ATSUAttributeTag getTag() const = 0; -}; - -class QuartzTextSize : public QuartzTextStyleAttribute -{ -public: - QuartzTextSize( float points ) - { - size = X2Fix( points ); - } - - ByteCount getSize() const - { - return sizeof( size ); - } - - ATSUAttributeValuePtr getValuePtr() - { - return &size; - } - - ATSUAttributeTag getTag() const - { - return kATSUSizeTag; - } - -private: - Fixed size; -}; - -class QuartzTextStyleAttributeBoolean : public QuartzTextStyleAttribute -{ -public: - QuartzTextStyleAttributeBoolean( bool newVal ) : value( newVal ) {} - - ByteCount getSize() const - { - return sizeof( value ); - } - ATSUAttributeValuePtr getValuePtr() - { - return &value; - } - - virtual ATSUAttributeTag getTag() const = 0; - -private: - Boolean value; -}; - -class QuartzTextBold : public QuartzTextStyleAttributeBoolean -{ -public: - QuartzTextBold( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} - ATSUAttributeTag getTag() const - { - return kATSUQDBoldfaceTag; - } -}; - -class QuartzTextItalic : public QuartzTextStyleAttributeBoolean -{ -public: - QuartzTextItalic( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} - ATSUAttributeTag getTag() const - { - return kATSUQDItalicTag; - } -}; - -class QuartzTextUnderline : public QuartzTextStyleAttributeBoolean -{ -public: - QuartzTextUnderline( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} - ATSUAttributeTag getTag() const { - return kATSUQDUnderlineTag; - } -}; - -class QuartzFont : public QuartzTextStyleAttribute +class QuartzFont { public: /** Create a font style from a name. */ - QuartzFont( const char* name, int length ) + QuartzFont( const char* name, int length, float size, bool bold, bool italic ) { assert( name != NULL && length > 0 && name[length] == '\0' ); - // try to create font - OSStatus err = ATSUFindFontFromName( const_cast( name ), length, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); - // need a fallback if font isn't installed - if( err != noErr || fontid == kATSUInvalidFontID ) - ::ATSUFindFontFromName( "Lucida Grande", 13, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); + CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); + assert(fontName != NULL); + + if (bold || italic) + { + CTFontSymbolicTraits desiredTrait = 0; + CTFontSymbolicTraits traitMask = 0; + + // if bold was specified, add the trait + if (bold) { + desiredTrait |= kCTFontBoldTrait; + traitMask |= kCTFontBoldTrait; + } + + // if italic was specified, add the trait + if (italic) { + desiredTrait |= kCTFontItalicTrait; + traitMask |= kCTFontItalicTrait; + } + + // 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); + } + else + { + // create the font, no traits + fontid = ::CTFontCreateWithName(fontName, size, NULL); + } } - ByteCount getSize() const - { - return sizeof( fontid ); - } - - ATSUAttributeValuePtr getValuePtr() - { - return &fontid; - } - - ATSUAttributeTag getTag() const - { - return kATSUFontTag; - } - - ATSUFontID getFontID() const + CTFontRef getFontID() { return fontid; } private: - ATSUFontID fontid; + CTFontRef fontid; }; - #endif diff --git a/scintilla/cocoa/ScintillaCallTip.h b/scintilla/cocoa/ScintillaCallTip.h deleted file mode 100644 index 74c551ac..00000000 --- a/scintilla/cocoa/ScintillaCallTip.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ScintillaMacOSX.h - * tutorial - * - * Created by Evan Jones on Sun Sep 01 2002. - * - */ -#ifndef SCINTILLA_CALLTIP_H -#define SCINTILLA_CALLTIP_H - -#include "TView.h" - -#include -#include -#include -#include -#include - -#include "Platform.h" -#include "Scintilla.h" - -static const OSType scintillaCallTipType = 'Scct'; - -namespace Scintilla { - -class ScintillaCallTip : public TView -{ -public: - // Private so ScintillaCallTip objects can not be copied - ScintillaCallTip(const ScintillaCallTip &) : TView( NULL ) {} - ScintillaCallTip &operator=(const ScintillaCallTip &) { return * this; } - ~ScintillaCallTip() {}; - -public: - /** This is the class ID that we've assigned to Scintilla. */ - static const CFStringRef kScintillaCallTipClassID; - static const ControlKind kScintillaCallTipKind; - - ScintillaCallTip( void* windowid ); - - /** Returns the HIView object kind, needed to subclass TView. */ - virtual ControlKind GetKind() { return kScintillaCallTipKind; } - -private: - - virtual ControlPartCode HitTest( const HIPoint& where ); - virtual void Draw( RgnHandle rgn, CGContextRef gc ); - virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); - virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); - virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); - -public: - static HIViewRef Create(); -private: - static OSStatus Construct( HIViewRef inControl, TView** outView ); - -}; - - -} - - -#endif diff --git a/scintilla/cocoa/ScintillaCallTip.mm b/scintilla/cocoa/ScintillaCallTip.mm deleted file mode 100644 index db72ee17..00000000 --- a/scintilla/cocoa/ScintillaCallTip.mm +++ /dev/null @@ -1,117 +0,0 @@ - -#include "ScintillaCocoa.h" -#include "ScintillaCallTip.h" -#include "CallTip.h" - -using namespace Scintilla; - -const CFStringRef ScintillaCallTip::kScintillaCallTipClassID = CFSTR( "org.scintilla.calltip" ); -const ControlKind ScintillaCallTip::kScintillaCallTipKind = { 'ejon', 'Scct' }; - -ScintillaCallTip::ScintillaCallTip( void* windowid ) : - TView( reinterpret_cast( windowid ) ) -{ - ActivateInterface( kMouse ); - // debugPrint = true; -} - -void ScintillaCallTip::Draw( - RgnHandle /*inLimitRgn*/, - CGContextRef inContext ) -{ - // Get a reference to the Scintilla C++ object - CallTip* ctip = NULL; - OSStatus err; - err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); - assert(err == noErr); - if (ctip == NULL) return; - - Rect contentBounds; - GetControlBounds(GetViewRef(), &contentBounds); - - HIRect controlFrame; - HIViewGetFrame( GetViewRef(), &controlFrame ); - - // what is the global pos? - Surface *surfaceWindow = Surface::Allocate(); - if (surfaceWindow) { - surfaceWindow->Init(inContext, GetViewRef()); - ctip->PaintCT(surfaceWindow); - surfaceWindow->Release(); - delete surfaceWindow; - } - -} - -ControlPartCode ScintillaCallTip::HitTest( const HIPoint& where ) -{ - if ( CGRectContainsPoint( Bounds(), where ) ) - return 1; - else - return kControlNoPart; -} - -OSStatus ScintillaCallTip::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) -{ - if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; - CallTip* ctip = NULL; - ScintillaCocoa *sciThis = NULL; - OSStatus err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); - err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); - ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); - sciThis->CallTipClick(); - return noErr; -} - -OSStatus ScintillaCallTip::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) -{ - if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; - return noErr; -} - -OSStatus ScintillaCallTip::MouseDragged( HIPoint& location, UInt32 /*modifiers*/, EventMouseButton /*button*/, UInt32 /*clickCount*/ ) -{ - SetThemeCursor( kThemeArrowCursor ); - return noErr; -} - -HIViewRef ScintillaCallTip::Create() -{ - // Register the HIView, if needed - static bool registered = false; - - if ( not registered ) - { - TView::RegisterSubclass( kScintillaCallTipClassID, Construct ); - registered = true; - } - - OSStatus err = noErr; - EventRef event = CreateInitializationEvent(); - assert( event != NULL ); - - HIViewRef control = NULL; - err = HIObjectCreate( kScintillaCallTipClassID, event, reinterpret_cast( &control ) ); - ReleaseEvent( event ); - if ( err == noErr ) { - Platform::DebugPrintf("ScintillaCallTip::Create control %08X\n",control); - return control; - } - return NULL; -} - -OSStatus ScintillaCallTip::Construct( HIViewRef inControl, TView** outView ) -{ - *outView = new ScintillaCallTip( inControl ); - Platform::DebugPrintf("ScintillaCallTip::Construct scintilla %08X\n",*outView); - if ( *outView != NULL ) - return noErr; - else - return memFullErr; -} - -extern "C" { -HIViewRef scintilla_calltip_new() { - return ScintillaCallTip::Create(); -} -} diff --git a/scintilla/cocoa/ScintillaCocoa.h b/scintilla/cocoa/ScintillaCocoa.h index f051deb0..fbf4b002 100644 --- a/scintilla/cocoa/ScintillaCocoa.h +++ b/scintilla/cocoa/ScintillaCocoa.h @@ -116,14 +116,16 @@ private: int scrollSpeed; int scrollTicks; protected: - NSView* ContentView(); PRectangle GetClientRectangle(); Point ConvertPoint(NSPoint point); virtual void Initialise(); virtual void Finalise(); + virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); public: + NSView* ContentView(); + ScintillaCocoa(NSView* view); virtual ~ScintillaCocoa(); @@ -160,6 +162,8 @@ public: virtual bool CanPaste(); virtual void Paste(); virtual void Paste(bool rectangular); + void CTPaint(void* gc, NSRect rc); + void CallTipMouseDown(NSPoint pt); virtual void CreateCallTipWindow(PRectangle rc); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void ClaimSelection(); @@ -199,10 +203,7 @@ public: virtual NSMenu* CreateContextMenu(NSEvent* event); void HandleCommand(NSInteger command); -// virtual OSStatus ActiveStateChanged(); -// -// virtual void CallTipClick(); - + virtual void ActiveStateChanged(bool isActive); }; diff --git a/scintilla/cocoa/ScintillaCocoa.mm b/scintilla/cocoa/ScintillaCocoa.mm index 6302641b..030397ec 100644 --- a/scintilla/cocoa/ScintillaCocoa.mm +++ b/scintilla/cocoa/ScintillaCocoa.mm @@ -32,24 +32,30 @@ NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular" //-------------------------------------------------------------------------------------------------- // Define keyboard shortcuts (equivalents) the Mac way. -#define SCI_CMD ( SCI_ALT | SCI_CTRL) +#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}, + + // Similar to Windows and GTK+ + // Where equivalent clashes with OS X standard, use Meta instead {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_META, SCI_LINESCROLLDOWN}, {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, {SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, + {SCK_UP, SCI_META, SCI_LINESCROLLUP}, {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, {'[', SCI_CTRL, SCI_PARAUP}, {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, @@ -58,13 +64,15 @@ static const KeyToCommand macMapDefault[] = {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_ALT, SCI_WORDLEFT}, - {SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND}, - {SCK_LEFT, SCI_ASHIFT, SCI_WORDLEFTEXTEND}, + {SCK_LEFT, SCI_META, SCI_WORDLEFT}, + {SCK_LEFT, SCI_SMETA, SCI_WORDLEFTEXTEND}, + {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, - {SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, - {SCK_RIGHT, SCI_ASHIFT, SCI_WORDRIGHTEXTEND}, + {SCK_RIGHT, SCI_META, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_SMETA, SCI_WORDRIGHTEXTEND}, + {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, {'/', SCI_CTRL, SCI_WORDPARTLEFT}, {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, @@ -253,28 +261,167 @@ void ScintillaCocoa::Finalise() ScintillaBase::Finalise(); } +//-------------------------------------------------------------------------------------------------- + +/** + * Convert a core foundation string into an array of bytes in a particular encoding + */ + +static char *EncodedBytes(CFStringRef cfsRef, CFStringEncoding encoding) { + CFRange rangeAll = {0, CFStringGetLength(cfsRef)}; + CFIndex usedLen = 0; + CFStringGetBytes(cfsRef, rangeAll, encoding, '?', + false, NULL, 0, &usedLen); + + char *buffer = new char[usedLen+1]; + CFStringGetBytes(cfsRef, rangeAll, encoding, '?', + false, (UInt8 *)buffer,usedLen, NULL); + buffer[usedLen] = '\0'; + return buffer; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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: + CaseFolderDBCS(CFStringEncoding encoding_) : encoding(encoding_) { + 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, encoding, false); + + NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch + locale:[NSLocale currentLocale]]; + + char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); + + size_t lenMapped = strlen(encoded); + if (lenMapped < sizeFolded) { + memcpy(folded, encoded, lenMapped); + } else { + folded[0] = '\0'; + lenMapped = 1; + } + delete []encoded; + CFRelease(cfsVal); + return lenMapped; + } + // Something failed so return a single NUL byte + folded[0] = '\0'; + return 1; + } +}; + +CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { + if (pdoc->dbcsCodePage == SC_CP_UTF8) { + return new CaseFolderUTF8(); + } else { + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + if (pdoc->dbcsCodePage == 0) { + CaseFolderTable *pcf = new CaseFolderTable(); + pcf->StandardASCII(); + // Only for single byte encodings + for (int i=0x80; i<0x100; i++) { + char sCharacter[2] = "A"; + sCharacter[0] = i; + CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast(sCharacter), + 1, encoding, false); + + NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch + locale:[NSLocale currentLocale]]; + + char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); + + if (strlen(encoded) == 1) { + pcf->SetTranslation(sCharacter[0], encoded[0]); + } + + delete []encoded; + CFRelease(cfsVal); + } + return pcf; + } else { + return new CaseFolderDBCS(encoding); + } + return 0; + } +} + + //-------------------------------------------------------------------------------------------------- /** * Case-fold the given string depending on the specified case mapping type. - * Note: ScintillaCocoa exclusively works with Unicode. We don't even think about adding support for - * obsolete code page stuff. */ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) { - NSString* textToConvert = [NSString stringWithUTF8String: s.c_str()]; - std::string result; + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast(s.c_str()), + s.length(), encoding, false); + + NSString *sMapped; switch (caseMapping) { case cmUpper: - result = [[textToConvert uppercaseString] UTF8String]; + sMapped = [(NSString *)cfsVal uppercaseString]; break; case cmLower: - result = [[textToConvert lowercaseString] UTF8String]; + sMapped = [(NSString *)cfsVal lowercaseString]; break; default: - result = s; + sMapped = [(NSString *)cfsVal copy]; } + + // Back to encoding + char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); + std::string result(encoded); + delete []encoded; + CFRelease(cfsVal); return result; } @@ -379,7 +526,9 @@ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPar return reinterpret_cast(this); case SCI_GRABFOCUS: - // TODO: implement it + [[ContentView() window] makeFirstResponder:ContentView()]; + break; + break; case WM_UNICHAR: @@ -396,7 +545,7 @@ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPar return 0; default: - unsigned int r = ScintillaBase::WndProc(iMessage, wParam, lParam); + sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); return r; } @@ -545,76 +694,97 @@ void ScintillaCocoa::Paste(bool forceRectangular) //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) -{ -/* - // create a calltip window - if (!ct.wCallTip.Created()) { - WindowClass windowClass = kHelpWindowClass; - WindowAttributes attributes = kWindowNoAttributes; - Rect contentBounds; - WindowRef outWindow; - - // convert PRectangle to Rect - // this adjustment gets the calltip window placed in the correct location relative - // to our editor window - Rect bounds; - OSStatus err; - err = GetWindowBounds( this->GetOwner(), kWindowGlobalPortRgn, &bounds ); - assert( err == noErr ); - contentBounds.top = rc.top + bounds.top; - contentBounds.bottom = rc.bottom + bounds.top; - contentBounds.right = rc.right + bounds.left; - contentBounds.left = rc.left + bounds.left; - - // create our calltip hiview - HIViewRef ctw = scintilla_calltip_new(); - CallTip* objectPtr = &ct; - ScintillaCocoa* sciThis = this; - SetControlProperty( ctw, scintillaMacOSType, 0, sizeof( this ), &sciThis ); - SetControlProperty( ctw, scintillaCallTipType, 0, sizeof( objectPtr ), &objectPtr ); - - CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow); - ControlRef root; - CreateRootControl(outWindow, &root); - - HIViewRef hiroot = HIViewGetRoot (outWindow); - HIViewAddSubview(hiroot, ctw); - - HIRect boundsRect; - HIViewGetFrame(hiroot, &boundsRect); - HIViewSetFrame( ctw, &boundsRect ); - - // bind the size of the calltip to the size of it's container window - HILayoutInfo layout = { - kHILayoutInfoVersionZero, - { - { NULL, kHILayoutBindTop, 0 }, - { NULL, kHILayoutBindLeft, 0 }, - { NULL, kHILayoutBindBottom, 0 }, - { NULL, kHILayoutBindRight, 0 } - }, - { - { NULL, kHILayoutScaleAbsolute, 0 }, - { NULL, kHILayoutScaleAbsolute, 0 } - - }, - { - { NULL, kHILayoutPositionTop, 0 }, - { NULL, kHILayoutPositionLeft, 0 } - } - }; - HIViewSetLayoutInfo(ctw, &layout); - - ct.wCallTip = root; - ct.wDraw = ctw; - ct.wCallTip.SetWindow(outWindow); - HIViewSetVisible(ctw,true); - - } -*/ +void ScintillaCocoa::CTPaint(void* gc, NSRect rc) { + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init(gc, wMain.GetID()); + surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage); + surfaceWindow->SetDBCSMode(ct.codePage); + ct.PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } } +@interface CallTipView : NSControl { + ScintillaCocoa *sci; +} + +@end + +@implementation CallTipView + +- (NSView*) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; + + if (self) { + sci = NULL; + } + + return self; +} + +- (void) dealloc { + [super dealloc]; +} + +- (BOOL) isFlipped { + return YES; +} + +- (void) setSci: (ScintillaCocoa *) sci_ { + sci = sci_; +} + +- (void) drawRect: (NSRect) needsDisplayInRect { + if (sci) { + CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + sci->CTPaint(context, needsDisplayInRect); + } +} + +- (void) mouseDown: (NSEvent *) event { + if (sci) { + sci->CallTipMouseDown([event locationInWindow]); + } +} + +// On OS X, only the key view should modify the cursor so the calltip can't. +// This view does not become key so resetCursorRects never called. +- (void) resetCursorRects { + //[super resetCursorRects]; + //[self addCursorRect: [self bounds] cursor: [NSCursor arrowCursor]]; +} + +@end + +void ScintillaCocoa::CallTipMouseDown(NSPoint pt) { + NSRect rectBounds = [(NSView *)(ct.wDraw.GetID()) bounds]; + Point location(pt.x, rectBounds.size.height - pt.y); + ct.MouseClick(location); + CallTipClick(); +} + +void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) { + if (!ct.wCallTip.Created()) { + NSRect ctRect = NSMakeRect(rc.top,rc.bottom, rc.Width(), rc.Height()); + NSWindow *callTip = [[NSWindow alloc] initWithContentRect: ctRect + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + [callTip setLevel:NSFloatingWindowLevel]; + [callTip setHasShadow:YES]; + NSRect ctContent = NSMakeRect(0,0, rc.Width(), rc.Height()); + CallTipView *caption = [CallTipView alloc]; + [caption initWithFrame: ctContent]; + [caption setAutoresizingMask: NSViewWidthSizable | NSViewMaxYMargin]; + [caption setSci: this]; + [[callTip contentView] addSubview: caption]; + [callTip orderFront:caption]; + ct.wCallTip = callTip; + ct.wDraw = caption; + } +} void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) { @@ -1178,7 +1348,7 @@ void ScintillaCocoa::NotifyParent(SCNotification scn) if (notifyProc != NULL) { scn.nmhdr.hwndFrom = (void*) this; - scn.nmhdr.idFrom = (unsigned int) wMain.GetID(); + scn.nmhdr.idFrom = GetCtrlID(); notifyProc(notifyObj, WM_NOTIFY, (uintptr_t) 0, (uintptr_t) &scn); } } @@ -1320,9 +1490,13 @@ bool ScintillaCocoa::KeyboardInput(NSEvent* event) bool consumed = false; // Consumed as command? - // Signal command as control + alt. This leaves us without command + control and command + alt - // but that's what we get when we have a modifier key more than other platforms. - if (KeyDown(key, shift, control || command, alt || command, &consumed)) + // Signal Control as SCMOD_META + int modifierKeys = + (shift ? SCI_SHIFT : 0) | + (command ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0) | + (control ? SCI_META : 0); + if (KeyDownWithModifiers(key, modifierKeys, &consumed)) handled = true; if (consumed) handled = true; @@ -1375,9 +1549,9 @@ void ScintillaCocoa::MouseDown(NSEvent* event) NSTimeInterval time = [event timestamp]; bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; bool shift = ([event modifierFlags] & NSShiftKeyMask) != 0; - bool control = ([event modifierFlags] & NSControlKeyMask) != 0; + bool alt = ([event modifierFlags] & NSAlternateKeyMask) != 0; - ButtonDown(Point(location.x, location.y), (int) (time * 1000), shift, control, command); + ButtonDown(Point(location.x, location.y), (int) (time * 1000), shift, command, alt); } //-------------------------------------------------------------------------------------------------- @@ -1487,19 +1661,18 @@ void ScintillaCocoa::HandleCommand(NSInteger command) //-------------------------------------------------------------------------------------------------- -//OSStatus ScintillaCocoa::ActiveStateChanged() -//{ -// // If the window is being deactivated, lose the focus and turn off the ticking -// if ( ! this->IsActive() ) { -// DropCaret(); -// //SetFocusState( false ); -// SetTicking( false ); -// } else { -// ShowCaretAtCurrentPosition(); -// } -// return noErr; -//} -// +void ScintillaCocoa::ActiveStateChanged(bool isActive) +{ + // If the window is being deactivated, lose the focus and turn off the ticking + if (!isActive) { + DropCaret(); + //SetFocusState( false ); + SetTicking( false ); + } else { + ShowCaretAtCurrentPosition(); + } +} + //-------------------------------------------------------------------------------------------------- diff --git a/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj index 4cbedf8e..0998d297 100644 --- a/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj +++ b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj @@ -936,6 +936,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -954,6 +955,7 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; + SDKROOT = macosx10.6; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -962,6 +964,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -976,6 +979,7 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; + SDKROOT = macosx10.6; WRAPPER_EXTENSION = framework; }; name = Release; diff --git a/scintilla/cocoa/ScintillaListBox.h b/scintilla/cocoa/ScintillaListBox.h deleted file mode 100644 index 9f6b722f..00000000 --- a/scintilla/cocoa/ScintillaListBox.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* - * ScintillaMacOSX.h - * tutorial - * - * Created by Evan Jones on Sun Sep 01 2002. - * - */ - -#ifndef SCINTILLA_LISTBOX_H -#define SCINTILLA_LISTBOX_H - -#include "TView.h" - -#include -#include -#include -#include -#include - -#include "Platform.h" -#include "Scintilla.h" - -static const OSType scintillaListBoxType = 'sclb'; - -namespace Scintilla { - -class ScintillaListBox : public TView -{ -public: - // Private so ScintillaListBox objects can not be copied - ScintillaListBox(const ScintillaListBox &) : TView( NULL ) {} - ScintillaListBox &operator=(const ScintillaListBox &) { return * this; } - ~ScintillaListBox() {}; - -public: - /** This is the class ID that we've assigned to Scintilla. */ - static const CFStringRef kScintillaListBoxClassID; - static const ControlKind kScintillaListBoxKind; - - ScintillaListBox( void* windowid ); - - /** Returns the HIView object kind, needed to subclass TView. */ - virtual ControlKind GetKind() { return kScintillaListBoxKind; } - -private: - - virtual ControlPartCode HitTest( const HIPoint& where ); - virtual void Draw( RgnHandle rgn, CGContextRef gc ); - virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); - virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); - -public: - static HIViewRef Create(); -private: - static OSStatus Construct( HIViewRef inControl, TView** outView ); - -}; - - -} - - -#endif diff --git a/scintilla/cocoa/ScintillaListBox.mm b/scintilla/cocoa/ScintillaListBox.mm deleted file mode 100644 index 8c517859..00000000 --- a/scintilla/cocoa/ScintillaListBox.mm +++ /dev/null @@ -1,110 +0,0 @@ - -#include "ScintillaCocoa.h" -#include "ScintillaListBox.h" - -using namespace Scintilla; - -const CFStringRef ScintillaListBox::kScintillaListBoxClassID = CFSTR( "org.scintilla.listbox" ); -const ControlKind ScintillaListBox::kScintillaListBoxKind = { 'ejon', 'Sclb' }; - -ScintillaListBox::ScintillaListBox( void* windowid ) : - TView( reinterpret_cast( windowid ) ) -{ - ActivateInterface( kMouse ); - // debugPrint = true; -} - -void ScintillaListBox::Draw( - RgnHandle /*inLimitRgn*/, - CGContextRef inContext ) -{ - Rect contentBounds; - GetControlBounds(GetViewRef(), &contentBounds); - - HIRect controlFrame; - HIViewGetFrame( GetViewRef(), &controlFrame ); - - // what is the global pos? - Surface *surfaceWindow = Surface::Allocate(); - if (surfaceWindow) - { - surfaceWindow->Init(inContext, GetViewRef()); - - // TODO: Implement or find workaround - // ctip->PaintCT(surfaceWindow); - surfaceWindow->Release(); - delete surfaceWindow; - } - -} - -ControlPartCode ScintillaListBox::HitTest( const HIPoint& where ) -{ - if ( CGRectContainsPoint( Bounds(), where ) ) - return 1; - else - return kControlNoPart; -} - -OSStatus ScintillaListBox::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) -{ - if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; - ListBox* ctip = NULL; - ScintillaCocoa *sciThis = NULL; - OSStatus err = GetControlProperty( GetViewRef(), scintillaListBoxType, 0, sizeof( ctip ), NULL, &ctip ); - err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); - - // TODO: Implement of find work around. - // ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); - - // TODO: still needed? - // sciThis->ListBoxClick(); - return noErr; -} - -OSStatus ScintillaListBox::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) -{ - if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; - return noErr; -} - -HIViewRef ScintillaListBox::Create() -{ - // Register the HIView, if needed - static bool registered = false; - - if ( not registered ) - { - TView::RegisterSubclass( kScintillaListBoxClassID, Construct ); - registered = true; - } - - OSStatus err = noErr; - EventRef event = CreateInitializationEvent(); - assert( event != NULL ); - - HIViewRef control = NULL; - err = HIObjectCreate( kScintillaListBoxClassID, event, reinterpret_cast( &control ) ); - ReleaseEvent( event ); - if ( err == noErr ) { - Platform::DebugPrintf("ScintillaListBox::Create control %08X\n",control); - return control; - } - return NULL; -} - -OSStatus ScintillaListBox::Construct( HIViewRef inControl, TView** outView ) -{ - *outView = new ScintillaListBox( inControl ); - Platform::DebugPrintf("ScintillaListBox::Construct scintilla %08X\n",*outView); - if ( *outView != NULL ) - return noErr; - else - return memFullErr; -} - -extern "C" { -HIViewRef scintilla_listbox_new() { - return ScintillaListBox::Create(); -} -} diff --git a/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj index 39962fb3..30398ef9 100644 --- a/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj +++ b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj @@ -282,11 +282,9 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; @@ -311,11 +309,9 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; @@ -344,7 +340,7 @@ ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = macosx10.6; }; name = Debug; }; @@ -357,7 +353,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = ""; PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = macosx10.6; }; name = Release; }; diff --git a/scintilla/cocoa/ScintillaView.h b/scintilla/cocoa/ScintillaView.h index 6cbfbfff..bf987870 100644 --- a/scintilla/cocoa/ScintillaView.h +++ b/scintilla/cocoa/ScintillaView.h @@ -127,6 +127,8 @@ extern NSString *SCIUpdateUINotification; - (void) setLexerProperty: (NSString*) name value: (NSString*) value; - (NSString*) getLexerProperty: (NSString*) name; +- (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback; + - (void) setInfoBar: (NSView *) aView top: (BOOL) top; - (void) setStatusText: (NSString*) text; diff --git a/scintilla/cocoa/ScintillaView.mm b/scintilla/cocoa/ScintillaView.mm index a1406a5f..3e991211 100644 --- a/scintilla/cocoa/ScintillaView.mm +++ b/scintilla/cocoa/ScintillaView.mm @@ -114,7 +114,6 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; [super resetCursorRects]; // We only have one cursor rect: our bounds. - NSRect bounds = [self bounds]; [self addCursorRect: [self bounds] cursor: mCurrentCursor]; [mCurrentCursor setOnMouseEntered: YES]; } @@ -239,9 +238,15 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; */ - (void) insertText: (id) aString { - // Remove any previously marked text first. - [self removeMarkedText]; - mOwner.backend->InsertText((NSString*) aString); + // Remove any previously marked text first. + [self removeMarkedText]; + NSString* newText = @""; + if ([aString isKindOfClass:[NSString class]]) + newText = (NSString*) aString; + else if ([aString isKindOfClass:[NSAttributedString class]]) + newText = (NSString*) [aString string]; + + mOwner.backend->InsertText(newText); } //-------------------------------------------------------------------------------------------------- @@ -274,7 +279,12 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; { // 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 = (NSString*) aString; + 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]; // Replace marked text if there is one. @@ -363,7 +373,8 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; */ - (void) keyDown: (NSEvent *) theEvent { - mOwner.backend->KeyboardInput(theEvent); + if (mMarkedTextRange.length == 0) + mOwner.backend->KeyboardInput(theEvent); NSArray* events = [NSArray arrayWithObject: theEvent]; [self interpretKeyEvents: events]; } @@ -617,7 +628,7 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; //-------------------------------------------------------------------------------------------------- /** - * Called by a connected compontent (usually the info bar) if something changed there. + * Called by a connected component (usually the info bar) if something changed there. * * @param type The type of the notification. * @param message Carries the new status message if the type is a status message change. @@ -637,6 +648,8 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI"; [self setGeneralProperty: SCI_SETZOOM value: zoom]; break; } + default: + break; }; } @@ -678,7 +691,8 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa { // Parent notification. Details are passed as SCNotification structure. SCNotification* scn = reinterpret_cast(lParam); - editor = reinterpret_cast(scn->nmhdr.idFrom).owner; + ScintillaCocoa *psc = reinterpret_cast(scn->nmhdr.hwndFrom); + editor = reinterpret_cast(psc->ContentView()).owner; switch (scn->nmhdr.code) { case SCN_MARGINCLICK: @@ -777,10 +791,21 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa // Setup a special indicator used in the editor to provide visual feedback for // input composition, depending on language, keyboard etc. - [self setColorProperty: SCI_INDICSETFORE parameter: INPUT_INDICATOR fromHTML: @"#FF9A00"]; + [self setColorProperty: SCI_INDICSETFORE parameter: INPUT_INDICATOR fromHTML: @"#FF0000"]; [self setGeneralProperty: SCI_INDICSETUNDER parameter: INPUT_INDICATOR value: 1]; - [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INPUT_INDICATOR value: INDIC_ROUNDBOX]; + [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INPUT_INDICATOR value: INDIC_PLAIN]; [self setGeneralProperty: SCI_INDICSETALPHA parameter: INPUT_INDICATOR value: 100]; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(applicationDidResignActive:) + name:NSApplicationDidResignActiveNotification + object:nil]; + + [center addObserver:self + selector:@selector(applicationDidBecomeActive:) + name:NSApplicationDidBecomeActiveNotification + object:nil]; } return self; } @@ -796,6 +821,18 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa //-------------------------------------------------------------------------------------------------- +- (void) applicationDidResignActive: (NSNotification *)note { + mBackend->ActiveStateChanged(false); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) applicationDidBecomeActive: (NSNotification *)note { + mBackend->ActiveStateChanged(true); +} + +//-------------------------------------------------------------------------------------------------- + - (void) viewDidMoveToWindow { [super viewDidMoveToWindow]; @@ -967,7 +1004,8 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa - (BOOL) setHorizontalScrollRange: (int) range page: (int) page { BOOL result = NO; - BOOL hideScroller = page >= range; + BOOL hideScroller = (page >= range) || + (mBackend->WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE); if ([mHorizontalScroller isHidden] != hideScroller) { @@ -1363,6 +1401,17 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa return [NSString stringWithUTF8String: result]; } +//-------------------------------------------------------------------------------------------------- + +/** + * Sets the notification callback + */ +- (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback +{ + mBackend->RegisterNotifyCallback(windowid, callback); +} + + //-------------------------------------------------------------------------------------------------- /** diff --git a/scintilla/doc/SciCoding.html b/scintilla/doc/SciCoding.html index f34fde6c..1d45f0a7 100644 --- a/scintilla/doc/SciCoding.html +++ b/scintilla/doc/SciCoding.html @@ -98,55 +98,53 @@ Introduction

- The source code of Scintilla and SciTE follow my preferences. + The source code of Scintilla and SciTE follow my preferences. Some of these decisions are arbitrary and based on my sense of aesthetics but its good to have all the code look the same even if its not exactly how everyone would prefer.

Code that does not follow these conventions will be accepted, but will be modified - as time goes by to fit the conventions. Scintilla code follows the conventions more - closely than SciTE except for lexers which are relatively independent modules. + as time goes by to fit the conventions. Scintilla code follows the conventions more + closely than SciTE except for lexers which are relatively independent modules. Lexers that are maintained by others are left as they are submitted except that warnings will be fixed so the whole project can compile cleanly.

- The AStyle formatting - program with a '-tapO' argument formats code in much the right way although - there are a few bugs in AStyle. The scite/scripts/Fixer.py script will run AStyle - over a C++ source file and fix up some of those bugs. + The AStyle formatting + program with '-taOHUKk3 -M8' arguments formats code in much the right way although + there are a few bugs in AStyle.

Language features

- Design goals for Scintilla and SciTE include portability to currently available C++ + Design goals for Scintilla and SciTE include portability to currently available C++ compilers on diverse platforms with high performance and low resource usage. - Scintilla has stricter portability requirements to SciTE as it may be ported to - low capability platforms such as Windows CE or PalmOS but it is less likely - SciTE will be. + Scintilla has stricter portability requirements to SciTE as it may be ported to + low capability platforms.

- To achieve portability, only a subset of C++ features are used. Exceptions are - not available on some platforms such as Windows CE so exceptions are not used - and thus the standard C++ library can not be used. - Template support differs between compilers so is not used in Scintilla but there - are some simple uses in SciTE. - Run-time type information adds to memory use so is turned off. - Name spaces are not used. + To achieve portability, only a subset of C++ features are used. + Exceptions and templates may be used but, since Scintilla can be used from C as well as + C++, exceptions may not be thrown out of Scintilla and all exceptions should be caught + before returning from Scintilla. + Run-time type information adds to memory use so is turned off. + A 'Scintilla' name spaces is optionally used based on the SCI_NAMESPACE + definition. This helps with name clashes on OS X.

- The goto statement is not used because of bad memories from my first job - maintaining FORTRAN programs. The union feature is not used as it can lead to + The goto statement is not used because of bad memories from my first job + maintaining FORTRAN programs. The union feature is not used as it can lead to non-type-safe value access.

Casting

- Do not use old C style casts like (char *)s. Instead use the most strict form of C++ - cast possible like const_cast<char *>(s). Use static_cast and const_cast - where possible rather than reinterpret_cast. Because the code is compiled with + Do not use old C style casts like (char *)s. Instead use the most strict form of C++ + cast possible like const_cast<char *>(s). Use static_cast and const_cast + where possible rather than reinterpret_cast. Because the code is compiled with run-time type information turned off, dynamic_cast will not work.

@@ -162,26 +160,26 @@

To help ensure code is well written and portable, it is compiled with almost all - warnings turned on. This sometimes results in warnings about code that is - completely good (false positives) but changing the code to avoid the warnings - is generally fast and has little impact on readability. + warnings turned on. This sometimes results in warnings about code that is + completely good (false positives) but changing the code to avoid the warnings + is generally fast and has little impact on readability.

Initialise all variables and minimise the scope of variables. If a variable is defined just before its use then it can't be misused by code before that point. - Use loop declarations that are compatible with both the C++ standard and currently - available compilers. + Use loop declarations that are compatible with both the C++ standard and currently + available compilers.

Allocation

- As exceptions are not used, memory exhaustion can occur. - This should be checked for and handled but there is quite a lot of Scintilla and - SciTE code that doesn't yet. - Fixed length buffers are often used as these are simple and avoid the need to - worry about memory exhaustion but then require that buffer lengths are - respected. + Memory exhaustion can occur in many Scintilla methods. + This should be checked for and handled but once it has happened, it is very difficult to do + anything as Scintilla's data structures may be in an inconsistent state. + Fixed length buffers are often used as these are simple and avoid the need to + worry about memory exhaustion but then require that buffer lengths are + respected.

The C++ new and delete operators are preferred over C's malloc and free @@ -193,11 +191,11 @@

Start brackets, '{', should be located on the line of the control structure they start and end brackets, '}', should be at the indented start of a line. When there is - an else clause, this occurs on the same line as the '}'. + an else clause, this occurs on the same line as the '}'. This format uses less lines than alternatives, allowing more code to be seen on screen. - Fully bracketed control - structures are preferred because this makes it more likely that modifications will - be correct and it allows Scintilla's folder to work. No braces on returned + Fully bracketed control + structures are preferred because this makes it more likely that modifications will + be correct and it allows Scintilla's folder to work. No braces on returned expressions as return is a keyword, not a function call.

bool fn(int a) {
@@ -213,10 +211,10 @@ Spacing

- Spaces on both sides of '=' and comparison operators and no attempt to line up '='. + Spaces on both sides of '=' and comparison operators and no attempt to line up '='. No space before or after '(', when used in calls, but a space after every ','. - No spaces between tokens in short expressions but may be present in - longer expressions. Space before '{'. No space before ';'. + No spaces between tokens in short expressions but may be present in + longer expressions. Space before '{'. No space before ';'. No space after '*' when used to mean pointer and no space after '[' or ']'. One space between keywords and '('.

@@ -232,10 +230,10 @@

Identifiers use mixed case and no underscores. Class, function and method names start with an uppercase letter and use - further upper case letters to distinguish words. Variables start with a lower - case letter and use upper case letters to distinguish words. + further upper case letters to distinguish words. Variables start with a lower + case letter and use upper case letters to distinguish words. Loop counters and similar variables can have simple names like 'i'. - Function calls should be differentiated from method calls with an initial '::' + Function calls should be differentiated from method calls with an initial '::' global scope modifier.

class StorageZone {
@@ -250,7 +248,7 @@

Submitting a lexer

- +

Add a public feature request to the Feature Request Tracker.

Send all the modified and new files as full text (not patches) in an archive (.zip or .tgz).

Define all of the lexical states in a modified Scintilla.iface.

diff --git a/scintilla/doc/ScintillaDoc.html b/scintilla/doc/ScintillaDoc.html index 3072572c..86fe3740 100644 --- a/scintilla/doc/ScintillaDoc.html +++ b/scintilla/doc/ScintillaDoc.html @@ -79,7 +79,7 @@

Scintilla Documentation

-

Last edited 19/January/2011 NH

+

Last edited 18/June/2011 NH

There is an overview of the internal design of Scintilla.
@@ -625,10 +625,9 @@ struct Sci_TextRange { -

If SCFIND_REGEXP is not included in the searchFlags, you can +

You can search backwards to find the previous occurrence of a search string by setting the end of the - search range before the start. If SCFIND_REGEXP is included, searches are always - from a lower position to a higher position, even if the search range is backwards.

+ search range before the start.

In a regular expression, special characters interpreted are:

@@ -722,6 +721,8 @@ struct Sci_TextRange { +

Regular expressions will only match ranges within a single line, never matching over multiple lines.

+

SCI_FINDTEXT(int searchFlags, Sci_TextToFind *ttf)
This message searches for text in the document. It does not use or move the current selection. @@ -730,9 +731,8 @@ struct Sci_TextRange {

The Sci_TextToFind structure is defined in Scintilla.h; set chrg.cpMin and chrg.cpMax with the range of positions in the document - to search. If SCFIND_REGEXP is not included in the flags, you can search backwards by - setting chrg.cpMax less than chrg.cpMin. If SCFIND_REGEXP - is included, the search is always forwards (even if chrg.cpMax is less than chrg.cpMin). + to search. You can search backwards by + setting chrg.cpMax less than chrg.cpMin. Set the lpstrText member of Sci_TextToFind to point at a zero terminated text string holding the search pattern. If your language makes the use of Sci_TextToFind difficult, you should consider using SCI_SEARCHINTARGET instead.

@@ -772,9 +772,7 @@ struct Sci_TextToFind {

SCI_SEARCHNEXT and SCI_SEARCHPREV search for the next and previous occurrence of the zero terminated search string pointed at by text. The search is modified by - the searchFlags. If you request a regular - expression, SCI_SEARCHPREV finds the first occurrence of the search string in the - document, not the previous one before the anchor point.

+ the searchFlags.

The return value is -1 if nothing is found, otherwise the return value is the start position of the matching text. The selection is updated to show the matched text, but is not scrolled @@ -1079,6 +1077,7 @@ struct Sci_TextToFind { SCI_GETSELECTIONSTART
SCI_SETSELECTIONEND(int position)
SCI_GETSELECTIONEND
+ SCI_SETEMPTYSELECTION(int pos)
SCI_SELECTALL
SCI_LINEFROMPOSITION(int position)
SCI_POSITIONFROMLINE(int line)
@@ -1114,6 +1113,8 @@ struct Sci_TextToFind { SCI_TEXTWIDTH(int styleNumber, const char *text)
SCI_TEXTHEIGHT(int line)
SCI_CHOOSECARETX
+ SCI_MOVESELECTEDLINESUP
+ SCI_MOVESELECTEDLINESDOWN

SCI_GETTEXTLENGTH
@@ -1229,6 +1230,9 @@ struct Sci_TextToFind { current position or the anchor position. SCI_GETSELECTIONEND returns the larger of the two values.

+

SCI_SETEMPTYSELECTION(int pos)
+ This removes any selection and sets the caret at pos. The caret is not scrolled into view.

+

SCI_SELECTALL
This selects all the text in the document. The current position is not scrolled into view.

@@ -1458,6 +1462,16 @@ struct Sci_TextToFind { user and this value is then used when moving vertically such as by using the up and down keys. This message sets the current x position of the caret as the remembered value.

+

SCI_MOVESELECTEDLINESUP
+ Move the selected lines up one line, shifting the line above after the selection. + The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. + If nothing was selected, the line the cursor is currently at will be selected.

+ +

SCI_MOVESELECTEDLINESDOWN
+ Move the selected lines down one line, shifting the line below before the selection. + The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. + If nothing was selected, the line the cursor is currently at will be selected.

+

Multiple Selection and Virtual Space

@@ -1549,7 +1563,8 @@ struct Sci_TextToFind {

SCI_SETMULTIPLESELECTION(bool multipleSelection)
SCI_GETMULTIPLESELECTION
- Enable or disable multiple selection.

+ Enable or disable multiple selection. When multiple selection is disabled, it is not possible to select + multiple ranges by holding down the Ctrl key while dragging with the mouse.

SCI_SETADDITIONALSELECTIONTYPING(bool additionalSelectionTyping)
@@ -2742,6 +2757,8 @@ struct Sci_TextToFind { SCI_MARGINTEXTCLEARALL
SCI_MARGINSETSTYLEOFFSET(int style)
SCI_MARGINGETSTYLEOFFSET
+ SCI_SETMARGINOPTIONS(int marginOptions)
+ SCI_GETMARGINOPTIONS

SCI_SETMARGINTYPEN(int margin, int iType)
@@ -2849,6 +2866,15 @@ 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.

+

+ 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 + SC_MARGINOPTION_NONE=0 by default. +

Annotations

@@ -3089,6 +3115,8 @@ struct Sci_TextToFind { SCI_BRACEHIGHLIGHT(int pos1, int pos2)
SCI_BRACEBADLIGHT(int pos1)
+ SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)
+ SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)
SCI_BRACEMATCH(int position, int maxReStyle)
@@ -3107,6 +3135,12 @@ struct Sci_TextToFind { that is unmatched. Using a position of INVALID_POSITION (-1) removes the highlight.

+

SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)
+ Use specified indicator to highlight matching braces instead of changing their style.

+ +

SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)
+ Use specified indicator to highlight non matching brace instead of changing its style.

+

SCI_BRACEMATCH(int pos, int maxReStyle)
The SCI_BRACEMATCH message finds a corresponding matching brace given pos, the position of one brace. The brace characters handled are '(', ')', '[', @@ -3275,6 +3309,9 @@ struct Sci_TextToFind { colour)
SCI_MARKERSETBACK(int markerNumber, int colour)
+ SCI_MARKERSETBACKSELECTED(int markerNumber, int + colour)
+ SCI_MARKERENABLEHIGHLIGHT(int enabled)
SCI_MARKERSETALPHA(int markerNumber, int alpha)
SCI_MARKERADD(int line, int markerNumber)
@@ -3461,7 +3498,12 @@ struct Sci_TextToFind { href="#colour">colour)
SCI_MARKERSETBACK(int markerNumber, int colour)
- These two messages set the foreground and background colour of a marker number.

+ These two messages set the foreground and background colour of a marker number.
+ SCI_MARKERSETBACKSELECTED(int markerNumber, int colour)
+ This message sets the highlight background colour of a marker number when its folding block is selected. The default colour is #FF0000.

+

SCI_MARKERENABLEHIGHLIGHT(bool enabled)
+ This message allows to enable/disable the highlight folding block when it is selected. (i.e. block that contains the caret)

SCI_MARKERSETALPHA(int markerNumber, int alpha)
When markers are drawn in the content area, either because there is no margin for them or @@ -3549,6 +3591,8 @@ struct Sci_TextToFind { SCI_INDICGETFORE(int indicatorNumber)
SCI_INDICSETALPHA(int indicatorNumber, int alpha)
SCI_INDICGETALPHA(int indicatorNumber)
+ SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)
+ SCI_INDICGETOUTLINEALPHA(int indicatorNumber)
SCI_INDICSETUNDER(int indicatorNumber, bool under)
SCI_INDICGETUNDER(int indicatorNumber)
@@ -3584,7 +3628,7 @@ struct Sci_TextToFind { 1 - A squiggly underline. + A squiggly underline. Requires 3 pixels of descender space. @@ -3633,11 +3677,49 @@ struct Sci_TextToFind { 7 A rectangle with rounded corners around the text using translucent drawing with the - interior more transparent than the border. You can use - SCI_INDICSETALPHA - to control the alpha transparency value. The default alpha value is 30. - + interior usually more transparent than the border. You can use + SCI_INDICSETALPHA and + SCI_INDICSETOUTLINEALPHA + to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour. + + + INDIC_STRAIGHTBOX + + 8 + + A rectangle around the text using translucent drawing with the + interior usually more transparent than the border. You can use + SCI_INDICSETALPHA and + SCI_INDICSETOUTLINEALPHA + to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour. + + + + INDIC_DASH + + 9 + + A dashed underline. + + + + INDIC_DOTS + + 10 + + A dotted underline. + + + + INDIC_SQUIGGLELOW + + 11 + + Similar to INDIC_SQUIGGLE but only using 2 vertical pixels + so will fit under small fonts. + + @@ -3657,7 +3739,14 @@ struct Sci_TextToFind {

SCI_INDICSETALPHA(int indicatorNumber, int alpha)
SCI_INDICGETALPHA(int indicatorNumber)
These two messages set and get the alpha transparency used for drawing the - fill color of the INDIC_ROUNDBOX rectangle. The alpha value can range from + fill colour of the INDIC_ROUNDBOX and INDIC_STRAIGHTBOX rectangle. The alpha value can range from + 0 (completely transparent) to 255 (no transparency). +

+ +

SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)
+ SCI_INDICGETOUTLINEALPHA(int indicatorNumber)
+ These two messages set and get the alpha transparency used for drawing the + outline colour of the INDIC_ROUNDBOX and INDIC_STRAIGHTBOX rectangle. The alpha value can range from 0 (completely transparent) to 255 (no transparency).

@@ -3677,8 +3766,8 @@ struct Sci_TextToFind { SCI_SETINDICATORCURRENT(int indicator)
SCI_GETINDICATORCURRENT
These two messages set and get the indicator that will be affected by calls to - SCI_INDICATORFILLRANGE and - SCI_INDICATORCLEARRANGE. + SCI_INDICATORFILLRANGE(int position, int fillLength) and + SCI_INDICATORCLEARRANGE(int position, int clearLength).

@@ -4302,6 +4391,12 @@ struct Sci_TextToFind { SCI_VERTICALCENTRECARET + + + SCI_MOVESELECTEDLINESUP + + SCI_MOVESELECTEDLINESDOWN + @@ -4360,7 +4455,10 @@ struct Sci_TextToFind { SCK_WIN.

The modifiers are a combination of zero or more of SCMOD_ALT, - SCMOD_CTRL, and SCMOD_SHIFT. If you are building a table, you might + SCMOD_CTRL, SCMOD_SHIFT, and SCMOD_META. + 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.

SCI_ASSIGNCMDKEY(int SCI_PRIVATELEXERCALL API.

+

Fold is called with the exact range that needs folding. +Previously, lexers were called with a range that started one line before the range that +needs to be folded as this allowed fixing up the last line from the previous folding. +The new approach allows the lexer to decide whether to backtrack or to handle this +more efficiently.

IDocument

@@ -5677,31 +5780,38 @@ struct NotifyHeader { // This matches the Win32 NMHDR structure }; struct SCNotification { - struct NotifyHeader nmhdr; - int position; - // SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_DWELLSTART, - // SCN_DWELLEND, SCN_CALLTIPCLICK, - // SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK - int ch; // SCN_CHARADDED, SCN_KEY - int modifiers; - // SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK - int modificationType; // SCN_MODIFIED - const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION - int length; // SCN_MODIFIED - int linesAdded; // SCN_MODIFIED - int message; // SCN_MACRORECORD - uptr_t wParam; // SCN_MACRORECORD - sptr_t lParam; // SCN_MACRORECORD - int line; // SCN_MODIFIED, SCN_DOUBLECLICK - int foldLevelNow; // SCN_MODIFIED - int foldLevelPrev; // SCN_MODIFIED - int margin; // SCN_MARGINCLICK - int listType; // SCN_USERLISTSELECTION, SCN_AUTOCSELECTION - int x; // SCN_DWELLSTART, SCN_DWELLEND - int y; // SCN_DWELLSTART, SCN_DWELLEND - int token; // SCN_MODIFIED with SC_MOD_CONTAINER - int annotationLinesAdded; // SC_MOD_CHANGEANNOTATION - int updated; // SCN_UPDATEUI + struct Sci_NotifyHeader nmhdr; + int position; + /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */ + /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */ + /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */ + /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ + /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ + + int ch; /* SCN_CHARADDED, SCN_KEY */ + int modifiers; + /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */ + /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ + + int modificationType; /* SCN_MODIFIED */ + const char *text; + /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */ + + int length; /* SCN_MODIFIED */ + int linesAdded; /* SCN_MODIFIED */ + int message; /* SCN_MACRORECORD */ + uptr_t wParam; /* SCN_MACRORECORD */ + sptr_t lParam; /* SCN_MACRORECORD */ + int line; /* SCN_MODIFIED */ + int foldLevelNow; /* SCN_MODIFIED */ + int foldLevelPrev; /* SCN_MODIFIED */ + int margin; /* SCN_MARGINCLICK */ + int listType; /* SCN_USERLISTSELECTION */ + int x; /* SCN_DWELLSTART, SCN_DWELLEND */ + int y; /* SCN_DWELLSTART, SCN_DWELLEND */ + int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ + int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */ + int updated; /* SCN_UPDATEUI */ }; @@ -5737,11 +5847,12 @@ struct SCNotification {

The following SCI_* messages are associated with these notifications:

-
SCI_SETMODEVENTMASK(int - eventMask)
+ SCI_SETMODEVENTMASK(int eventMask)
SCI_GETMODEVENTMASK
- SCI_SETMOUSEDWELLTIME
+ SCI_SETMOUSEDWELLTIME(int milliseconds)
SCI_GETMOUSEDWELLTIME
+ SCI_SETIDENTIFIER(int identifier)
+ SCI_GETIDENTIFIER

The following additional notifications are sent using the WM_COMMAND message on @@ -5752,6 +5863,17 @@ struct SCNotification { SCEN_KILLFOCUS
+

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. + 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. + 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. +

+

SCN_STYLENEEDED
If you used SCI_SETLEXER(SCLEX_CONTAINER) to make the container act as the @@ -5799,12 +5921,14 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(lineNumber);

SCN_DOUBLECLICK
The mouse button was double clicked in editor. The position field is set to the text position of the - double click and the line field is set to the line of the double click.

+ double click, the line field is set to the line of the double click, and + the modifiers field is set to the key modifiers + held down in a similar manner to SCN_KEY.

SCN_UPDATEUI
Either the text or styling of the document has changed or the selection range or scroll position has changed. Now would be a good time to update any container UI elements that depend on document or view state. - The updated field is set to the bit set of things changed since the previous notiication.

+ The updated field is set to the bit set of things changed since the previous notification.

@@ -6328,7 +6452,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next - + + + + + + +
wParamlistType This is set to the listType parameter from the SCI_USERLISTSHOW message that @@ -6340,10 +6464,15 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next The text of the selection.
positionThe position the list was displayed at.

-

SCN_URIDROPPED
@@ -6387,9 +6516,8 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
-
-

SCI_SETMOUSEDWELLTIME
+

SCI_SETMOUSEDWELLTIME(int milliseconds)
SCI_GETMOUSEDWELLTIME
These two messages set and get the time the mouse must sit still, in milliseconds, to generate a SCN_DWELLSTART notification. If @@ -6447,7 +6575,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next - lParam + position The start position of the word being completed. @@ -6482,9 +6610,8 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next

void scintilla_set_id(ScintillaObject *sci, uptr_t id)
Set the control ID which will be used in the idFrom field of the NotifyHeader structure of all - notifications for this instance. When an application creates multiple Scintilla widgets, this allows - the source of each notification to be found. 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.

+ notifications for this instance. + This is equivalent to SCI_SETIDENTIFIER.

sptr_t scintilla_send_message(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam)
The main entry point allows sending any of the messages described in this document.

diff --git a/scintilla/doc/ScintillaDownload.html b/scintilla/doc/ScintillaDownload.html index 0ccb913e..176acf22 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.25 + Release 2.27

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 (1200K) commonly used on Windows
  • +
  • tgz format (1080K) 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 821393df..93d444ff 100644 --- a/scintilla/doc/ScintillaHistory.html +++ b/scintilla/doc/ScintillaHistory.html @@ -368,6 +368,16 @@

+ + + + + + + + + +
- + Windows   - + GTK+/Linux  
Dariusz Knociński Ben FisherDon GobinJohn Yeung
AdobeElizabeth A. IrizarryMike SchroederMorten MacFly
Jaime GimenoThomas Linder Puls

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

+ Release 2.27 +

+
    +
  • + Released 20 June 2011. +
  • +
  • + On recent GTK+ 2.x versions when using Cairo, bug fixed where wrong colours were drawn. +
  • +
  • + SciTE on GTK+ slow performance in menu maintenance fixed. + Bug #3315233. +
  • +
  • + Cocoa platform supports 64-bit builds and uses only non-deprecated APIs. + Asian Input Method Editors are supported. + Autocompletion lists and calltips implemented. + Control identifier used in notifications. +
  • +
  • + On Cocoa, rectangular selection now uses Option/Alt key to be compatible with Apple Human + Interface Guidelines and other applications. + The Control key is reported with an SCMOD_META modifier bit. +
  • +
  • + API added for setting and retrieving the identifier number used in notifications. +
  • +
  • + SCI_SETEMPTYSELECTION added to set selection without scrolling or redrawing more than needed. + Feature #3314877. +
  • +
  • + Added new indicators. INDIC_DASH and INDIC_DOTS are variants of underlines. + INDIC_SQUIGGLELOW indicator added as shorter alternative to INDIC_SQUIGGLE for small fonts. + Bug #3314591 +
  • +
  • + Margin line selection can be changed to select display lines instead of document lines. + Bug #3312763. +
  • +
  • + On Windows, SciTE can perform reverse searches by pressing Shift+Enter + in the Find or Replace strips or dialogs. +
  • +
  • + Matlab lexer does not special case '\' in single quoted strings. + Bug #948757 + Bug #1755950 + Bug #1888738 + Bug #3316852. +
  • +
  • + Verilog lexer supports SystemVerilog folding and keywords. +
  • +
  • + Font leak fixed. + Bug #3306156. +
  • +
  • + Automatic scrolling works for long wrapped lines. + Bug #3312763. +
  • +
  • + Multiple typing works for cases where selections collapse together. + Bug #3309906. +
  • +
  • + Fold expanded when needed in word wrap mode. + Bug #3291579. +
  • +
  • + Bug fixed with edge drawn in wrong place on wrapped lines. + Bug #3314807. +
  • +
  • + Bug fixed with unnecessary scrolling for SCI_GOTOLINE. + Bug #3303406. +
  • +
  • + Bug fixed where extra step needed to undo SCI_CLEAR in virtual space. + Bug #3159691. +
  • +
  • + Regular expression search fixed for \$ on last line of search range. + Bug #3313746. +
  • +
  • + SciTE performance improved when switching to a tab with a very large file. + Bug #3311421. +
  • +
  • + On Windows, SciTE advanced search remembers the "Search only in this style" setting. + Bug #3313344. +
  • +
  • + On GTK+, SciTE opens help using "xdg-open" instead of "netscape" as "netscape" no longer commonly installed. + Bug #3314377. +
  • +
  • + SciTE script lexers can use 256 styles. +
  • +
  • + SciTE word highlight works for words containing DBCS characters. + Bug #3315173. +
  • +
  • + Compilation fixed for wxWidgets. + Bug #3306156. +
  • +
+

+ Release 2.26 +

+
    +
  • + Released 25 May 2011. +
  • +
  • + Folding margin symbols can be highlighted for the current folding block. + Feature #3147069. +
  • +
  • + Selected lines can be moved up or down together. + Feature #3304850. +
  • +
  • + SciTE can highlight all occurrences of the current word or selected text. + Feature #3291636. +
  • +
  • + Experimental GTK+ 3.0 support: build with "make GTK3=1". +
  • +
  • + INDIC_STRAIGHTBOX added. Is similar to INDIC_ROUNDBOX but without rounded corners. + Bug #3290435. +
  • +
  • + Can show brace matching and mismatching with indicators instead of text style. + Translucency of outline can be altered for INDIC_ROUNDBOX and INDIC_STRAIGHTBOX. + Feature #3290434. +
  • +
  • + SciTE can automatically indent python by examining previous line for scope-starting ':' with indent.python.colon. +
  • +
  • + Batch file lexer allows braces '(' or ')' inside variable names. +
  • +
  • + The cpp lexer only recognises Vala triple quoted strings when lexer.cpp.triplequoted.strings property is set. + Bug #3239234. +
  • +
  • + Make file lexer treats a variable with a nested variable like $(f$(qx)b) as one variable. + Bug #3298223. +
  • +
  • + Folding bug fixed for JavaScript with nested PHP. + Bug #3193530. +
  • +
  • + HTML lexer styles Django's {# #} comments. + Bug #3013798. +
  • +
  • + HTML lexer styles JavaScript regular expression correctly for /abc/i.test('abc');. + Bug #3209108. +
  • +
  • + Inno Setup Script lexer now works properly when it restarts from middle of [CODE] section. + Bug #3283880. + Bug #3129044. +
  • +
  • + Lua lexer updated for Lua 5.2 with hexadecimal floating-point numbers and '\*' whitespace escaping in strings. + Feature #3243811. +
  • +
  • + Perl folding folds "here doc"s and adds options fold.perl.at.else and fold.perl.comment.explicit. Fold structure for Perl fixed. + Feature #3112671. + Bug #3265401. +
  • +
  • + Python lexer supports cpdef keyword for Cython. + Bug #3279728. +
  • +
  • + SQL folding option lexer.sql.fold.at.else renamed to fold.sql.at.else. + Bug #3271474. +
  • +
  • + SQL lexer no longer treats ';' as terminating a comment. + Bug #3196071. +
  • +
  • + Text drawing and measurement segmented into smaller runs to avoid platform bugs. + Bug #3277449. + Bug #3165743. +
  • +
  • + SciTE on Windows adds temp.files.sync.load property to open dropped temporary files synchronously as they may + be removed before they can be opened asynchronously. + Bug #3072009. +
  • +
  • + Bug fixed with indentation guides ignoring first line in SC_IV_LOOKBOTH mode. + Bug #3291317. +
  • +
  • + Bugs fixed in backward regex search. + Bug #3292659. +
  • +
  • + Bugs with display of folding structure fixed for wrapped lines and where there is a fold header but no body. + Bug #3291579. + Bug #3265401. +
  • +
  • + SciTE on Windows cursor changes to an arrow now when over horizontal splitter near top of window. + Bug #3286620. +
  • +
  • + Fixed default widget size problem on GTK+. + Bug #3267892. +
  • +
  • + Fixed font size when using Cairo on GTK+. + Bug #3272662. +
  • +
  • + Fixed primary selection and cursor issues on GTK+ when unrealized then realized. + Bug #3256153. +
  • +
  • + Right click now cancels selection on GTK+ like on Windows. + Bug #3235190. +
  • +
  • + SciTE on GTK+ implements z-order buffer switching like on Windows. + Bug #3228384. +
  • +
  • + Improve selection position after SciTE Insert Abbreviation command when abbreviation expansion includes '|'. +
  • +

Release 2.25

diff --git a/scintilla/doc/ScintillaRelated.html b/scintilla/doc/ScintillaRelated.html index fd9a4880..f060ce0f 100644 --- a/scintilla/doc/ScintillaRelated.html +++ b/scintilla/doc/ScintillaRelated.html @@ -28,6 +28,14 @@

Ports and Bindings of Scintilla

+

+ GtkScintilla + is a GTK+ widget which enables easily adding a powerful + source code editor to your applications. Harnessing the abilities + of the Scintilla editing component, GtkScintilla adds a familiar + GTK+/GObject API, making the widget comfortable to use in + these programs, using all the typical GObject conventions. +

Editawy is an ActiveX Control wrapper that support all Scintilla functions and additional high level functions. @@ -99,11 +107,6 @@ is a Python binding for gtk1.x scintilla that uses gtkscintilla instead of the default GTK class.

-

- pyscintilla2 - is a Python binding for GTK 2.x scintilla that uses - gtkscintilla2. -

ScintillaCtrl is an unmaintained ActiveX control wrapper for Scintilla. @@ -112,7 +115,7 @@ Projects using Scintilla

- Coder's Studio + CoderStudio is an IDE for Assembly programming similar to Visual Studio 6.0.

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