[UPDATE] Update Scintilla to 2.27.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@791 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2011-07-17 22:30:49 +00:00
parent f1d217157b
commit 10dc4e06d7
68 changed files with 4317 additions and 2665 deletions

View File

@ -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;

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 <class T>
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

View File

@ -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<char*>( 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

View File

@ -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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#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

View File

@ -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<HIViewRef>( 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<int>( location.x ), static_cast<int>( 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<HIObjectRef*>( &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();
}
}

View File

@ -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);
};

View File

@ -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<unsigned char>(mixed[0])];
return 1;
} else {
CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(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<unsigned char>(mixed[0])];
return 1;
} else {
CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(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<const UInt8 *>(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<const UInt8 *>(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<sptr_t>(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();
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -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;

View File

@ -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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#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

View File

@ -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<HIViewRef>( 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<int>( location.x ), static_cast<int>( 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<HIObjectRef*>( &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();
}
}

View File

@ -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;
};

View File

@ -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 <InfoBarCommunicator>*) aView top: (BOOL) top;
- (void) setStatusText: (NSString*) text;

View File

@ -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<SCNotification*>(lParam);
editor = reinterpret_cast<InnerView*>(scn->nmhdr.idFrom).owner;
ScintillaCocoa *psc = reinterpret_cast<ScintillaCocoa*>(scn->nmhdr.hwndFrom);
editor = reinterpret_cast<InnerView*>(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);
}
//--------------------------------------------------------------------------------------------------
/**

View File

@ -98,55 +98,53 @@
Introduction
</h3>
<p>
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.
</p>
<p>
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.
</p>
<p>
The <a href="http://astyle.sourceforge.net/">AStyle</a> 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 <a href="http://astyle.sourceforge.net/">AStyle</a> formatting
program with '-taOHUKk3 -M8' arguments formats code in much the right way although
there are a few bugs in AStyle.
</p>
<h3>
Language features
</h3>
<p>
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.
</p>
<p>
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.
</p>
<p>
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.
</p>
<h3>
Casting
</h3>
<p>
Do not use old C style casts like (char *)s. Instead use the most strict form of C++
cast possible like const_cast&lt;char *&gt;(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&lt;char *&gt;(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.
</p>
<p>
@ -162,26 +160,26 @@
</h3>
<p>
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.
</p>
<p>
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.
</p>
<h3>
Allocation
</h3>
<p>
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.
</p>
<p>
The C++ new and delete operators are preferred over C's malloc and free
@ -193,11 +191,11 @@
<p>
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.
</p>
<SPAN class=S0></SPAN><SPAN class=S5>bool</SPAN><SPAN class=S0>&nbsp;</SPAN><SPAN class=S11>fn</SPAN><SPAN class=S10>(</SPAN><SPAN class=S5>int</SPAN><SPAN class=S0>&nbsp;</SPAN><SPAN class=S11>a</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0>&nbsp;</SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR>
@ -213,10 +211,10 @@
Spacing
</h3>
<p>
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 '('.
</p>
@ -232,10 +230,10 @@
<p>
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.
</p>
<SPAN class=S0></SPAN><SPAN class=S5>class</SPAN><SPAN class=S0>&nbsp;</SPAN><SPAN class=S11>StorageZone</SPAN><SPAN class=S0>&nbsp;</SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR>
@ -250,7 +248,7 @@
<h3>
Submitting a lexer
</h3>
<p>Add a public feature request to the <a href="https://sourceforge.net/tracker/?group_id=2439&atid=352439">Feature Request Tracker</a>.</p>
<p>Send all the modified and new files as full text (not patches) in an archive (.zip or .tgz).</p>
<p>Define all of the lexical states in a modified Scintilla.iface.</p>

View File

@ -79,7 +79,7 @@
<h1>Scintilla Documentation</h1>
<p>Last edited 19/January/2011 NH</p>
<p>Last edited 18/June/2011 NH</p>
<p>There is <a class="jump" href="Design.html">an overview of the internal design of
Scintilla</a>.<br />
@ -625,10 +625,9 @@ struct Sci_TextRange {
</tbody>
</table>
<p>If <code>SCFIND_REGEXP</code> is not included in the <code>searchFlags</code>, you can
<p>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 <code>SCFIND_REGEXP</code> is included, searches are always
from a lower position to a higher position, even if the search range is backwards.</p>
search range before the start.</p>
<p>In a regular expression, special characters interpreted are:</p>
@ -722,6 +721,8 @@ struct Sci_TextRange {
</tbody>
</table>
<p>Regular expressions will only match ranges within a single line, never matching over multiple lines.</p>
<p><b id="SCI_FINDTEXT">SCI_FINDTEXT(int searchFlags, <a class="jump"
href="#Sci_TextToFind">Sci_TextToFind</a> *ttf)</b><br />
This message searches for text in the document. It does not use or move the current selection.
@ -730,9 +731,8 @@ struct Sci_TextRange {
<p>The <code>Sci_TextToFind</code> structure is defined in <code>Scintilla.h</code>; set
<code>chrg.cpMin</code> and <code>chrg.cpMax</code> with the range of positions in the document
to search. If <code>SCFIND_REGEXP</code> is not included in the flags, you can search backwards by
setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>. If <code>SCFIND_REGEXP</code>
is included, the search is always forwards (even if <code>chrg.cpMax</code> is less than <code>chrg.cpMin</code>).
to search. You can search backwards by
setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>.
Set the <code>lpstrText</code> member of <code>Sci_TextToFind</code> to point at a zero terminated
text string holding the search pattern. If your language makes the use of <code>Sci_TextToFind</code>
difficult, you should consider using <code>SCI_SEARCHINTARGET</code> instead.</p>
@ -772,9 +772,7 @@ struct Sci_TextToFind {
<p><code>SCI_SEARCHNEXT</code> and <code>SCI_SEARCHPREV</code> search for the next and previous
occurrence of the zero terminated search string pointed at by text. The search is modified by
the <a class="jump" href="#searchFlags"><code>searchFlags</code></a>. If you request a regular
expression, <code>SCI_SEARCHPREV</code> finds the first occurrence of the search string in the
document, not the previous one before the anchor point.</p>
the <a class="jump" href="#searchFlags"><code>searchFlags</code></a>. </p>
<p>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 {
<a class="message" href="#SCI_GETSELECTIONSTART">SCI_GETSELECTIONSTART</a><br />
<a class="message" href="#SCI_SETSELECTIONEND">SCI_SETSELECTIONEND(int position)</a><br />
<a class="message" href="#SCI_GETSELECTIONEND">SCI_GETSELECTIONEND</a><br />
<a class="message" href="#SCI_SETEMPTYSELECTION">SCI_SETEMPTYSELECTION(int pos)</a><br />
<a class="message" href="#SCI_SELECTALL">SCI_SELECTALL</a><br />
<a class="message" href="#SCI_LINEFROMPOSITION">SCI_LINEFROMPOSITION(int position)</a><br />
<a class="message" href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(int line)</a><br />
@ -1114,6 +1113,8 @@ struct Sci_TextToFind {
<a class="message" href="#SCI_TEXTWIDTH">SCI_TEXTWIDTH(int styleNumber, const char *text)</a><br />
<a class="message" href="#SCI_TEXTHEIGHT">SCI_TEXTHEIGHT(int line)</a><br />
<a class="message" href="#SCI_CHOOSECARETX">SCI_CHOOSECARETX</a><br />
<a class="message" href="#SCI_MOVESELECTEDLINESUP">SCI_MOVESELECTEDLINESUP</a><br />
<a class="message" href="#SCI_MOVESELECTEDLINESDOWN">SCI_MOVESELECTEDLINESDOWN</a><br />
</code>
<p><b id="SCI_GETTEXTLENGTH">SCI_GETTEXTLENGTH</b><br />
@ -1229,6 +1230,9 @@ struct Sci_TextToFind {
current position or the anchor position. <code>SCI_GETSELECTIONEND</code> returns the larger of
the two values.</p>
<p><b id="SCI_SETEMPTYSELECTION">SCI_SETEMPTYSELECTION(int pos)</b><br />
This removes any selection and sets the caret at <code>pos</code>. The caret is not scrolled into view.</p>
<p><b id="SCI_SELECTALL">SCI_SELECTALL</b><br />
This selects all the text in the document. The current position is not scrolled into view.</p>
@ -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.</p>
<p><b id="SCI_MOVESELECTEDLINESUP">SCI_MOVESELECTEDLINESUP</b><br />
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.</p>
<p><b id="SCI_MOVESELECTEDLINESDOWN">SCI_MOVESELECTEDLINESDOWN</b><br />
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.</p>
<h2 id="MultipleSelectionAndVirtualSpace">Multiple Selection and Virtual Space</h2>
<code>
@ -1549,7 +1563,8 @@ struct Sci_TextToFind {
<p>
<b id="SCI_SETMULTIPLESELECTION">SCI_SETMULTIPLESELECTION(bool multipleSelection)</b><br />
<b id="SCI_GETMULTIPLESELECTION">SCI_GETMULTIPLESELECTION</b><br />
Enable or disable multiple selection.</p>
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.</p>
<p>
<b id="SCI_SETADDITIONALSELECTIONTYPING">SCI_SETADDITIONALSELECTIONTYPING(bool additionalSelectionTyping)</b><br />
@ -2742,6 +2757,8 @@ struct Sci_TextToFind {
<a class="message" href="#SCI_MARGINTEXTCLEARALL">SCI_MARGINTEXTCLEARALL</a><br />
<a class="message" href="#SCI_MARGINSETSTYLEOFFSET">SCI_MARGINSETSTYLEOFFSET(int style)</a><br />
<a class="message" href="#SCI_MARGINGETSTYLEOFFSET">SCI_MARGINGETSTYLEOFFSET</a><br />
<a class="message" href="#SCI_SETMARGINOPTIONS">SCI_SETMARGINOPTIONS(int marginOptions)</a><br />
<a class="message" href="#SCI_GETMARGINOPTIONS">SCI_GETMARGINOPTIONS</a><br />
</code>
<p><b id="SCI_SETMARGINTYPEN">SCI_SETMARGINTYPEN(int margin, int iType)</b><br />
@ -2849,6 +2866,15 @@ struct Sci_TextToFind {
256 upto 511 so they do not overlap styles set by lexers. Each style number set with <code>SCI_MARGINSETSTYLE</code>
or <code>SCI_MARGINSETSTYLES</code> has the offset added before looking up the style.
</p>
<p>
<b id="SCI_SETMARGINOPTIONS">SCI_SETMARGINOPTIONS(int marginOptions)</b><br />
<b id="SCI_GETMARGINOPTIONS">SCI_GETMARGINOPTIONS</b><br />
Define margin options by enabling appropriate bit flags. At the moment, only one flag is available
<code>SC_MARGINOPTION_SUBLINESELECT</code>=1, which controls how wrapped lines are selected when clicking
on margin in front of them. If <code>SC_MARGINOPTION_SUBLINESELECT</code> is set only sub line of wrapped
line is selected, otherwise whole wrapped line is selected. Margin options are set to
<code>SC_MARGINOPTION_NONE</code>=0 by default.
</p>
<h2 id="Annotations">Annotations</h2>
@ -3089,6 +3115,8 @@ struct Sci_TextToFind {
<code><a class="message" href="#SCI_BRACEHIGHLIGHT">SCI_BRACEHIGHLIGHT(int pos1, int
pos2)</a><br />
<a class="message" href="#SCI_BRACEBADLIGHT">SCI_BRACEBADLIGHT(int pos1)</a><br />
<a class="message" href="#SCI_BRACEHIGHLIGHTINDICATOR">SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)</a><br />
<a class="message" href="#SCI_BRACEBADLIGHTINDICATOR">SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)</a><br />
<a class="message" href="#SCI_BRACEMATCH">SCI_BRACEMATCH(int position, int
maxReStyle)</a><br />
</code>
@ -3107,6 +3135,12 @@ struct Sci_TextToFind {
that is unmatched. Using a position of <code>INVALID_POSITION</code> (-1) removes the
highlight.</p>
<p><b id="#SCI_BRACEHIGHLIGHTINDICATOR">SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)</b><br />
Use specified indicator to highlight matching braces instead of changing their style.</p>
<p><b id="#SCI_BRACEBADLIGHTINDICATOR">SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)</b><br />
Use specified indicator to highlight non matching brace instead of changing its style.</p>
<p><b id="SCI_BRACEMATCH">SCI_BRACEMATCH(int pos, int maxReStyle)</b><br />
The <code>SCI_BRACEMATCH</code> message finds a corresponding matching brace given
<code>pos</code>, the position of one brace. The brace characters handled are '(', ')', '[',
@ -3275,6 +3309,9 @@ struct Sci_TextToFind {
colour)</a><br />
<a class="message" href="#SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int
colour)</a><br />
<a class="message" href="#SCI_MARKERSETBACKSELECTED">SCI_MARKERSETBACKSELECTED(int markerNumber, int
colour)</a><br />
<a class="message" href="#SCI_MARKERENABLEHIGHLIGHT">SCI_MARKERENABLEHIGHLIGHT(int enabled)</a><br />
<a class="message" href="#SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int
alpha)</a><br />
<a class="message" href="#SCI_MARKERADD">SCI_MARKERADD(int line, int markerNumber)</a><br />
@ -3461,7 +3498,12 @@ struct Sci_TextToFind {
href="#colour">colour</a>)</b><br />
<b id="SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int <a class="jump"
href="#colour">colour</a>)</b><br />
These two messages set the foreground and background colour of a marker number.</p>
These two messages set the foreground and background colour of a marker number.<br />
<b id="SCI_MARKERSETBACKSELECTED">SCI_MARKERSETBACKSELECTED(int markerNumber, int <a class="jump"
href="#colour">colour</a>)</b><br />
This message sets the highlight background colour of a marker number when its folding block is selected. The default colour is #FF0000.</p>
<p><b id="SCI_MARKERENABLEHIGHLIGHT">SCI_MARKERENABLEHIGHLIGHT(bool enabled)</b><br />
This message allows to enable/disable the highlight folding block when it is selected. (i.e. block that contains the caret)</p>
<p><b id="SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int <a class="jump"
href="#alpha">alpha</a>)</b><br />
When markers are drawn in the content area, either because there is no margin for them or
@ -3549,6 +3591,8 @@ struct Sci_TextToFind {
<a class="message" href="#SCI_INDICGETFORE">SCI_INDICGETFORE(int indicatorNumber)</a><br />
<a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</a><br />
<a class="message" href="#SCI_INDICGETALPHA">SCI_INDICGETALPHA(int indicatorNumber)</a><br />
<a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)</a><br />
<a class="message" href="#SCI_INDICGETOUTLINEALPHA">SCI_INDICGETOUTLINEALPHA(int indicatorNumber)</a><br />
<a class="message" href="#SCI_INDICSETUNDER">SCI_INDICSETUNDER(int indicatorNumber, bool under)</a><br />
<a class="message" href="#SCI_INDICGETUNDER">SCI_INDICGETUNDER(int indicatorNumber)</a><br />
</code>
@ -3584,7 +3628,7 @@ struct Sci_TextToFind {
<td align="center">1</td>
<td>A squiggly underline.</td>
<td>A squiggly underline. Requires 3 pixels of descender space.</td>
</tr>
<tr>
@ -3633,11 +3677,49 @@ struct Sci_TextToFind {
<td align="center">7</td>
<td>A rectangle with rounded corners around the text using translucent drawing with the
interior more transparent than the border. You can use
<a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a>
to control the alpha transparency value. The default alpha value is 30.
</td>
interior usually more transparent than the border. You can use
<a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and
<a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a>
to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour.</td>
</tr>
<tr>
<td align="left"><code>INDIC_STRAIGHTBOX</code></td>
<td align="center">8</td>
<td>A rectangle around the text using translucent drawing with the
interior usually more transparent than the border. You can use
<a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and
<a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a>
to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour.</td>
</tr>
<tr>
<td align="left"><code>INDIC_DASH</code></td>
<td align="center">9</td>
<td>A dashed underline.</td>
</tr>
<tr>
<td align="left"><code>INDIC_DOTS</code></td>
<td align="center">10</td>
<td>A dotted underline.</td>
</tr>
<tr>
<td align="left"><code>INDIC_SQUIGGLELOW</code></td>
<td align="center">11</td>
<td>Similar to <code>INDIC_SQUIGGLE</code> but only using 2 vertical pixels
so will fit under small fonts.</td>
</tr>
</tbody>
</table>
@ -3657,7 +3739,14 @@ struct Sci_TextToFind {
<p><b id="SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</b><br />
<b id="SCI_INDICGETALPHA">SCI_INDICGETALPHA(int indicatorNumber)</b><br />
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).
</p>
<p><b id="SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)</b><br />
<b id="SCI_INDICGETOUTLINEALPHA">SCI_INDICGETOUTLINEALPHA(int indicatorNumber)</b><br />
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).
</p>
@ -3677,8 +3766,8 @@ struct Sci_TextToFind {
<b id="SCI_SETINDICATORCURRENT">SCI_SETINDICATORCURRENT(int indicator)</b><br />
<b id="SCI_GETINDICATORCURRENT">SCI_GETINDICATORCURRENT</b><br />
These two messages set and get the indicator that will be affected by calls to
<a class="message" href="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE</a> and
<a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE</a>.
<a class="message" href="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE(int position, int fillLength)</a> and
<a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE(int position, int clearLength)</a>.
</p>
<p>
@ -4302,6 +4391,12 @@ struct Sci_TextToFind {
<td><code>SCI_VERTICALCENTRECARET</code></td>
</tr>
<tr>
<td><code>SCI_MOVESELECTEDLINESUP</code></td>
<td><code>SCI_MOVESELECTEDLINESDOWN</code></td>
</tr>
</tbody>
</table>
@ -4360,7 +4455,10 @@ struct Sci_TextToFind {
<code>SCK_WIN</code>.</p>
<p>The modifiers are a combination of zero or more of <code>SCMOD_ALT</code>,
<code>SCMOD_CTRL</code>, and <code>SCMOD_SHIFT</code>. If you are building a table, you might
<code>SCMOD_CTRL</code>, <code>SCMOD_SHIFT</code>, and <code>SCMOD_META</code>.
On OS X, the Command key is mapped to <code>SCMOD_CTRL</code> and the Control key to
<code>SCMOD_META</code>.
If you are building a table, you might
want to use <code>SCMOD_NORM</code>, which has the value 0, to mean no modifiers.</p>
<p><b id="SCI_ASSIGNCMDKEY">SCI_ASSIGNCMDKEY(int <a class="jump"
@ -5509,6 +5607,11 @@ where it can be applied to each document. This avoids the costs of
constructing the system header information for each document. This is
invoked with the <code>SCI_PRIVATELEXERCALL</code> API.</p>
<p><code>Fold</code> 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.</p>
<h4>IDocument</h4>
@ -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 */
};
</pre>
@ -5737,11 +5847,12 @@ struct SCNotification {
</code>
<p>The following <code>SCI_*</code> messages are associated with these notifications:</p>
<code><a class="message" href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int
eventMask)</a><br />
<code><a class="message" href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int eventMask)</a><br />
<a class="message" href="#SCI_GETMODEVENTMASK">SCI_GETMODEVENTMASK</a><br />
<a class="message" href="#SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME</a><br />
<a class="message" href="#SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME(int milliseconds)</a><br />
<a class="message" href="#SCI_GETMOUSEDWELLTIME">SCI_GETMOUSEDWELLTIME</a><br />
<a class="message" href="#SCI_SETIDENTIFIER">SCI_SETIDENTIFIER(int identifier)</a><br />
<a class="message" href="#SCI_GETIDENTIFIER">SCI_GETIDENTIFIER</a><br />
</code>
<p>The following additional notifications are sent using the <code>WM_COMMAND</code> message on
@ -5752,6 +5863,17 @@ struct SCNotification {
<a class="message" href="#SCEN_KILLFOCUS">SCEN_KILLFOCUS</a><br />
</code>
<p><b id="SCI_SETIDENTIFIER">SCI_SETIDENTIFIER(int identifier)</b><br />
<b id="SCI_GETIDENTIFIER">SCI_GETIDENTIFIER</b><br />
These two messages set and get the identifier of the Scintilla instance which is included in notifications as the
<code>idFrom</code> 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 <code>CreateWindow</code> call and stored as the
<code>GWLP_ID</code> 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.
</p>
<p><b id="SCN_STYLENEEDED">SCN_STYLENEEDED</b><br />
If you used <code><a class="message"
href="#SCI_SETLEXER">SCI_SETLEXER</a>(SCLEX_CONTAINER)</code> to make the container act as the
@ -5799,12 +5921,14 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber);
<p><b id="SCN_DOUBLECLICK">SCN_DOUBLECLICK</b><br />
The mouse button was double clicked in editor. The <code>position</code> field is set to the text position of the
double click and the <code>line</code> field is set to the line of the double click.</p>
double click, the <code>line</code> field is set to the line of the double click, and
the <code>modifiers</code> field is set to the key modifiers
held down in a similar manner to <a class="message" href="#SCN_KEY">SCN_KEY</a>.</p>
<p><b id="SCN_UPDATEUI">SCN_UPDATEUI</b><br />
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 <code>updated</code> field is set to the bit set of things changed since the previous notiication.</p>
The <code>updated</code> field is set to the bit set of things changed since the previous notification.</p>
<table cellpadding="1" cellspacing="2" border="0" summary="Modify notification type flags">
<tbody>
<tr>
@ -6328,7 +6452,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<tbody valign="top">
<tr>
<td align="left"><code>wParam</code></td>
<td align="left"><code>listType</code></td>
<td align="left">This is set to the <code>listType</code> parameter from the <a
class="message" href="#SCI_USERLISTSHOW"><code>SCI_USERLISTSHOW</code></a> message that
@ -6340,10 +6464,15 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<td align="left">The text of the selection.</td>
</tr>
<tr>
<td align="left"><code>position</code></td>
<td align="left">The position the list was displayed at.</td>
</tr>
</tbody>
</table>
<br />
<br />
<p><b id="SCN_URIDROPPED">SCN_URIDROPPED</b><br />
@ -6387,9 +6516,8 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
</tbody>
</table>
<br />
<br />
<p><b id="SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME</b><br />
<p><b id="SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME(int milliseconds)</b><br />
<b id="SCI_GETMOUSEDWELLTIME">SCI_GETMOUSEDWELLTIME</b><br />
These two messages set and get the time the mouse must sit still, in milliseconds, to generate
a <code><a class="message" href="#SCN_DWELLSTART">SCN_DWELLSTART</a></code> notification. If
@ -6447,7 +6575,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<tbody valign="top">
<tr>
<td align="left"><code>lParam</code></td>
<td align="left"><code>position</code></td>
<td align="left">The start position of the word being completed.</td>
</tr>
@ -6482,9 +6610,8 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<p><b id="scintilla_set_id">void scintilla_set_id(ScintillaObject *sci, uptr_t id)</b><br />
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.</p>
notifications for this instance.
This is equivalent to <a class="message" href="#SCI_SETIDENTIFIER">SCI_SETIDENTIFIER</a>.</p>
<p><b id="scintilla_send_message">sptr_t scintilla_send_message(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam)</b><br />
The main entry point allows sending any of the messages described in this document.</p>

View File

@ -25,9 +25,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr>
<td>
<font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.zip?download">
<font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla227.zip?download">
Windows</a>&nbsp;&nbsp;
<a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.tgz?download">
<a href="http://prdownloads.sourceforge.net/scintilla/scintilla227.tgz?download">
GTK+/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -41,7 +41,7 @@
containing very few restrictions.
</p>
<h3>
Release 2.25
Release 2.27
</h3>
<h4>
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
<ul>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.zip?download">zip format</a> (1200K) commonly used on Windows</li>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla227.zip?download">zip format</a> (1200K) commonly used on Windows</li>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla227.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -368,6 +368,16 @@
</tr><tr>
<td>Dariusz Knociński</td>
<td>Ben Fisher</td>
<td>Don Gobin</td>
<td>John Yeung</td>
</tr><tr>
<td>Adobe</td>
<td>Elizabeth A. Irizarry</td>
<td>Mike Schroeder</td>
<td>Morten MacFly</td>
</tr><tr>
<td>Jaime Gimeno</td>
<td>Thomas Linder Puls</td>
</tr>
</table>
<p>
@ -379,6 +389,251 @@
Icons</a> Copyright(C) 1998 by Dean S. Jones<br />
</li>
</ul>
<h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite227.zip?download">Release 2.27</a>
</h3>
<ul>
<li>
Released 20 June 2011.
</li>
<li>
On recent GTK+ 2.x versions when using Cairo, bug fixed where wrong colours were drawn.
</li>
<li>
SciTE on GTK+ slow performance in menu maintenance fixed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315233&group_id=2439">Bug #3315233.</a>
</li>
<li>
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.
</li>
<li>
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.
</li>
<li>
API added for setting and retrieving the identifier number used in notifications.
</li>
<li>
SCI_SETEMPTYSELECTION added to set selection without scrolling or redrawing more than needed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3314877&group_id=2439">Feature #3314877.</a>
</li>
<li>
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.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314591&group_id=2439">Bug #3314591</a>
</li>
<li>
Margin line selection can be changed to select display lines instead of document lines.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439">Bug #3312763.</a>
</li>
<li>
On Windows, SciTE can perform reverse searches by pressing Shift+Enter
in the Find or Replace strips or dialogs.
</li>
<li>
Matlab lexer does not special case '\' in single quoted strings.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=948757&group_id=2439">Bug #948757</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1755950&group_id=2439">Bug #1755950</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1888738&group_id=2439">Bug #1888738</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3316852&group_id=2439">Bug #3316852.</a>
</li>
<li>
Verilog lexer supports SystemVerilog folding and keywords.
</li>
<li>
Font leak fixed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439">Bug #3306156.</a>
</li>
<li>
Automatic scrolling works for long wrapped lines.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439">Bug #3312763.</a>
</li>
<li>
Multiple typing works for cases where selections collapse together.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3309906&group_id=2439">Bug #3309906.</a>
</li>
<li>
Fold expanded when needed in word wrap mode.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439">Bug #3291579.</a>
</li>
<li>
Bug fixed with edge drawn in wrong place on wrapped lines.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314807&group_id=2439">Bug #3314807.</a>
</li>
<li>
Bug fixed with unnecessary scrolling for SCI_GOTOLINE.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3303406&group_id=2439">Bug #3303406.</a>
</li>
<li>
Bug fixed where extra step needed to undo SCI_CLEAR in virtual space.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3159691&group_id=2439">Bug #3159691.</a>
</li>
<li>
Regular expression search fixed for \$ on last line of search range.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313746&group_id=2439">Bug #3313746.</a>
</li>
<li>
SciTE performance improved when switching to a tab with a very large file.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3311421&group_id=2439">Bug #3311421.</a>
</li>
<li>
On Windows, SciTE advanced search remembers the "Search only in this style" setting.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313344&group_id=2439">Bug #3313344.</a>
</li>
<li>
On GTK+, SciTE opens help using "xdg-open" instead of "netscape" as "netscape" no longer commonly installed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314377&group_id=2439">Bug #3314377.</a>
</li>
<li>
SciTE script lexers can use 256 styles.
</li>
<li>
SciTE word highlight works for words containing DBCS characters.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315173&group_id=2439">Bug #3315173.</a>
</li>
<li>
Compilation fixed for wxWidgets.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439">Bug #3306156.</a>
</li>
</ul>
<h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite226.zip?download">Release 2.26</a>
</h3>
<ul>
<li>
Released 25 May 2011.
</li>
<li>
Folding margin symbols can be highlighted for the current folding block.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3147069&group_id=2439">Feature #3147069.</a>
</li>
<li>
Selected lines can be moved up or down together.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3304850&group_id=2439">Feature #3304850.</a>
</li>
<li>
SciTE can highlight all occurrences of the current word or selected text.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3291636&group_id=2439">Feature #3291636.</a>
</li>
<li>
Experimental GTK+ 3.0 support: build with "make GTK3=1".
</li>
<li>
INDIC_STRAIGHTBOX added. Is similar to INDIC_ROUNDBOX but without rounded corners.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3290435&group_id=2439">Bug #3290435.</a>
</li>
<li>
Can show brace matching and mismatching with indicators instead of text style.
Translucency of outline can be altered for INDIC_ROUNDBOX and INDIC_STRAIGHTBOX.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3290434&group_id=2439">Feature #3290434.</a>
</li>
<li>
SciTE can automatically indent python by examining previous line for scope-starting ':' with indent.python.colon.
</li>
<li>
Batch file lexer allows braces '(' or ')' inside variable names.
</li>
<li>
The cpp lexer only recognises Vala triple quoted strings when lexer.cpp.triplequoted.strings property is set.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3239234&group_id=2439">Bug #3239234.</a>
</li>
<li>
Make file lexer treats a variable with a nested variable like $(f$(qx)b) as one variable.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3298223&group_id=2439">Bug #3298223.</a>
</li>
<li>
Folding bug fixed for JavaScript with nested PHP.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3193530&group_id=2439">Bug #3193530.</a>
</li>
<li>
HTML lexer styles Django's {# #} comments.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3013798&group_id=2439">Bug #3013798.</a>
</li>
<li>
HTML lexer styles JavaScript regular expression correctly for /abc/i.test('abc');.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3209108&group_id=2439">Bug #3209108.</a>
</li>
<li>
Inno Setup Script lexer now works properly when it restarts from middle of [CODE] section.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3283880&group_id=2439">Bug #3283880.</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3129044&group_id=2439">Bug #3129044.</a>
</li>
<li>
Lua lexer updated for Lua 5.2 with hexadecimal floating-point numbers and '\*' whitespace escaping in strings.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3243811&group_id=2439">Feature #3243811.</a>
</li>
<li>
Perl folding folds "here doc"s and adds options fold.perl.at.else and fold.perl.comment.explicit. Fold structure for Perl fixed.
<a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3112671&group_id=2439">Feature #3112671.</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439">Bug #3265401.</a>
</li>
<li>
Python lexer supports cpdef keyword for Cython.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3279728&group_id=2439">Bug #3279728.</a>
</li>
<li>
SQL folding option lexer.sql.fold.at.else renamed to fold.sql.at.else.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3271474&group_id=2439">Bug #3271474.</a>
</li>
<li>
SQL lexer no longer treats ';' as terminating a comment.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3196071&group_id=2439">Bug #3196071.</a>
</li>
<li>
Text drawing and measurement segmented into smaller runs to avoid platform bugs.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3277449&group_id=2439">Bug #3277449.</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3165743&group_id=2439">Bug #3165743.</a>
</li>
<li>
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.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3072009&group_id=2439">Bug #3072009.</a>
</li>
<li>
Bug fixed with indentation guides ignoring first line in SC_IV_LOOKBOTH mode.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291317&group_id=2439">Bug #3291317.</a>
</li>
<li>
Bugs fixed in backward regex search.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3292659&group_id=2439">Bug #3292659.</a>
</li>
<li>
Bugs with display of folding structure fixed for wrapped lines and where there is a fold header but no body.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439">Bug #3291579.</a>
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439">Bug #3265401.</a>
</li>
<li>
SciTE on Windows cursor changes to an arrow now when over horizontal splitter near top of window.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3286620&group_id=2439">Bug #3286620.</a>
</li>
<li>
Fixed default widget size problem on GTK+.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3267892&group_id=2439">Bug #3267892.</a>
</li>
<li>
Fixed font size when using Cairo on GTK+.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3272662&group_id=2439">Bug #3272662.</a>
</li>
<li>
Fixed primary selection and cursor issues on GTK+ when unrealized then realized.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3256153&group_id=2439">Bug #3256153.</a>
</li>
<li>
Right click now cancels selection on GTK+ like on Windows.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3235190&group_id=2439">Bug #3235190.</a>
</li>
<li>
SciTE on GTK+ implements z-order buffer switching like on Windows.
<a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3228384&group_id=2439">Bug #3228384.</a>
</li>
<li>
Improve selection position after SciTE Insert Abbreviation command when abbreviation expansion includes '|'.
</li>
</ul>
<h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite225.zip?download">Release 2.25</a>
</h3>

View File

@ -28,6 +28,14 @@
<h3>
Ports and Bindings of Scintilla
</h3>
<p>
<a href="http://codebrainz.github.com/GtkScintilla/">GtkScintilla</a>
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.
</p>
<p>
<a href="http://mewsoft.com/cgi-bin/forum/forum.cgi?action=ViewTopic&Topic=1494&Forum=1&Page=1&Period=0a&Lang=English">Editawy</a>
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.
</p>
<p>
<a href="http://sra.itc.it/people/cavada/PyScintilla2.html">pyscintilla2</a>
is a Python binding for GTK 2.x scintilla that uses
gtkscintilla2.
</p>
<p>
<a href="http://scintilla.cvs.sourceforge.net/viewvc/scintilla/scintillactrl/">ScintillaCtrl</a>
is an unmaintained ActiveX control wrapper for Scintilla.
@ -112,7 +115,7 @@
Projects using Scintilla
</h3>
<p>
<a href="http://manoscoder.gr/phpBB3/viewtopic.php?f=25&t=103">Coder's Studio</a>
<a href="http://manoscoder.gr/CoderStudio/CoderStudio.asp">CoderStudio</a>
is an IDE for Assembly programming similar to Visual Studio 6.0.
</p>
<p>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20110321" />
<meta name="Date.Modified" content="20110620" />
<style type="text/css">
#versionlist {
margin: 0;
@ -55,8 +55,8 @@
GTK+</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 2.25<br />
Site last modified March 21 2011</font>
<font color="#FFCC99" size="3"> Release version 2.27<br />
Site last modified June 20 2011</font>
</td>
<td width="20%">
&nbsp;
@ -71,6 +71,8 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 2.27 fixes incorrect colours on some versions of GTK+.</li>
<li>Version 2.26 can highlight folding margin symbols for the current folding block. Experimental support for GTK+ 3.</li>
<li>Version 2.25 improves ability of lexers to remember complex state between lines.</li>
<li>Version 2.24 fixes a memory leak on GTK+ with Cairo.</li>
<li>Version 2.23 uses Cairo for drawing on GTK+ 2.22+ rather than GDK.</li>
@ -109,11 +111,6 @@ if (!IsRemote()) { //if NOT remote...
allowing the use of proportional fonts, bold and italics, multiple foreground and background
colours and multiple fonts.
</p>
<p>
The <a href="http://www.scintilla.org/SinkWorld.html">SinkWorld project</a>
investigates possible future directions for Scintilla to make it more flexible, robust, perform
better and run on the .NET and Java virtual machines.
</p>
<p>
<a href="http://www.scintilla.org/SciTE.html">SciTE</a> is a SCIntilla based Text Editor. Originally built to
demonstrate Scintilla, it has grown to be a generally useful editor with facilities for
@ -154,7 +151,6 @@ if (!IsRemote()) { //if NOT remote...
<a href="http://www.scintilla.org/Icons.html">Icons that can be used with Scintilla.</a>
</p>
<p>
The scintilla-interest mailing list has moved from lyra.org to Google Groups.
Questions and comments about Scintilla should be directed to the
<a href="http://groups.google.com/group/scintilla-interest">scintilla-interest</a>
mailing list,

View File

@ -44,6 +44,14 @@
#define USE_CAIRO 1
#endif
static GdkWindow *WindowFromWidget(GtkWidget *w) {
#if GTK_CHECK_VERSION(3,0,0)
return gtk_widget_get_window(w);
#else
return w->window;
#endif
}
#ifdef USE_CAIRO
#define DISABLE_GDK_FONT 1
#endif
@ -116,10 +124,17 @@ class FontHandle {
encodingType et;
public:
int ascent;
#ifndef DISABLE_GDK_FONT
GdkFont *pfont;
#endif
PangoFontDescription *pfd;
int characterSet;
FontHandle(GdkFont *pfont_) {
#ifdef DISABLE_GDK_FONT
FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
ResetWidths(et);
}
#else
FontHandle(GdkFont *pfont_=0) {
et = singleByte;
ascent = 0;
pfont = pfont_;
@ -127,10 +142,13 @@ public:
characterSet = -1;
ResetWidths(et);
}
#endif
FontHandle(PangoFontDescription *pfd_, int characterSet_) {
et = singleByte;
ascent = 0;
#ifndef DISABLE_GDK_FONT
pfont = 0;
#endif
pfd = pfd_;
characterSet = characterSet_;
ResetWidths(et);
@ -139,8 +157,8 @@ public:
#ifndef DISABLE_GDK_FONT
if (pfont)
gdk_font_unref(pfont);
#endif
pfont = 0;
#endif
if (pfd)
pango_font_description_free(pfd);
pfd = 0;
@ -183,9 +201,11 @@ static GtkWidget *PWidget(WindowID wid) {
return reinterpret_cast<GtkWidget *>(wid);
}
#if !GTK_CHECK_VERSION(3,0,0)
static GtkWidget *PWidget(Window &w) {
return PWidget(w.GetID());
}
#endif
Point Point::FromLong(long lpoint) {
return Point(
@ -254,6 +274,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
}
void Palette::Allocate(Window &w) {
#if !GTK_CHECK_VERSION(3,0,0)
// Disable palette on GTK+ 3.
if (allocatedPalette) {
gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
reinterpret_cast<GdkColor *>(allocatedPalette),
@ -274,14 +296,17 @@ void Palette::Allocate(Window &w) {
paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255);
paletteNew[iPal].pixel = entries[iPal].desired.AsLong();
}
#ifndef USE_CAIRO
gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)),
paletteNew, allocatedLen, FALSE, TRUE,
successPalette);
#endif
for (iPal = 0; iPal < used; iPal++) {
entries[iPal].allocated.Set(paletteNew[iPal].pixel);
}
}
delete []successPalette;
#endif
}
#ifndef DISABLE_GDK_FONT
@ -671,7 +696,7 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
}
return new FontHandle(newid);
#else
return new FontHandle(0);
return new FontHandle();
#endif
}
@ -695,6 +720,8 @@ void Font::Release() {
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
class SurfaceImpl : public Surface {
encodingType et;
#ifdef USE_CAIRO
@ -883,7 +910,11 @@ void SurfaceImpl::Init(WindowID wid) {
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
#if GTK_CHECK_VERSION(3,0,0)
GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
#else
GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
#endif
if (drawable_) {
context = gdk_cairo_create(drawable_);
PLATFORM_ASSERT(context);
@ -894,39 +925,30 @@ void SurfaceImpl::Init(WindowID wid) {
context = cairo_create(psurf);
}
createdGC = true;
pcontext = pango_cairo_create_context(context);
PLATFORM_ASSERT(pcontext);
layout = pango_cairo_create_layout(context);
PLATFORM_ASSERT(layout);
#else
#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
PLATFORM_ASSERT(pcontext);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
#endif
inited = true;
}
void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(sid);
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
context = gdk_cairo_create(drawable_);
#if GTK_CHECK_VERSION(3,0,0)
context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
#else
gc = gdk_gc_new(drawable_);
context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
#endif
#ifdef USE_CAIRO
pcontext = pango_cairo_create_context(context);
PLATFORM_ASSERT(pcontext);
layout = pango_cairo_create_layout(context);
PLATFORM_ASSERT(layout);
#else
drawable = reinterpret_cast<GdkDrawable *>(sid);
gc = gdk_gc_new(drawable);
#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
layout = pango_layout_new(pcontext);
drawable = drawable_;
#endif
#ifdef USE_CAIRO
cairo_set_line_width(context, 1);
#else
@ -948,20 +970,16 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
PLATFORM_ASSERT(surfImpl->drawable);
gc = gdk_gc_new(surfImpl->drawable);
#endif
#ifdef USE_CAIRO
pcontext = pango_cairo_create_context(context);
pcontext = gtk_widget_create_pango_context(PWidget(wid));
PLATFORM_ASSERT(pcontext);
layout = pango_cairo_create_layout(context);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
#ifdef USE_CAIRO
if (height > 0 && width > 0)
psurf = gdk_window_create_similar_surface(
gtk_widget_get_window(PWidget(wid)),
CAIRO_CONTENT_COLOR_ALPHA, width, height);
#else
pcontext = gtk_widget_create_pango_context(PWidget(wid));
PLATFORM_ASSERT(pcontext);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
if (height > 0 && width > 0)
ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
drawable = ppixmap;
@ -990,9 +1008,9 @@ void SurfaceImpl::PenColour(ColourAllocated fore) {
if (context) {
ColourDesired cdFore(fore.AsLong());
cairo_set_source_rgb(context,
cdFore.GetBlue() / 255.0,
cdFore.GetRed() / 255.0,
cdFore.GetGreen() / 255.0,
cdFore.GetRed() / 255.0);
cdFore.GetBlue() / 255.0);
}
#else
if (gc) {
@ -1232,8 +1250,6 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
return converter.val;
}
#endif
static unsigned int GetRValue(unsigned int co) {
return (co >> 16) & 0xff;
}
@ -1246,22 +1262,26 @@ static unsigned int GetBValue(unsigned int co) {
return co & 0xff;
}
#endif
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags) {
#ifdef USE_CAIRO
if (context && rc.Width() > 0) {
ColourDesired cdFill(fill.AsLong());
cairo_set_source_rgba(context,
GetRValue(fill.AsLong()) / 255.0,
GetGValue(fill.AsLong()) / 255.0,
GetBValue(fill.AsLong()) / 255.0,
cdFill.GetRed() / 255.0,
cdFill.GetGreen() / 255.0,
cdFill.GetBlue() / 255.0,
alphaFill / 255.0);
PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
cairo_fill(context);
ColourDesired cdOutline(outline.AsLong());
cairo_set_source_rgba(context,
GetRValue(outline.AsLong()) / 255.0,
GetGValue(outline.AsLong()) / 255.0,
GetBValue(outline.AsLong()) / 255.0,
cdOutline.GetRed() / 255.0,
cdOutline.GetGreen() / 255.0,
cdOutline.GetBlue() / 255.0,
alphaOutline / 255.0);
PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
cairo_stroke(context);
@ -2021,11 +2041,17 @@ PRectangle Window::GetPosition() {
// Before any size allocated pretend its 1000 wide so not scrolled
PRectangle rc(0, 0, 1000, 1000);
if (wid) {
rc.left = PWidget(wid)->allocation.x;
rc.top = PWidget(wid)->allocation.y;
if (PWidget(wid)->allocation.width > 20) {
rc.right = rc.left + PWidget(wid)->allocation.width;
rc.bottom = rc.top + PWidget(wid)->allocation.height;
GtkAllocation allocation;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_allocation(PWidget(wid), &allocation);
#else
allocation = PWidget(wid)->allocation;
#endif
rc.left = allocation.x;
rc.top = allocation.y;
if (allocation.width > 20) {
rc.right = rc.left + allocation.width;
rc.bottom = rc.top + allocation.height;
}
}
return rc;
@ -2043,7 +2069,7 @@ void Window::SetPosition(PRectangle rc) {
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
int ox = 0;
int oy = 0;
gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy);
gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
ox += rc.left;
if (ox < 0)
ox = 0;
@ -2129,8 +2155,8 @@ void Window::SetCursor(Cursor curs) {
break;
}
if (PWidget(wid)->window)
gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
if (WindowFromWidget(PWidget(wid)))
gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
gdk_cursor_unref(gdkCurs);
}
@ -2143,7 +2169,7 @@ void Window::SetTitle(const char *s) {
PRectangle Window::GetMonitorRect(Point pt) {
gint x_offset, y_offset;
gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
#if GTK_CHECK_VERSION(2,2,0)
// GTK+ 2.2+
@ -2174,7 +2200,7 @@ struct ListImage {
static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value;
if (list_image->pixbuf)
g_object_unref (list_image->pixbuf);
g_object_unref(list_image->pixbuf);
g_free(list_image);
}
@ -2258,24 +2284,47 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
/* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
GtkStyle* style;
g_return_if_fail(w != NULL);
/* Copy the selected color to active. Note that the modify calls will cause
recursive calls to this function after the value is updated and w->style to
be set to a new object */
style = gtk_widget_get_style(w);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourForeSelected;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
GdkRGBA colourForeActive;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourBaseSelected;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
GdkRGBA colourBaseActive;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
#else
GtkStyle *style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
#endif
}
void ListBoxX::Create(Window &, int, Point, int, bool) {
@ -2340,7 +2389,11 @@ void ListBoxX::SetFont(Font &scint_font) {
// Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(scint_font)->pfd) {
// Current font is Pango font
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
#else
gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
#endif
}
}
@ -2376,14 +2429,27 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
gtk_tree_view_column_cell_get_size(column, NULL,
NULL, NULL, &row_width, &row_height);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
GtkBorder padding;
gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
height = (rows * row_height
+ padding.top + padding.bottom
+ 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
#else
int ythickness = PWidget(list)->style->ythickness;
height = (rows * row_height
+ 2 * (ythickness
+ GTK_CONTAINER(PWidget(list))->border_width + 1));
#endif
gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
#else
gtk_widget_size_request(GTK_WIDGET(scroller), &req);
#endif
rc.right = req.width;
rc.bottom = req.height;
@ -2497,11 +2563,17 @@ void ListBoxX::Select(int n) {
// Move the scrollbar to show the selection.
int total = Length();
#if GTK_CHECK_VERSION(3,0,0)
GtkAdjustment *adj =
gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+ gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
#else
GtkAdjustment *adj =
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
+ adj->lower - adj->page_size / 2;
#endif
// Get cell height
int row_width;
int row_height;
@ -2520,8 +2592,13 @@ void ListBoxX::Select(int n) {
}
// Clamp it.
value = (value < 0)? 0 : value;
#if GTK_CHECK_VERSION(3,0,0)
value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
#else
value = (value > (adj->upper - adj->page_size))?
(adj->upper - adj->page_size) : value;
#endif
// Set it.
gtk_adjustment_set_value(adj, value);
@ -2679,7 +2756,11 @@ void Menu::Show(Point pt, Window &) {
GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
gtk_widget_show_all(GTK_WIDGET(widget));
GtkRequisition requisition;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
#else
gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
#endif
if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width;
}

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,12 @@ endif
AR = ar
RANLIB = touch
ifdef GTK3
GTKVERSION=gtk+-3.0
else
GTKVERSION=gtk+-2.0
endif
# Environment variable windir always defined on Win32
ifndef windir
@ -37,7 +43,9 @@ vpath %.h ../src ../include ../lexlib
vpath %.cxx ../src ../lexlib ../lexers
INCLUDEDIRS=-I ../include -I ../src -I ../lexlib
#~ DEPRECATED=-DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DDISABLE_GDK_FONT
ifdef CHECK_DEPRECATED
DEPRECATED=-DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DDISABLE_GDK_FONT
endif
CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -Wno-long-long -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) $(DEPRECATED)
ifdef NOTHREADS
@ -52,13 +60,15 @@ else
CXXFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) $(THREADFLAGS)
endif
CONFIGFLAGS:=$(shell pkg-config --cflags gtk+-2.0)
CFLAGS:=$(CXXFLAGS)
CONFIGFLAGS:=$(shell pkg-config --cflags $(GTKVERSION))
MARSHALLER=scintilla-marshal.o
.cxx.o:
$(CC) $(CONFIGFLAGS) $(CXXFLAGS) -c $<
.c.o:
$(CCOMP) $(CONFIGFLAGS) $(CXXFLAGS) -w -c $<
$(CCOMP) $(CONFIGFLAGS) $(CFLAGS) -w -c $<
LEXOBJS:=$(addsuffix .o,$(basename $(notdir $(wildcard ../lexers/Lex*.cxx))))

View File

@ -301,8 +301,11 @@ public:
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface;
friend class SurfaceImpl;
friend class SurfaceImpl;
};
/**
@ -411,8 +414,8 @@ public:
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; };
void SetControl(void *_control) { control = _control; };
void SetWindow(void *ref) { windowRef = ref; }
void SetControl(void *_control) { control = _control; }
#endif
private:
Cursor cursorLast;

View File

@ -136,6 +136,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
#define SCI_MARKERSETBACKSELECTED 2292
#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
@ -245,6 +247,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
#define INDIC_STRAIGHTBOX 8
#define INDIC_DASH 9
#define INDIC_DOTS 10
#define INDIC_SQUIGGLELOW 11
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
@ -330,6 +336,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145
#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0
@ -556,7 +563,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
@ -709,6 +718,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
#define SCI_INDICSETOUTLINEALPHA 2558
#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
@ -723,6 +734,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538
#define SC_MARGINOPTION_NONE 0
#define SC_MARGINOPTION_SUBLINESELECT 1
#define SCI_SETMARGINOPTIONS 2539
#define SCI_GETMARGINOPTIONS 2557
#define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542
@ -794,6 +809,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CHANGELEXERSTATE 2617
#define SCI_CONTRACTEDFOLDNEXT 2618
#define SCI_VERTICALCENTRECARET 2619
#define SCI_MOVESELECTEDLINESUP 2620
#define SCI_MOVESELECTEDLINESDOWN 2621
#define SCI_SETIDENTIFIER 2622
#define SCI_GETIDENTIFIER 2623
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@ -871,6 +890,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
#define SCMOD_META 16
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002
@ -964,11 +984,22 @@ struct Sci_NotifyHeader {
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
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 */
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 */
const char *text;
/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
@ -982,7 +1013,7 @@ struct SCNotification {
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 annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
int updated; /* SCN_UPDATEUI */
};
@ -996,7 +1027,6 @@ struct SearchResultMarkings {
SearchResultMarking *_markings;
};
#ifdef SCI_NAMESPACE
}
#endif

View File

@ -292,6 +292,12 @@ fun void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number.
fun void MarkerSetBack=2042(int markerNumber, colour back)
# Set the background colour used for a particular marker number when its folding block is selected.
fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
# Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber)
@ -544,6 +550,10 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5
val INDIC_BOX=6
val INDIC_ROUNDBOX=7
val INDIC_STRAIGHTBOX=8
val INDIC_DASH=9
val INDIC_DOTS=10
val INDIC_SQUIGGLELOW=11
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
@ -791,6 +801,9 @@ set void SetSelectionEnd=2144(position pos,)
# Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,)
# Set caret to a position, while removing any existing selection.
fun void SetEmptySelection=2556(position pos,)
# Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,)
@ -1440,9 +1453,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2)
# Use specified indicator to highlight matching braces instead of changing their style.
fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
# Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,)
# Use specified indicator to highlight non matching brace instead of changing its style.
fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
# Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,)
@ -1884,6 +1903,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,)
# Set the alpha outline colour of the given indicator.
set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
# Get the alpha outline colour of the given indicator.
get int IndicGetOutlineAlpha=2559(int indicator,)
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
@ -1926,6 +1951,16 @@ set void MarginSetStyleOffset=2537(int style,)
# Get the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,)
enu MarginOption=SC_MARGINOPTION_
val SC_MARGINOPTION_NONE=0
val SC_MARGINOPTION_SUBLINESELECT=1
# Set the margin options.
set void SetMarginOptions=2539(int marginOptions,)
# Get the margin options.
get int GetMarginOptions=2557(,)
# Set the annotation text for a line
set void AnnotationSetText=2540(int line, string text)
@ -2106,6 +2141,18 @@ fun int ContractedFoldNext=2618(int lineStart,)
# Centre current line in window.
fun void VerticalCentreCaret=2619(,)
# Move the selected lines up one line, shifting the line above after the selection
fun void MoveSelectedLinesUp=2620(,)
# Move the selected lines down one line, shifting the line below before the selection
fun void MoveSelectedLinesDown=2621(,)
# Set the identifier reported as idFrom in notification messages.
set void SetIdentifier=2622(int identifier,)
# Get the identifier.
get int GetIdentifier=2623(,)
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@ -2247,6 +2294,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
val SCMOD_META=16
################################################
# For SciLexer.h
@ -3889,22 +3937,22 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers)
evt void DoubleClick=2006(void)
evt void UpdateUI=2007(void)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
evt void DoubleClick=2006(int modifiers, int position, int line)
evt void UpdateUI=2007(int updated)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void)
evt void UserListSelection=2014(int listType, string text)
evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text)
evt void DwellStart=2016(int position)
evt void DwellEnd=2017(int position)
evt void DwellStart=2016(int position, int x, int y)
evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
evt void AutoCSelection=2022(string text)
evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void)

View File

@ -208,6 +208,7 @@ struct OptionsCPP {
bool identifiersAllowDollars;
bool trackPreprocessor;
bool updatePreprocessor;
bool triplequotedStrings;
bool fold;
bool foldSyntaxBased;
bool foldComment;
@ -224,6 +225,7 @@ struct OptionsCPP {
identifiersAllowDollars = true;
trackPreprocessor = true;
updatePreprocessor = true;
triplequotedStrings = false;
fold = false;
foldSyntaxBased = true;
foldComment = false;
@ -263,6 +265,9 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
"Set to 1 to update preprocessor definitions when #define found.");
DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings,
"Set to 1 to enable highlighting of triple-quoted strings.");
DefineProperty("fold", &OptionsCPP::fold);
DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
@ -319,6 +324,7 @@ class LexerCPP : public ILexer {
OptionsCPP options;
OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
public:
LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_),
@ -363,7 +369,9 @@ public:
static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false);
}
static int MaskActive(int style) {
return style & ~activeFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens);
bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
};
@ -427,7 +435,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
struct After {
int line;
After(int line_) : line(line_) {}
bool operator() (PPDefinition &p) const {
bool operator()(PPDefinition &p) const {
return p.line > line;
}
};
@ -503,11 +511,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
preprocessorDefinitions[itDef->key] = itDef->value;
}
const int maskActivity = 0x3F;
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? 0x40 : 0;
int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) {
@ -523,7 +530,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
lastWordWasUUID = false;
isIncludePreprocessor = false;
if (preproc.IsInactive()) {
activitySet = 0x40;
activitySet = activeFlag;
sc.SetState(sc.state | activitySet);
}
if (activitySet) {
@ -558,7 +565,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate.
switch (sc.state & maskActivity) {
switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT|activitySet);
break;
@ -734,7 +741,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_TRIPLEVERBATIM:
if (sc.Match ("\"\"\"")) {
if (sc.Match("\"\"\"")) {
while (sc.Match('"')) {
sc.Forward();
}
@ -754,11 +761,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
// Determine if a new state should be entered.
if ((sc.state & maskActivity) == SCE_C_DEFAULT) {
if (MaskActive(sc.state) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward();
} else if (sc.Match("\"\"\"")) {
} else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
sc.Forward(2);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
@ -798,7 +805,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (sc.chPrev == 'R') {
sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;;termPos++) {
for (int termPos = sc.currentPos + 1;; termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(')
break;
@ -839,12 +846,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else if (sc.Match("else")) {
if (!preproc.CurrentIfTaken()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
@ -856,19 +863,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (sc.Match("endif")) {
preproc.EndSection();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) {
@ -928,15 +935,15 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int styleNext = MaskActive(styler.StyleAt(startPos));
int style = MaskActive(initStyle);
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {

View File

@ -318,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
char chAttr = SCE_HJ_WORD;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
if (wordIsNumber)
bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER;
else {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
if (keywords.InList(s))
chAttr = SCE_HJ_KEYWORD;
} else if (keywords.InList(s)) {
chAttr = SCE_HJ_KEYWORD;
}
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
}
@ -417,7 +417,7 @@ static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler)
static int StateForScript(script_type scriptLanguage) {
int Result;
switch (scriptLanguage) {
case eScriptJS:
case eScriptJS:
Result = SCE_HJ_START;
break;
case eScriptPython:
@ -754,8 +754,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (styler.Match(j, "end")) {
levelCurrent--;
}
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) {
levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1;
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
}
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
levelCurrent--;
@ -882,7 +882,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') &&
(chNext == '?') &&
!IsScriptCommentState(state) ) {
!IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
@ -954,6 +955,36 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
// handle the start/end of Django comment
else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
beforeLanguage = scriptLanguage;
if (inScriptType == eNonHtmlScript)
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
i += 1;
visibleChars += 1;
scriptLanguage = eScriptComment;
state = SCE_H_COMMENT;
styler.ColourTo(i, SCE_H_ASP);
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
styler.ColourTo(i - 1, StateToPrint);
i += 1;
visibleChars += 1;
styler.ColourTo(i, SCE_H_ASP);
state = beforePreProc;
if (inScriptType == eNonHtmlScriptPreProc)
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
scriptLanguage = beforeLanguage;
continue;
}
// handle the start Django template code
else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
if (chNext == '%')
@ -1024,7 +1055,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) {
(!IsScriptCommentState(StateToPrint))) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
@ -1154,7 +1185,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
scriptLanguage = eScriptNone;
scriptLanguage = beforeLanguage;
continue;
}
/////////////////////////////////////

View File

@ -36,7 +36,6 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
char *buffer = new char[length];
int bufferCount = 0;
bool isBOL, isEOL, isWS, isBOLWS = 0;
bool isCode = false;
bool isCStyleComment = false;
WordList &sectionKeywords = *keywordLists[0];
@ -46,6 +45,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
WordList &pascalKeywords = *keywordLists[4];
WordList &userKeywords = *keywordLists[5];
int curLine = styler.GetLine(startPos);
int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
bool isCode = (curLineState == 1);
// Go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
@ -66,6 +69,12 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
isEOL = (ch == '\n' || ch == '\r');
isWS = (ch == ' ' || ch == '\t');
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
// Remember the line state for future incremental lexing
curLine = styler.GetLine(i);
styler.SetLineState(curLine, (isCode ? 1 : 0));
}
switch(state) {
case SCE_INNO_DEFAULT:
if (!isCode && ch == ';' && isBOLWS) {

View File

@ -61,8 +61,9 @@ static void ColouriseLuaDoc(
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
// but probably enough in most cases. [pP] is for hex floats.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
CharacterSet setExponent(CharacterSet::setNone, "eEpP");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
@ -70,12 +71,16 @@ static void ColouriseLuaDoc(
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1.
// Continuation of a string (\* whitespace escaping) is controlled by stringWs.
int nestLevel = 0;
int sepCount = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
int stringWs = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
int lineState = styler.GetLineState(currentLine - 1);
nestLevel = lineState >> 8;
nestLevel = lineState >> 9;
sepCount = lineState & 0xFF;
stringWs = lineState & 0x100;
}
// Do not leak onto next line
@ -95,8 +100,10 @@ static void ColouriseLuaDoc(
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT:
// Inside a literal string or block comment, we set the line state
styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
case SCE_LUA_STRING:
case SCE_LUA_CHARACTER:
// Inside a literal string, block comment or string, we set the line state
styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
break;
default:
// Reset the line state
@ -125,11 +132,11 @@ static void ColouriseLuaDoc(
if (sc.state == SCE_LUA_OPERATOR) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') {
if (sc.chPrev != 'E' && sc.chPrev != 'e')
if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
@ -160,24 +167,38 @@ static void ColouriseLuaDoc(
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == '*') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_CHARACTER) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == '*') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
@ -214,8 +235,10 @@ static void ColouriseLuaDoc(
sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
stringWs = 0;
} else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
stringWs = 0;
} else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc);
if (sepCount == 0) {

View File

@ -106,12 +106,12 @@ static void ColouriseMatlabOctaveDoc(
transpose = true;
}
} else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
if (sc.ch == '\'') {
if (sc.chNext == '\'') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') {

View File

@ -58,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators
static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
(ch == '\"') || (ch == '\'') || (ch == '/');
}
static void ColouriseBatchLine(
@ -854,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return;
}
int varCount = 0;
while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
if (--varCount == 0) {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
}
// skip identifier and target styling if this is a command line

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ using namespace Scintilla;
#endif
/* kwCDef, kwCTypeName only used for Cython */
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1;
@ -246,7 +246,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) {
} else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') {
@ -277,11 +277,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport;
else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef;
else if (0 == strcmp(s, "cpdef"))
kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport"))
kwLast = kwImport;
else if (kwLast != kwCDef)
else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther;
} else if (kwLast != kwCDef) {
} else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther;
}
}
@ -337,8 +339,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true;
}
// One cdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) {
// One cdef or cpdef line, clear kwLast only at end of line
if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther;
}

View File

@ -204,8 +204,8 @@ struct OptionSetSQL : public OptionSet<OptionsSQL> {
OptionSetSQL() {
DefineProperty("fold", &OptionsSQL::fold);
DefineProperty("lexer.sql.fold.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\"line of an IF statement.");
DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
DefineProperty("fold.comment", &OptionsSQL::foldComment);
@ -283,6 +283,20 @@ private:
style == SCE_SQL_COMMENTDOCKEYWORDERROR;
}
bool IsCommentStyle (int style) {
switch (style) {
case SCE_SQL_COMMENT :
case SCE_SQL_COMMENTDOC :
case SCE_SQL_COMMENTLINE :
case SCE_SQL_COMMENTLINEDOC :
case SCE_SQL_COMMENTDOCKEYWORD :
case SCE_SQL_COMMENTDOCKEYWORDERROR :
return true;
default :
return false;
}
}
OptionsSQL options;
OptionSetSQL osSQL;
SQLStates sqlStates;
@ -521,7 +535,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (atEOL || (ch == ';')) {
if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
if (endFound) {
//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
@ -554,7 +568,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (ch == '(') {
if (levelCurrent > levelNext)
levelCurrent--;
levelNext++;
levelNext++;
} else if (ch == ')') {
levelNext--;
} else if ((!options.foldOnlyBegin) && ch == ';') {

View File

@ -29,7 +29,7 @@ using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
}
static inline bool IsAWordStart(const int ch) {
@ -269,24 +269,36 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
if (styler.Match(j, "case") ||
styler.Match(j, "casex") ||
styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") ||
styler.Match(j, "fork") ||
styler.Match(j, "generate") ||
styler.Match(j, "covergroup") ||
styler.Match(j, "package") ||
styler.Match(j, "primitive") ||
styler.Match(j, "program") ||
styler.Match(j, "sequence") ||
styler.Match(j, "specify") ||
styler.Match(j, "table") ||
styler.Match(j, "task") ||
styler.Match(j, "generate") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
styler.Match(j, "fork") ||
(styler.Match(j, "module") && foldAtModule) ||
styler.Match(j, "begin")) {
levelNext++;
} else if (styler.Match(j, "endcase") ||
styler.Match(j, "endclass") ||
styler.Match(j, "endfunction") ||
styler.Match(j, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endgroup") ||
styler.Match(j, "endpackage") ||
styler.Match(j, "endprimitive") ||
styler.Match(j, "endprogram") ||
styler.Match(j, "endsequence") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endtask") ||
styler.Match(j, "join") ||
styler.Match(j, "join_any") ||
styler.Match(j, "join_none") ||
(styler.Match(j, "endmodule") && foldAtModule) ||
(styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
levelNext--;

View File

@ -119,7 +119,6 @@ inline bool iswordstart(int ch) {
inline bool isoperator(int ch) {
if (IsASCII(ch) && IsAlphaNumeric(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||

View File

@ -43,12 +43,12 @@ public:
}
void Set(int position, T value) {
Delete(position);
if ((states.size() == 0) || (value != states[states.size()-1].value)) {
if (states.empty() || (value != states[states.size()-1].value)) {
states.push_back(State(position, value));
}
}
T ValueAt(int position) {
if (!states.size())
if (states.empty())
return T();
if (position < states[0].position)
return T();

View File

@ -315,7 +315,6 @@ void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore,
// Draw the polygon
CGContextAddLines( gc, points, npts );
// TODO: Should the path be automatically closed, or is that the caller's responsability?
// Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only)
CGContextClosePath( gc );
CGContextDrawPath( gc, kCGPathFillStroke );
@ -334,7 +333,6 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAlloc
// Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo)
// We subtract 1 from the Width() and Height() so that all our drawing is within the area defined
// by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom.
// TODO: Create some version of PRectangleToCGRect to do this conversion for us?
CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) );
CGContextDrawPath( gc, kCGPathFillStroke );
}
@ -407,8 +405,12 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
}
void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
// TODO: Look at the Win32 API to determine what this is supposed to do:
// This is only called from the margin marker drawing code for SC_MARK_ROUNDRECT
// The Win32 version does
// ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 );
// which is a rectangle with rounded corners each having a radius of 4 pixels.
// It would be almost as good just cutting off the corners with lines at
// 45 degrees as is done on GTK+.
// Create a rectangle with semicircles at the corners
const int MAX_RADIUS = 4;
@ -442,7 +444,6 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
};
// Align the points in the middle of the pixels
// TODO: Should I include these +0.5 in the array creation code above?
for( int i = 0; i < 4*3; ++ i )
{
CGPoint* c = (CGPoint*) corners;
@ -629,15 +630,15 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
// 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<const UInt8*>(buf), len+1, *reinterpret_cast<QuartzTextStyle*>(font_.GetID()));
ATSUGlyphInfoArray* theGlyphInfoArrayPtr;
ByteCount theArraySize;
@ -663,12 +664,12 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
// 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 )
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 )
while ( uch >= mask && count < 8 )
{
positions[i++] = position;
count ++;
@ -1126,7 +1127,6 @@ public:
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);
void ClearRegisteredImages();
void SetDoubleClickAction(CallBackAction action, void *data) {
@ -1482,7 +1482,7 @@ PRectangle ListBoxImpl::GetDesiredRect() {
rcDesired.bottom = itemHeight * rows;
rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth;
if (Length() > rows)
if (Length() > rows)
rcDesired.right += kScrollBarWidth;
rcDesired.right += IconWidth();
@ -1631,11 +1631,6 @@ void ListBoxImpl::GetValue(int n, char *value, int len) {
delete []text;
}
void ListBoxImpl::Sort() {
// TODO: Implement this
fprintf(stderr, "ListBox::Sort\n");
}
void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
xset.Add(type, xpm_data);
}
@ -1679,7 +1674,9 @@ void Menu::Show(Point pt, Window &) {
);
}
// TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday
// ElapsedTime is used for precise performance measurements during development
// and not for anything a user sees.
ElapsedTime::ElapsedTime() {
struct timeval curTime;
int retVal;
@ -1837,7 +1834,7 @@ void Platform::Assert(const char *c, const char *file, int line) {
sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
strcat(buffer, "\r\n");
Platform::DebugDisplay(buffer);
#ifdef DEBUG
#ifdef DEBUG
// Jump into debugger in assert on Mac (CL269835)
::Debugger();
#endif

View File

@ -29,7 +29,7 @@ ifeq ($(GCC_MAJOR),3)
ARCHFLAGS=-arch ppc -faltivec -mcpu=7400 -mtune=7400 -mpowerpc -mpowerpc-gfxopt
else
ifndef NATIVE
ARCH_BASE_FLAGS=/Developer/SDKs/MacOSX10.5.sdk -arch ppc -arch i386
ARCH_BASE_FLAGS=/Developer/SDKs/MacOSX10.6.sdk -arch i386
ARCHFLAGS=-isysroot $(ARCH_BASE_FLAGS)
LINK_FLAGS=-Wl,-syslibroot,$(ARCH_BASE_FLAGS)
DYN_FLAGS=$(LINK_FLAGS) -framework Carbon -bundle

View File

@ -100,7 +100,7 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int ends[numEnds + 2];
for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;

View File

@ -168,6 +168,14 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible
}
}
bool ContractionState::HiddenLines() const {
if (OneToOne()) {
return false;
} else {
return !visible->AllSameAs(1);
}
}
bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) {
return true;

View File

@ -48,6 +48,7 @@ public:
bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
bool HiddenLines() const;
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);

View File

@ -28,7 +28,7 @@ Decoration::~Decoration() {
}
bool Decoration::Empty() {
return rs.starts->Partitions() == 1;
return rs.Runs() == 1;
}
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),

View File

@ -2,7 +2,7 @@
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
@ -355,6 +355,110 @@ int Document::GetFoldParent(int line) {
}
}
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int topLine, int bottomLine) {
int noNeedToParseBefore = Platform::Minimum(line, topLine) - 1;
int noNeedToParseAfter = Platform::Maximum(line, bottomLine) + 1;
int endLine = LineFromPosition(Length());
int beginFoldBlock = noNeedToParseBefore;
int endFoldBlock = -1;
int beginMarginCorrectlyDrawnZone = noNeedToParseBefore;
int endMarginCorrectlyDrawnZone = noNeedToParseAfter;
int endOfTailOfWhiteFlag = -1; //endOfTailOfWhiteFlag points the last SC_FOLDLEVELWHITEFLAG if follow a fold block. Otherwise endOfTailOfWhiteFlag points end of fold block.
int level = GetLevel(line);
int levelNumber = -1;
int lineLookLevel = 0;
int lineLookLevelNumber = -1;
int lineLook = line;
bool beginFoldBlockFound = false;
bool endFoldBlockFound = false;
bool beginMarginCorrectlyDrawnZoneFound = false;
bool endMarginCorrectlyDrawnZoneFound = false;
/*******************************************************************************/
/* search backward (beginFoldBlock & beginMarginCorrectlyDrawnZone) */
/*******************************************************************************/
for (endOfTailOfWhiteFlag = line; (lineLook > noNeedToParseBefore || (lineLookLevel & SC_FOLDLEVELWHITEFLAG)) && (!beginFoldBlockFound || !beginMarginCorrectlyDrawnZoneFound); --lineLook) {
lineLookLevel = GetLevel(lineLook);
if (levelNumber != -1) {
lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
if (!beginMarginCorrectlyDrawnZoneFound && (lineLookLevelNumber > levelNumber)) {
beginMarginCorrectlyDrawnZoneFound = true;
beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
}
//find the last space line (SC_FOLDLEVELWHITEFLAG).
if (!beginMarginCorrectlyDrawnZoneFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
endOfTailOfWhiteFlag = lineLook - 1;
}
if (!beginFoldBlockFound && (lineLookLevelNumber < levelNumber)) {
beginFoldBlockFound = true;
beginFoldBlock = lineLook;
if (!beginMarginCorrectlyDrawnZoneFound) {
beginMarginCorrectlyDrawnZoneFound = true;
beginMarginCorrectlyDrawnZone = lineLook - 1;
}
} else if (!beginFoldBlockFound && lineLookLevelNumber == SC_FOLDLEVELBASE) {
beginFoldBlockFound = true;
beginFoldBlock = -1;
}
} else if (!(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
endOfTailOfWhiteFlag = lineLook - 1;
levelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
if (lineLookLevel & SC_FOLDLEVELHEADERFLAG &&
//Managed the folding block when a fold header does not have any subordinate lines to fold away.
(levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
beginFoldBlockFound = true;
beginFoldBlock = lineLook;
beginMarginCorrectlyDrawnZoneFound = true;
beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
levelNumber = GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK;;
}
}
}
/****************************************************************************/
/* search forward (endStartBlock & endMarginCorrectlyDrawnZone) */
/****************************************************************************/
if (level & SC_FOLDLEVELHEADERFLAG) {
//ignore this line because this line is on first one of block.
lineLook = line + 1;
} else {
lineLook = line;
}
for (; lineLook < noNeedToParseAfter && (!endFoldBlockFound || !endMarginCorrectlyDrawnZoneFound); ++lineLook) {
lineLookLevel = GetLevel(lineLook);
lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
if (!endFoldBlockFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG) && lineLookLevelNumber < levelNumber) {
endFoldBlockFound = true;
endFoldBlock = lineLook - 1;
if (!endMarginCorrectlyDrawnZoneFound) {
endMarginCorrectlyDrawnZoneFound = true;
endMarginCorrectlyDrawnZone = lineLook;
}
} else if (!endFoldBlockFound && lineLookLevel == SC_FOLDLEVELBASE) {
endFoldBlockFound = true;
endFoldBlock = -1;
}
if (!endMarginCorrectlyDrawnZoneFound && (lineLookLevel & SC_FOLDLEVELHEADERFLAG) &&
//Managed the folding block when a fold header does not have any subordinate lines to fold away.
(levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
endMarginCorrectlyDrawnZoneFound = true;
endMarginCorrectlyDrawnZone = lineLook;
}
}
if (!endFoldBlockFound && ((lineLook > endLine && lineLookLevelNumber < levelNumber) ||
(levelNumber > SC_FOLDLEVELBASE))) {
//manage when endfold is incorrect or on last line.
endFoldBlock = lineLook - 1;
//useless to set endMarginCorrectlyDrawnZone.
//if endMarginCorrectlyDrawnZoneFound equals false then endMarginCorrectlyDrawnZone already equals to endLine + 1.
}
highlightDelimiter.beginFoldBlock = beginFoldBlock;
highlightDelimiter.endFoldBlock = endFoldBlock;
highlightDelimiter.beginMarginCorrectlyDrawnZone = beginMarginCorrectlyDrawnZone;
highlightDelimiter.endMarginCorrectlyDrawnZone = endMarginCorrectlyDrawnZone;
}
int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length());
}
@ -609,6 +713,55 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return false;
}
inline bool IsSpaceOrTab(int ch) {
return ch == ' ' || ch == '\t';
}
// Need to break text into segments near lengthSegment but taking into
// account the encoding to not break inside a UTF-8 or DBCS character
// and also trying to avoid breaking inside a pair of combining characters.
// The segment length must always be long enough (more than 4 bytes)
// so that there will be at least one whole character to make a segment.
// For UTF-8, text must consist only of valid whole characters.
// In preference order from best to worst:
// 1) Break after space
// 2) Break before punctuation
// 3) Break after whole character
int Document::SafeSegment(const char *text, int length, int lengthSegment) {
if (length <= lengthSegment)
return length;
int lastSpaceBreak = -1;
int lastPunctuationBreak = -1;
int lastEncodingAllowedBreak = -1;
for (int j=0; j < lengthSegment;) {
unsigned char ch = static_cast<unsigned char>(text[j]);
if (j > 0) {
if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
lastSpaceBreak = j;
}
if (ch < 'A') {
lastPunctuationBreak = j;
}
}
lastEncodingAllowedBreak = j;
if (dbcsCodePage == SC_CP_UTF8) {
j += (ch < 0x80) ? 1 : BytesFromLead(ch);
} else if (dbcsCodePage) {
j += IsDBCSLeadByte(ch) ? 2 : 1;
} else {
j++;
}
}
if (lastSpaceBreak >= 0) {
return lastSpaceBreak;
} else if (lastPunctuationBreak >= 0) {
return lastPunctuationBreak;
}
return lastEncodingAllowedBreak;
}
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
@ -1950,10 +2103,17 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
// the start position is at end of line or between line end characters.
lineRangeStart++;
startPos = doc->LineStart(lineRangeStart);
} else if ((increment == -1) &&
(startPos <= doc->LineStart(lineRangeStart)) &&
(lineRangeStart > lineRangeEnd)) {
// the start position is at beginning of line.
lineRangeStart--;
startPos = doc->LineEnd(lineRangeStart);
}
int pos = -1;
int lenRet = 0;
char searchEnd = s[*length - 1];
char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line);
@ -1965,7 +2125,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = startPos;
}
if (line == lineRangeEnd) {
if ((endPos != endOfLine) && (searchEnd == '$'))
if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if end position before end of line
endOfLine = endPos;
}
@ -1976,7 +2136,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = endPos;
}
if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$'))
if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if start position before end of line
endOfLine = startPos;
}
@ -1987,7 +2147,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) {
pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0];
if (increment == -1) {
// There can be only one start of a line, so no need to look for last match in line
if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {

View File

@ -2,7 +2,7 @@
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
@ -115,6 +115,47 @@ struct StyledText {
}
};
class HighlightDelimiter {
public:
HighlightDelimiter() {
beginFoldBlock = -1;
endFoldBlock = -1;
beginMarginCorrectlyDrawnZone = -1;
endMarginCorrectlyDrawnZone = -1;
isEnabled = false;
}
bool NeedsDrawing(int line) {
return isEnabled && (line <= beginMarginCorrectlyDrawnZone || endMarginCorrectlyDrawnZone <= line);
}
bool isCurrentBlockHighlight(int line) {
return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
}
bool isHeadBlockFold(int line) {
return beginFoldBlock == line && line < endFoldBlock;
}
bool isBodyBlockFold(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
}
bool isTailBlockFold(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
}
// beginFoldBlock : Begin of current fold block.
// endStartBlock : End of current fold block.
// beginMarginCorrectlyDrawnZone : Begin of zone where margin is correctly drawn.
// endMarginCorrectlyDrawnZone : End of zone where margin is correctly drawn.
int beginFoldBlock;
int endFoldBlock;
int beginMarginCorrectlyDrawnZone;
int endMarginCorrectlyDrawnZone;
bool isEnabled;
};
class CaseFolder {
public:
virtual ~CaseFolder() {
@ -234,6 +275,7 @@ public:
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const;
int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document
void ModifiedAt(int pos);
@ -299,6 +341,7 @@ public:
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetFoldParent(int line);
void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int topLine, int bottomLine);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);

View File

@ -2,7 +2,7 @@
/** @file Editor.cxx
** Main code for the edit control.
**/
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
@ -131,7 +131,7 @@ Editor::Editor() {
selectionType = selChar;
lastXChosen = 0;
lineAnchor = 0;
lineAnchorPos = 0;
originalAnchorPos = 0;
wordSelectAnchorStartPos = 0;
wordSelectAnchorEndPos = 0;
@ -144,6 +144,9 @@ Editor::Editor() {
caretYPolicy = CARET_EVEN;
caretYSlop = 0;
visiblePolicy = 0;
visibleSlop = 0;
searchAnchor = 0;
@ -156,6 +159,7 @@ Editor::Editor() {
verticalScrollBarVisible = true;
endAtLastLine = true;
caretSticky = SC_CARETSTICKY_OFF;
marginOptions = SC_MARGINOPTION_NONE;
multipleSelection = false;
additionalSelectionTyping = false;
multiPasteMode = SC_MULTIPASTE_ONCE;
@ -755,6 +759,7 @@ void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSel
void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
currentPos_ = ClampPositionIntoDocument(currentPos_);
anchor_ = ClampPositionIntoDocument(anchor_);
int currentLine = pdoc->LineFromPosition(currentPos_.Position());
/* For Line selection - ensure the anchor and caret are always
at the beginning and end of the region lines. */
if (sel.selType == Selection::selLines) {
@ -773,6 +778,10 @@ void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition ancho
sel.RangeMain() = rangeNew;
SetRectangularRange();
ClaimSelection();
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
}
void Editor::SetSelection(int currentPos_, int anchor_) {
@ -782,6 +791,7 @@ void Editor::SetSelection(int currentPos_, int anchor_) {
// Just move the caret on the main selection
void Editor::SetSelection(SelectionPosition currentPos_) {
currentPos_ = ClampPositionIntoDocument(currentPos_);
int currentLine = pdoc->LineFromPosition(currentPos_.Position());
if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
InvalidateSelection(SelectionRange(currentPos_));
}
@ -794,6 +804,10 @@ void Editor::SetSelection(SelectionPosition currentPos_) {
SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
}
ClaimSelection();
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
}
void Editor::SetSelection(int currentPos_) {
@ -801,6 +815,7 @@ void Editor::SetSelection(int currentPos_) {
}
void Editor::SetEmptySelection(SelectionPosition currentPos_) {
int currentLine = pdoc->LineFromPosition(currentPos_.Position());
SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
InvalidateSelection(rangeNew);
@ -810,6 +825,9 @@ void Editor::SetEmptySelection(SelectionPosition currentPos_) {
SetRectangularRange();
ClaimSelection();
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
}
void Editor::SetEmptySelection(int currentPos_) {
@ -910,6 +928,12 @@ int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, b
SetXYScroll(newXY);
}
}
int currentLine = pdoc->LineFromPosition(newPos.Position());
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
return 0;
}
@ -957,7 +981,9 @@ void Editor::ScrollTo(int line, bool moveThumb) {
int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
if (topLineNew != topLine) {
// Try to optimise small scrolls
#ifndef UNDER_CE
int linesToMove = topLine - topLineNew;
#endif
SetTopLine(topLineNew);
// Optimize by styling the view as this will invalidate any needed area
// which could abort the initial paint if discovered later.
@ -1006,6 +1032,59 @@ void Editor::VerticalCentreCaret() {
}
}
void Editor::MoveSelectedLines(int lineDelta) {
// if selection doesn't start at the beginning of the line, set the new start
int selectionStart = SelectionStart().Position();
int startLine = pdoc->LineFromPosition(selectionStart);
int beginningOfStartLine = pdoc->LineStart(startLine);
selectionStart = beginningOfStartLine;
// if selection doesn't end at the beginning of a line greater than that of the start,
// then set it at the beginning of the next one
int selectionEnd = SelectionEnd().Position();
int endLine = pdoc->LineFromPosition(selectionEnd);
int beginningOfEndLine = pdoc->LineStart(endLine);
if (selectionEnd > beginningOfEndLine
|| selectionStart == selectionEnd) {
selectionEnd = pdoc->LineStart(endLine + 1);
}
// if there's nowhere for the selection to move
// (i.e. at the beginning going up or at the end going down),
// stop it right there!
if ((selectionStart == 0 && lineDelta < 0)
|| (selectionEnd == pdoc->Length() && lineDelta > 0)
|| selectionStart == selectionEnd) {
return;
}
UndoGroup ug(pdoc);
SetSelection(selectionStart, selectionEnd);
SelectionText selectedText;
CopySelectionRange(&selectedText);
int selectionLength = SelectionRange(selectionStart, selectionEnd).Length();
ClearSelection();
Point currentLocation = LocationFromPosition(CurrentPosition());
int currentLine = LineFromLocation(currentLocation);
GoToLine(currentLine + lineDelta);
pdoc->InsertCString(CurrentPosition(), selectedText.s);
SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
}
void Editor::MoveSelectedLinesUp() {
MoveSelectedLines(-1);
}
void Editor::MoveSelectedLinesDown() {
MoveSelectedLines(1);
}
void Editor::MoveCaretInsideView(bool ensureVisible) {
PRectangle rcClient = GetTextRectangle();
Point pt = PointMainCaret();
@ -1691,7 +1770,6 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
int visibleLine = topLine;
int yposScreen = 0;
// Work out whether the top line is whitespace located after a
// lessening of fold level which implies a 'fold tail' but which should not
// be displayed until the last of a sequence of whitespace.
@ -1709,6 +1787,11 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
needWhiteClosure = true;
}
}
if (highlightDelimiter.isEnabled && (vs.ms[margin].mask & SC_MASK_FOLDERS)) {
int lineBack = cs.DocFromDisplay(topLine);
int lineFront = cs.DocFromDisplay(((rcMargin.bottom - rcMargin.top) / vs.lineHeight) + topLine) + 1;
pdoc->GetHighlightDelimiters(highlightDelimiter, pdoc->LineFromPosition(CurrentPosition()), lineBack, lineFront);
}
// Old code does not know about new markers needed to distinguish all cases
int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
@ -1719,10 +1802,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed());
int lineDoc = cs.DocFromDisplay(visibleLine);
PLATFORM_ASSERT(cs.GetVisible(lineDoc));
bool firstSubLine = visibleLine == cs.DisplayFromDoc(lineDoc);
bool lastSubLine = visibleLine == (cs.DisplayFromDoc(lineDoc + 1) - 1);
// Decide which fold indicator should be displayed
level = pdoc->GetLevel(lineDoc);
@ -1734,19 +1817,31 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK;
if (level & SC_FOLDLEVELHEADERFLAG) {
if (firstSubLine) {
if (cs.GetExpanded(lineDoc)) {
if (levelNum == SC_FOLDLEVELBASE)
marks |= 1 << SC_MARKNUM_FOLDEROPEN;
else
marks |= 1 << folderOpenMid;
} else {
if (levelNum == SC_FOLDLEVELBASE)
marks |= 1 << SC_MARKNUM_FOLDER;
else
marks |= 1 << folderEnd;
}
if (levelNum < levelNextNum) {
if (cs.GetExpanded(lineDoc)) {
if (levelNum == SC_FOLDLEVELBASE)
marks |= 1 << SC_MARKNUM_FOLDEROPEN;
else
marks |= 1 << folderOpenMid;
} else {
if (levelNum == SC_FOLDLEVELBASE)
marks |= 1 << SC_MARKNUM_FOLDER;
else
marks |= 1 << folderEnd;
}
} else if (levelNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
} else {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
if (levelNum < levelNextNum) {
if (cs.GetExpanded(lineDoc)) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
} else if (levelNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
} else if (levelNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
}
needWhiteClosure = false;
} else if (level & SC_FOLDLEVELWHITEFLAG) {
@ -1777,16 +1872,19 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
if (levelNext & SC_FOLDLEVELWHITEFLAG) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
needWhiteClosure = true;
} else if (levelNextNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
} else if (lastSubLine) {
if (levelNextNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
} else {
marks |= 1 << SC_MARKNUM_FOLDERTAIL;
}
} else {
marks |= 1 << SC_MARKNUM_FOLDERTAIL;
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
} else {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
}
marks &= vs.ms[margin].mask;
PRectangle rcMarker = rcSelMargin;
rcMarker.top = yposScreen;
@ -1833,7 +1931,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
if (marks) {
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if (marks & 1) {
vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font);
LineMarker::typeOfFold tFold;
if (!highlightDelimiter.isCurrentBlockHighlight(lineDoc)) {
tFold = LineMarker::undefined;
} else if (highlightDelimiter.isBodyBlockFold(lineDoc)) {
tFold = LineMarker::body;
} else if (highlightDelimiter.isHeadBlockFold(lineDoc)) {
tFold = LineMarker::head;
} else if (highlightDelimiter.isTailBlockFold(lineDoc)) {
tFold = LineMarker::tail;
} else {
//Normally, this branch is never used. But I prefer to manage it anyway.
tFold = LineMarker::undefined;
}
vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font, tFold);
}
marks >>= 1;
}
@ -2132,7 +2243,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
} else {
lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg,
lenSeg, ll->positions + startseg + 1);
lenSeg, ll->positions + startseg + 1, pdoc);
}
}
} else { // invisible
@ -2478,12 +2589,22 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
}
}
void Editor::DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine) {
const int subLineStart = ll->positions[ll->LineStart(subLine)];
PRectangle rcIndic(
ll->positions[startPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
ll->positions[endPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine);
}
void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
// Draw decorators
const int posLineStart = pdoc->LineStart(line);
const int lineStart = ll->LineStart(subLine);
const int subLineStart = ll->positions[lineStart];
const int posLineEnd = posLineStart + lineEnd;
if (!under) {
@ -2508,12 +2629,7 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
// IN indicator run, looking for END
if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
// AT end of indicator run, DRAW it!
PRectangle rcIndic(
ll->positions[startPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
ll->positions[indicPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
DrawIndicator(indicnum, startPos, indicPos, surface, vsDraw, xStart, rcLine, ll, subLine);
// RESET control var
startPos = -1;
}
@ -2533,16 +2649,33 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
int endPos = deco->rs.EndRun(startPos);
if (endPos > posLineEnd)
endPos = posLineEnd;
PRectangle rcIndic(
ll->positions[startPos - posLineStart] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
ll->positions[endPos - posLineStart] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine);
DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
surface, vsDraw, xStart, rcLine, ll, subLine);
startPos = deco->rs.EndRun(endPos);
}
}
}
// Use indicators to highlight matching braces
if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
(vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
int braceIndicator = (bracesMatchStyle == STYLE_BRACELIGHT) ? vs.braceHighlightIndicator : vs.braceBadLightIndicator;
if (under == vsDraw.indicators[braceIndicator].under) {
Range rangeLine(posLineStart + lineStart, posLineEnd);
if (rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - posLineStart;
if (braceOffset < ll->numCharsInLine) {
DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - posLineStart;
if (braceOffset < ll->numCharsInLine) {
DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
}
}
}
}
}
void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@ -2727,7 +2860,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
ll->psel = &sel;
BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc);
int next = bfBack.First();
// Background drawing loop
@ -2798,6 +2931,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
if (vsDraw.edgeState == EDGE_LINE) {
int edgeX = theEdge * vsDraw.spaceWidth;
rcSegment.left = edgeX + xStart;
if ((ll->wrapIndent != 0) && (lineStart != 0))
rcSegment.left -= ll->wrapIndent;
rcSegment.right = rcSegment.left + 1;
surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated);
}
@ -2817,8 +2952,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
inIndentation = subLine == 0; // Do not handle indentation except on first subline.
// Foreground drawing loop
BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible,
((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset), pdoc);
next = bfFore.First();
while (next < lineEnd) {
@ -2998,7 +3133,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
lineNextWithText++;
}
if (lineNextWithText > line) {
// This line is empty, so use indentation of last line with text
xStartText = 100000; // Don't limit to visible indentation on empty line
// This line is empty, so use indentation of first next line with text
indentSpace = Platform::Maximum(indentSpace,
pdoc->GetLineIndentation(lineNextWithText));
}
@ -3430,34 +3566,40 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
rcLine.top = ypos;
rcLine.bottom = ypos + vs.lineHeight;
bool bracesIgnoreStyle = false;
if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
(vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
bracesIgnoreStyle = true;
}
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
highlightGuideColumn * vs.spaceWidth);
highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle);
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
//durPaint += et.Duration(true);
// Restore the previous styles for the brace highlights in case layout is in cache.
ll->RestoreBracesHighlight(rangeLine, braces);
ll->RestoreBracesHighlight(rangeLine, braces, bracesIgnoreStyle);
bool expanded = cs.GetExpanded(lineDoc);
// Paint the line above the fold
if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
||
(!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
const int level = pdoc->GetLevel(lineDoc);
const int levelNext = pdoc->GetLevel(lineDoc + 1);
if ((level & SC_FOLDLEVELHEADERFLAG) &&
((level & SC_FOLDLEVELNUMBERMASK) < (levelNext & SC_FOLDLEVELNUMBERMASK))) {
// Paint the line above the fold
if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
||
(!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.bottom = rcFoldLine.top + 1;
surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
}
}
// Paint the line below the fold
if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
||
(!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
// Paint the line below the fold
if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
||
(!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.top = rcFoldLine.bottom - 1;
surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
@ -3572,6 +3714,10 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
vsPrint.whitespaceForegroundSet = false;
vsPrint.showCaretLineBackground = false;
vsPrint.showCaretLineBackgroundAlways = false;
// Don't highlight matching braces using indicators
vsPrint.braceHighlightIndicatorSet = false;
vsPrint.braceBadLightIndicatorSet = false;
// Set colours for printing according to users settings
for (size_t sty = 0; sty < vsPrint.stylesSize; sty++) {
@ -3792,37 +3938,50 @@ void Editor::FilterSelections() {
}
}
static bool cmpSelPtrs(const SelectionRange *a, const SelectionRange *b) {
return *a < *b;
}
// AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
FilterSelections();
{
UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
for (size_t r=0; r<sel.Count(); r++) {
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
sel.Range(r).End().Position())) {
int positionInsert = sel.Range(r).Start().Position();
if (!sel.Range(r).Empty()) {
if (sel.Range(r).Length()) {
pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
sel.Range(r).ClearVirtualSpace();
std::vector<SelectionRange *> selPtrs;
for (size_t r = 0; r < sel.Count(); r++) {
selPtrs.push_back(&sel.Range(r));
}
std::sort(selPtrs.begin(), selPtrs.end(), cmpSelPtrs);
for (std::vector<SelectionRange *>::reverse_iterator rit = selPtrs.rbegin();
rit != selPtrs.rend(); ++rit) {
SelectionRange *currentSel = *rit;
if (!RangeContainsProtected(currentSel->Start().Position(),
currentSel->End().Position())) {
int positionInsert = currentSel->Start().Position();
if (!currentSel->Empty()) {
if (currentSel->Length()) {
pdoc->DeleteChars(positionInsert, currentSel->Length());
currentSel->ClearVirtualSpace();
} else {
// Range is all virtual so collapse to start of virtual space
sel.Range(r).MinimizeVirtualSpace();
currentSel->MinimizeVirtualSpace();
}
} else if (inOverstrike) {
if (positionInsert < pdoc->Length()) {
if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
pdoc->DelChar(positionInsert);
sel.Range(r).ClearVirtualSpace();
currentSel->ClearVirtualSpace();
}
}
}
positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
positionInsert = InsertSpace(positionInsert, currentSel->caret.VirtualSpace());
if (pdoc->InsertString(positionInsert, s, len)) {
sel.Range(r).caret.SetPosition(positionInsert + len);
sel.Range(r).anchor.SetPosition(positionInsert + len);
currentSel->caret.SetPosition(positionInsert + len);
currentSel->anchor.SetPosition(positionInsert + len);
}
sel.Range(r).ClearVirtualSpace();
currentSel->ClearVirtualSpace();
// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
if (wrapState != eWrapNone) {
AutoSurface surface(this);
@ -4041,7 +4200,13 @@ bool Editor::CanPaste() {
void Editor::Clear() {
// If multiple selections, don't delete EOLS
if (sel.Empty()) {
UndoGroup ug(pdoc, sel.Count() > 1);
bool singleVirtual = false;
if ((sel.Count() == 1) &&
!RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1) &&
sel.RangeMain().Start().VirtualSpace()) {
singleVirtual = true;
}
UndoGroup ug(pdoc, (sel.Count() > 1) || singleVirtual);
for (size_t r=0; r<sel.Count(); r++) {
if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
if (sel.Range(r).Start().VirtualSpace()) {
@ -4144,6 +4309,10 @@ void Editor::DelCharBack(bool allowLineStartDeletion) {
void Editor::NotifyFocus(bool) {}
void Editor::SetCtrlID(int identifier) {
ctrlID = identifier;
}
void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_STYLENEEDED;
@ -4395,7 +4564,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);
braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length);
}
if (cs.LinesDisplayed() < cs.LinesInDoc()) {
if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && cs.HiddenLines()) {
// Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
@ -4611,6 +4780,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
case SCI_SELECTIONDUPLICATE:
case SCI_COPYALLOWLINE:
case SCI_VERTICALCENTRECARET:
case SCI_MOVESELECTEDLINESUP:
case SCI_MOVESELECTEDLINESDOWN:
break;
// Filter out all others like display changes. Also, newlines are redundant
@ -5355,10 +5526,8 @@ int Editor::KeyDefault(int, int) {
return 0;
}
int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) {
DwellEnd(false);
int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
int msg = kmap.Find(key, modifiers);
if (msg) {
if (consumed)
@ -5371,6 +5540,12 @@ int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
}
}
int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
return KeyDownWithModifiers(key, modifiers, consumed);
}
void Editor::SetWhitespaceVisible(int view) {
vs.viewWhitespace = static_cast<WhiteSpaceVisibility>(view);
}
@ -5862,17 +6037,37 @@ Window::Cursor Editor::GetMarginCursor(Point pt) {
return Window::cursorReverseArrow;
}
void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
if (lineAnchor_ < lineCurrent_) {
SetSelection(pdoc->LineStart(lineCurrent_ + 1),
pdoc->LineStart(lineAnchor_));
} else if (lineAnchor_ > lineCurrent_) {
SetSelection(pdoc->LineStart(lineCurrent_),
pdoc->LineStart(lineAnchor_ + 1));
} else { // Same line, select it
SetSelection(pdoc->LineStart(lineAnchor_ + 1),
pdoc->LineStart(lineAnchor_));
void Editor::LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine) {
int selCurrentPos, selAnchorPos;
if (wholeLine) {
int lineCurrent_ = pdoc->LineFromPosition(lineCurrentPos_);
int lineAnchor_ = pdoc->LineFromPosition(lineAnchorPos_);
if (lineAnchorPos_ < lineCurrentPos_) {
selCurrentPos = pdoc->LineStart(lineCurrent_ + 1);
selAnchorPos = pdoc->LineStart(lineAnchor_);
} else if (lineAnchorPos_ > lineCurrentPos_) {
selCurrentPos = pdoc->LineStart(lineCurrent_);
selAnchorPos = pdoc->LineStart(lineAnchor_ + 1);
} else { // Same line, select it
selCurrentPos = pdoc->LineStart(lineAnchor_ + 1);
selAnchorPos = pdoc->LineStart(lineAnchor_);
}
} else {
if (lineAnchorPos_ < lineCurrentPos_) {
selCurrentPos = StartEndDisplayLine(lineCurrentPos_, false) + 1;
selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1);
selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true);
} else if (lineAnchorPos_ > lineCurrentPos_) {
selCurrentPos = StartEndDisplayLine(lineCurrentPos_, true);
selAnchorPos = StartEndDisplayLine(lineAnchorPos_, false) + 1;
selAnchorPos = pdoc->MovePositionOutsideChar(selAnchorPos, 1);
} else { // Same line, select it
selCurrentPos = StartEndDisplayLine(lineAnchorPos_, false) + 1;
selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1);
selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true);
}
}
SetSelection(selCurrentPos, selAnchorPos);
}
void Editor::WordSelection(int pos) {
@ -5952,10 +6147,20 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
selectionType = selWord;
doubleClick = true;
} else if (selectionType == selWord) {
selectionType = selLine;
// Since we ended up here, we're inside a *triple* click, which should always select
// whole line irregardless of word wrap being enabled or not.
selectionType = selWholeLine;
} else {
selectionType = selChar;
originalAnchorPos = sel.MainCaret();
if (inSelMargin) {
// Selection type is either selSubLine or selWholeLine here and we're inside margin.
// If it is selSubLine, we're inside a *double* click and word wrap is enabled,
// so we switch to selWholeLine in order to select whole line.
if (selectionType == selSubLine)
selectionType = selWholeLine;
} else {
selectionType = selChar;
originalAnchorPos = sel.MainCaret();
}
}
}
@ -5987,9 +6192,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
wordSelectAnchorEndPos = endWord;
wordSelectInitialCaretPos = sel.MainCaret();
WordSelection(wordSelectInitialCaretPos);
} else if (selectionType == selLine) {
lineAnchor = LineFromLocation(pt);
SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
} else if (selectionType == selSubLine || selectionType == selWholeLine) {
lineAnchorPos = newPos.Position();
LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine);
//Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
} else {
SetEmptySelection(sel.MainCaret());
@ -6009,25 +6214,27 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
return;
}
if (!shift) {
lineAnchor = LineFromLocation(pt);
// Single click in margin: select whole line
LineSelection(lineAnchor, lineAnchor);
SetSelection(pdoc->LineStart(lineAnchor + 1),
pdoc->LineStart(lineAnchor));
// Single click in margin: select whole line or only subline if word wrap is enabled
lineAnchorPos = newPos.Position();
selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine;
LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine);
} else {
// Single shift+click in margin: select from line anchor to clicked line
if (sel.MainAnchor() > sel.MainCaret())
lineAnchor = pdoc->LineFromPosition(sel.MainAnchor() - 1);
lineAnchorPos = sel.MainAnchor() - 1;
else
lineAnchor = pdoc->LineFromPosition(sel.MainAnchor());
int lineStart = LineFromLocation(pt);
LineSelection(lineStart, lineAnchor);
//lineAnchor = lineStart; // Keep the same anchor for ButtonMove
lineAnchorPos = sel.MainAnchor();
// Reset selection type if there is an empty selection.
// This ensures that we don't end up stuck in previous selection mode, which is no longer valid.
// Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine.
// This ensures that we continue selecting in the same selection mode.
if (sel.Empty() || (selectionType != selSubLine && selectionType != selWholeLine))
selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine;
LineSelection(newPos.Position(), lineAnchorPos, selectionType == selWholeLine);
}
SetDragPosition(SelectionPosition(invalidPosition));
SetMouseCapture(true);
selectionType = selLine;
} else {
if (PointIsHotspot(pt)) {
NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
@ -6185,23 +6392,18 @@ void Editor::ButtonMove(Point pt) {
}
} else {
// Continue selecting by line
int lineMove = LineFromLocation(pt);
LineSelection(lineMove, lineAnchor);
LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine);
}
}
// Autoscroll
PRectangle rcClient = GetClientRectangle();
int lineMove = DisplayFromPosition(movePos.Position());
if (pt.y > rcClient.bottom) {
int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
if (lineMove < 0) {
lineMove = cs.DisplayFromDoc(pdoc->LinesTotal() - 1);
}
ScrollTo(lineMove - LinesOnScreen() + 5);
ScrollTo(lineMove - LinesOnScreen() + 1);
Redraw();
} else if (pt.y < rcClient.top) {
int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
ScrollTo(lineMove - 2);
ScrollTo(lineMove);
Redraw();
}
EnsureCaretVisible(false, false, true);
@ -6209,7 +6411,7 @@ void Editor::ButtonMove(Point pt) {
if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
SetHotSpotRange(NULL);
if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos ) {
if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) {
if (inDragDrop == ddNone) {
DisplayCursor(Window::cursorText);
}
@ -6565,8 +6767,8 @@ void Editor::ToggleContraction(int line) {
if (cs.GetExpanded(line)) {
int lineMaxSubord = pdoc->GetLastChild(line);
cs.SetExpanded(line, 0);
if (lineMaxSubord > line) {
cs.SetExpanded(line, 0);
cs.SetVisible(line + 1, lineMaxSubord, false);
int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
@ -6593,7 +6795,7 @@ void Editor::ToggleContraction(int line) {
}
int Editor::ContractedFoldNext(int lineStart) {
for (int line = lineStart; line<pdoc->LinesTotal(); ) {
for (int line = lineStart; line<pdoc->LinesTotal();) {
if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG))
return line;
line = cs.ContractedNext(line+1);
@ -6880,6 +7082,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
VerticalCentreCaret();
break;
case SCI_MOVESELECTEDLINESUP:
MoveSelectedLinesUp();
break;
case SCI_MOVESELECTEDLINESDOWN:
MoveSelectedLinesDown();
break;
case SCI_COPYRANGE:
CopyRangeToClipboard(wParam, lParam);
break;
@ -7288,6 +7498,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETSELECTIONEND:
return sel.LimitsForRectangularElseMain().end.Position();
case SCI_SETEMPTYSELECTION:
SetEmptySelection(wParam);
break;
case SCI_SETPRINTMAGNIFICATION:
printMagnification = wParam;
break;
@ -7746,6 +7960,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
InvalidateStyleData();
RedrawSelMargin();
break;
case SCI_MARKERSETBACKSELECTED:
if (wParam <= MARKER_MAX)
vs.markers[wParam].backSelected.desired = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_MARKERENABLEHIGHLIGHT:
highlightDelimiter.isEnabled = wParam == 1;
InvalidateStyleRedraw();
break;
case SCI_MARKERSETBACK:
if (wParam <= MARKER_MAX)
vs.markers[wParam].back.desired = ColourDesired(lParam);
@ -7936,7 +8159,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETCARETLINEVISIBLEALWAYS:
vs.showCaretLineBackgroundAlways = wParam != 0;
InvalidateStyleRedraw();
break;
case SCI_GETCARETLINEBACK:
return vs.caretLineBackground.desired.AsLong();
case SCI_SETCARETLINEBACK:
@ -8178,6 +8400,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_INDICGETALPHA:
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
case SCI_INDICSETOUTLINEALPHA:
if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
vs.indicators[wParam].outlineAlpha = lParam;
InvalidateStyleRedraw();
}
break;
case SCI_INDICGETOUTLINEALPHA:
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0;
case SCI_SETINDICATORCURRENT:
pdoc->decorations.SetCurrentIndicator(wParam);
break;
@ -8303,10 +8535,24 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
SetBraceHighlight(static_cast<int>(wParam), lParam, STYLE_BRACELIGHT);
break;
case SCI_BRACEHIGHLIGHTINDICATOR:
if (lParam >= 0 && lParam <= INDIC_MAX) {
vs.braceHighlightIndicatorSet = wParam != 0;
vs.braceHighlightIndicator = lParam;
}
break;
case SCI_BRACEBADLIGHT:
SetBraceHighlight(static_cast<int>(wParam), -1, STYLE_BRACEBAD);
break;
case SCI_BRACEBADLIGHTINDICATOR:
if (lParam >= 0 && lParam <= INDIC_MAX) {
vs.braceBadLightIndicatorSet = wParam != 0;
vs.braceBadLightIndicator = lParam;
}
break;
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
@ -8581,6 +8827,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_MARGINGETSTYLEOFFSET:
return vs.marginStyleOffset;
case SCI_SETMARGINOPTIONS:
marginOptions = wParam;
break;
case SCI_GETMARGINOPTIONS:
return marginOptions;
case SCI_MARGINSETTEXT:
pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam));
break;
@ -8895,6 +9148,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_CHANGELEXERSTATE:
pdoc->ChangeLexerState(wParam, lParam);
break;
case SCI_SETIDENTIFIER:
SetCtrlID(wParam);
break;
case SCI_GETIDENTIFIER:
return GetCtrlID();
default:
return DefWndProc(iMessage, wParam, lParam);

View File

@ -2,7 +2,7 @@
/** @file Editor.h
** Defines the main editor class.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
@ -139,6 +139,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
int cursorMode;
int controlCharSymbol;
// Highlight current folding block
HighlightDelimiter highlightDelimiter;
bool hasFocus;
bool hideSelection;
bool inOverstrike;
@ -160,6 +163,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool verticalScrollBarVisible;
bool endAtLastLine;
int caretSticky;
int marginOptions;
bool multipleSelection;
bool additionalSelectionTyping;
int multiPasteMode;
@ -191,7 +195,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int dwellDelay;
int ticksToDwell;
bool dwelling;
enum { selChar, selWord, selLine } selectionType;
enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
@ -199,7 +203,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
SelectionPosition posDrop;
int hotSpotClickPos;
int lastXChosen;
int lineAnchor;
int lineAnchorPos;
int originalAnchorPos;
int wordSelectAnchorStartPos;
int wordSelectAnchorEndPos;
@ -332,6 +336,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
void VerticalCentreCaret();
void MoveSelectedLines(int lineDelta);
void MoveSelectedLinesUp();
void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
@ -367,6 +374,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour);
void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@ -413,6 +422,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded);
@ -456,6 +466,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
int GetWhitespaceVisible();
@ -485,7 +496,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
Window::Cursor GetMarginCursor(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
void WordSelection(int pos);
void DwellEnd(bool mouseMoved);
void MouseLeave();

View File

@ -27,6 +27,17 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
y = 2 - y;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_SQUIGGLELOW) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 3;
int y = 0;
while (x < rc.right) {
surface->LineTo(x-1, rc.top + y);
y = 1 - y;
surface->LineTo(x, rc.top + y);
x += 3;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid);
int x = rc.left + 5;
@ -67,12 +78,26 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) {
} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, (fillAlpha > SC_ALPHA_OPAQUE-30)?SC_ALPHA_OPAQUE:(fillAlpha+30), 0);
surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 0);
} else if (style == INDIC_DASH) {
int x = rc.left;
while (x < rc.right) {
surface->MoveTo(x, ymid);
surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
x += 7;
}
} else if (style == INDIC_DOTS) {
int x = rc.left;
while (x < rc.right) {
PRectangle rcDot(x, ymid, x+1, ymid+1);
surface->FillRectangle(rcDot, fore.allocated);
x += 2;
}
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);

View File

@ -20,7 +20,8 @@ public:
bool under;
ColourPair fore;
int fillAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
int outlineAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};

View File

@ -2,7 +2,7 @@
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
@ -20,6 +20,7 @@ using namespace Scintilla;
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want);
pal.WantFind(back, want);
pal.WantFind(backSelected, want);
if (pxpm) {
pxpm->RefreshColourPalette(pal, want);
}
@ -67,7 +68,32 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore);
}
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
ColourPair head = back;
ColourPair body = back;
ColourPair tail = back;
switch (tFold) {
case LineMarker::head :
head = backSelected;
tail = backSelected;
if (markType == SC_MARK_VLINE)
body = backSelected;
break;
case LineMarker::body :
head = backSelected;
body = backSelected;
break;
case LineMarker::tail :
body = backSelected;
tail = backSelected;
break;
default :
// LineMarker::undefined
break;
}
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
@ -159,106 +185,138 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top + blobSize - (rcWhole.bottom - rcWhole.top)/2);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNER) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2 + 1);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNERCURVE) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNERCURVE) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-2);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_BOXMINUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_BOXMINUS) {
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);

View File

@ -2,7 +2,7 @@
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
@ -12,19 +12,24 @@
namespace Scintilla {
#endif
/**
*/
class LineMarker {
public:
enum typeOfFold { undefined, head, body, tail };
int markType;
ColourPair fore;
ColourPair back;
ColourPair backSelected;
int alpha;
XPM *pxpm;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
}
@ -33,6 +38,7 @@ public:
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
}
@ -44,6 +50,7 @@ public:
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
delete pxpm;
pxpm = NULL;
@ -52,7 +59,7 @@ public:
void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
};
#ifdef SCI_NAMESPACE

View File

@ -151,15 +151,15 @@ void LineLayout::SetLineStart(int line, int start) {
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight) {
if (rangeLine.ContainsCharacter(braces[0])) {
char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle;
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset];
@ -172,14 +172,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
}
}
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
if (rangeLine.ContainsCharacter(braces[0])) {
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0];
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1];
@ -391,18 +391,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1;
}
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
utf8(utf8_),
nextBreak(lineStart_),
saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
subBreak(-1) {
subBreak(-1),
pdoc(pdoc_) {
saeSize = 8;
selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) {
@ -435,7 +436,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
if (utf8) {
if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0;
for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@ -456,10 +457,6 @@ int BreakFinder::First() const {
return nextBreak;
}
static bool IsTrailByte(int ch) {
return (ch >= 0x80) && (ch < (0x80 + 0x40));
}
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
@ -490,34 +487,7 @@ int BreakFinder::Next() {
subBreak = -1;
return nextBreak;
} else {
int lastGoodBreak = -1;
int lastOKBreak = -1;
int lastUTF8Break = -1;
int j;
for (j = subBreak + 1; j <= nextBreak; j++) {
if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
lastGoodBreak = j;
}
if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
lastOKBreak = j;
}
if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
lastUTF8Break = j;
}
if (((j - subBreak) >= lengthEachSubdivision) &&
((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
break;
}
}
if (lastGoodBreak >= 0) {
subBreak = lastGoodBreak;
} else if (lastOKBreak >= 0) {
subBreak = lastOKBreak;
} else if (lastUTF8Break >= 0) {
subBreak = lastUTF8Break;
} else {
subBreak = nextBreak;
}
subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
if (subBreak >= nextBreak) {
subBreak = -1;
return nextBreak;
@ -624,7 +594,8 @@ void PositionCache::SetSize(size_t size_) {
}
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions) {
const char *s, unsigned int len, int *positions, Document *pdoc) {
allClear = false;
int probe = -1;
if ((size > 0) && (len < 30)) {
@ -646,7 +617,22 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
probe = probe2;
}
}
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
if (len > BreakFinder::lengthStartSubdivision) {
// Break up into segments
unsigned int startSegment = 0;
int xStartSegment = 0;
while (startSegment < len) {
unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
positions[startSegment + inSeg] += xStartSegment;
}
xStartSegment = positions[startSegment + lenSegment - 1];
startSegment += lenSegment;
}
} else {
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
}
if (probe >= 0) {
clock++;
if (clock > 60000) {

View File

@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const;
void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight);
void RestoreBracesHighlight(Range rangeLine, Position braces[]);
char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const;
};
@ -117,16 +117,10 @@ public:
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
LineLayout *ll;
int lineStart;
int lineEnd;
int posLineStart;
bool utf8;
int nextBreak;
int *selAndEdge;
unsigned int saeSize;
@ -134,9 +128,16 @@ class BreakFinder {
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
Document *pdoc;
void Insert(int val);
public:
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder();
int First() const;
int Next();
@ -152,9 +153,9 @@ public:
~PositionCache();
void Clear();
void SetSize(size_t size_);
int GetSize() const { return size; }
size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions);
const char *s, unsigned int len, int *positions, Document *pdoc);
};
inline bool IsSpaceOrTab(int ch) {

View File

@ -321,7 +321,7 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) {
}
}
const unsigned char escapeValue(unsigned char ch) {
unsigned char escapeValue(unsigned char ch) {
switch (ch) {
case 'a': return '\a';
case 'b': return '\b';
@ -888,10 +888,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
return NOTFOUND;
break;
case BOT:
bopat[*ap++] = lp;
bopat[static_cast<int>(*ap++)] = lp;
break;
case EOT:
eopat[*ap++] = lp;
eopat[static_cast<int>(*ap++)] = lp;
break;
case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))

View File

@ -21,7 +21,7 @@ using namespace Scintilla;
#endif
// Find the first run at a position
int RunStyles::RunFromPosition(int position) {
int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position);
// Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
@ -147,6 +147,8 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart);
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return true;
} else {
return false;
@ -216,3 +218,33 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
}
}
int RunStyles::Runs() const {
return starts->Partitions();
}
bool RunStyles::AllSame() const {
for (int run = 1; run < starts->Partitions(); run++) {
if (styles->ValueAt(run) != styles->ValueAt(run - 1))
return false;
}
return true;
}
bool RunStyles::AllSameAs(int value) const {
return AllSame() && (styles->ValueAt(0) == value);
}
int RunStyles::Find(int value, int start) const {
if (start < Length()) {
int run = start ? RunFromPosition(start) : 0;
if (styles->ValueAt(run) == value)
return start;
run++;
while (run < starts->Partitions()) {
if (styles->ValueAt(run) == value)
return starts->PositionFromPartition(run);
run++;
}
}
return -1;
}

View File

@ -15,10 +15,10 @@ namespace Scintilla {
#endif
class RunStyles {
public:
private:
Partitioning *starts;
SplitVector<int> *styles;
int RunFromPosition(int position);
int RunFromPosition(int position) const;
int SplitRun(int position);
void RemoveRun(int run);
void RemoveRunIfEmpty(int run);
@ -37,6 +37,10 @@ public:
void InsertSpace(int position, int insertLength);
void DeleteAll();
void DeleteRange(int position, int deleteLength);
int Runs() const;
bool AllSame() const;
bool AllSameAs(int value) const;
int Find(int value, int start) const;
};
#ifdef SCI_NAMESPACE

View File

@ -135,16 +135,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
AutoCompleteMove(1);
return 0;
case SCI_LINEUP:
AutoCompleteMove( -1);
AutoCompleteMove(-1);
return 0;
case SCI_PAGEDOWN:
AutoCompleteMove(5);
return 0;
case SCI_PAGEUP:
AutoCompleteMove( -5);
AutoCompleteMove(-5);
return 0;
case SCI_VCHOME:
AutoCompleteMove( -5000);
AutoCompleteMove(-5000);
return 0;
case SCI_LINEEND:
AutoCompleteMove(5000);
@ -349,6 +349,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.wParam = listType;
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
scn.position = firstPos;
scn.lParam = firstPos;
scn.text = selected;
NotifyParent(scn);

View File

@ -16,14 +16,51 @@
using namespace Scintilla;
#endif
Style::Style() {
aliasOfDefaultFont = true;
FontAlias::FontAlias() {
}
FontAlias::~FontAlias() {
SetID(0);
// ~Font will not release the actual font resource sine it is now 0
}
void FontAlias::MakeAlias(Font &fontOrigin) {
SetID(fontOrigin.GetID());
}
void FontAlias::ClearFont() {
SetID(0);
}
bool FontSpecification::EqualTo(const FontSpecification &other) const {
return bold == other.bold &&
italic == other.italic &&
size == other.size &&
characterSet == other.characterSet &&
fontName == other.fontName;
}
FontMeasurements::FontMeasurements() {
Clear();
}
void FontMeasurements::Clear() {
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
sizeZoomed = 2;
}
Style::Style() : FontSpecification() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false);
}
Style::Style(const Style &source) {
Style::Style(const Style &source) : FontSpecification(), FontMeasurements() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0,
false, false, false, false, caseMixed, true, true, false);
@ -42,11 +79,6 @@ Style::Style(const Style &source) {
}
Style::~Style() {
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_;
back.desired = back_;
characterSet = characterSet_;
@ -87,79 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
sizeZoomed = 2;
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
font.ClearFont();
FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
}
bool Style::EquivalentFontTo(const Style *other) const {
if (bold != other->bold ||
italic != other->italic ||
size != other->size ||
characterSet != other->characterSet)
return false;
if (fontName == other->fontName)
return true;
if (!fontName)
return false;
if (!other->fontName)
return false;
return strcmp(fontName, other->fontName) == 0;
}
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) {
font.SetID(defaultStyle->font.GetID());
} else if (fontName) {
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
} else {
font.SetID(0);
}
ascent = surface.Ascent(font);
descent = surface.Descent(font);
// Probably more typographically correct to include leading
// but that means more complex drawing as leading must be erased
//lineHeight = surface.ExternalLeading() + surface.Height();
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
void Style::Copy(Font &font_, const FontMeasurements &fm_) {
font.MakeAlias(font_);
#if PLAT_WX
font.SetAscent(fm_.ascent);
#endif
(FontMeasurements &)(*this) = fm_;
}

View File

@ -12,18 +12,54 @@
namespace Scintilla {
#endif
/**
*/
class Style {
public:
ColourPair fore;
ColourPair back;
bool aliasOfDefaultFont;
struct FontSpecification {
const char *fontName;
bool bold;
bool italic;
int size;
const char *fontName;
int characterSet;
int extraFontFlag;
FontSpecification() :
fontName(0),
bold(false),
italic(false),
size(10),
characterSet(0),
extraFontFlag(0) {
}
bool EqualTo(const FontSpecification &other) const;
};
// Just like Font but only has a copy of the FontID so should not delete it
class FontAlias : public Font {
// Private so FontAlias objects can not be copied
FontAlias(const FontAlias &);
FontAlias &operator=(const FontAlias &);
public:
FontAlias();
virtual ~FontAlias();
void MakeAlias(Font &fontOrigin);
void ClearFont();
};
struct FontMeasurements {
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
int sizeZoomed;
FontMeasurements();
void Clear();
};
/**
*/
class Style : public FontSpecification, public FontMeasurements {
public:
ColourPair fore;
ColourPair back;
bool eolFilled;
bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower};
@ -32,14 +68,7 @@ public:
bool changeable;
bool hotspot;
Font font;
int sizeZoomed;
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
FontAlias font;
Style();
Style(const Style &source);
@ -52,8 +81,7 @@ public:
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const;
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
void Copy(Font &font_, const FontMeasurements &fm_);
bool IsProtected() const { return !(changeable && visible);}
};

View File

@ -72,11 +72,66 @@ const char *FontNames::Save(const char *name) {
return names[max-1];
}
FontRealised::FontRealised(const FontSpecification &fs) {
frNext = NULL;
(FontSpecification &)(*this) = fs;
}
FontRealised::~FontRealised() {
font.Release();
delete frNext;
frNext = 0;
}
void FontRealised::Realise(Surface &surface, int zoomLevel) {
PLATFORM_ASSERT(fontName);
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
ascent = surface.Ascent(font);
descent = surface.Descent(font);
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
if (frNext) {
frNext->Realise(surface, zoomLevel);
}
}
FontRealised *FontRealised::Find(const FontSpecification &fs) {
if (!fs.fontName)
return this;
FontRealised *fr = this;
while (fr) {
if (fr->EqualTo(fs))
return fr;
fr = fr->frNext;
}
return 0;
}
void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
FontRealised *fr = this;
while (fr) {
if (maxAscent < fr->ascent)
maxAscent = fr->ascent;
if (maxDescent < fr->descent)
maxDescent = fr->descent;
fr = fr->frNext;
}
}
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
frFirst = NULL;
Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
@ -151,14 +206,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset;
braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
braceHighlightIndicator = source.braceHighlightIndicator;
braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
braceBadLightIndicator = source.braceBadLightIndicator;
}
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
delete frFirst;
frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
@ -257,6 +319,10 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0;
braceHighlightIndicatorSet = false;
braceHighlightIndicator = 0;
braceBadLightIndicatorSet = false;
braceBadLightIndicator = 0;
}
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@ -292,33 +358,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want);
}
void ViewStyle::CreateFont(const FontSpecification &fs) {
if (fs.fontName) {
for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
if (cur->EqualTo(fs))
return;
if (!cur->frNext) {
cur->frNext = new FontRealised(fs);
return;
}
}
frFirst = new FontRealised(fs);
}
}
void ViewStyle::Refresh(Surface &surface) {
delete frFirst;
frFirst = NULL;
selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight();
styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
maxAscent = styles[STYLE_DEFAULT].ascent;
maxDescent = styles[STYLE_DEFAULT].descent;
for (unsigned int i=0; i<stylesSize; i++) {
styles[i].extraFontFlag = extraFontFlag;
}
CreateFont(styles[STYLE_DEFAULT]);
for (unsigned int j=0; j<stylesSize; j++) {
CreateFont(styles[j]);
}
frFirst->Realise(surface, zoomLevel);
for (unsigned int k=0; k<stylesSize; k++) {
FontRealised *fr = frFirst->Find(styles[k]);
styles[k].Copy(fr->font, *fr);
}
maxAscent = 1;
maxDescent = 1;
frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
someStylesProtected = false;
someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) {
if (i != STYLE_DEFAULT) {
styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
if (maxAscent < styles[i].ascent)
maxAscent = styles[i].ascent;
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
if (styles[i].IsProtected()) {
for (unsigned int l=0; l<stylesSize; l++) {
if (styles[l].IsProtected()) {
someStylesProtected = true;
}
if (styles[i].caseForce != Style::caseMixed) {
if (styles[l].caseForce != Style::caseMixed) {
someStylesForceCase = true;
}
}
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@ -363,10 +455,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {

View File

@ -39,6 +39,20 @@ public:
const char *Save(const char *name);
};
class FontRealised : public FontSpecification, public FontMeasurements {
// Private so FontRealised objects can not be copied
FontRealised(const FontRealised &);
FontRealised &operator=(const FontRealised &);
public:
Font font;
FontRealised *frNext;
FontRealised(const FontSpecification &fs);
virtual ~FontRealised();
void Realise(Surface &surface, int zoomLevel);
FontRealised *Find(const FontSpecification &fs);
void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
};
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@ -48,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle {
public:
FontNames fontNames;
FontRealised *frFirst;
size_t stylesSize;
Style *styles;
LineMarker markers[MARKER_MAX + 1];
@ -115,11 +130,16 @@ public:
int marginStyleOffset;
int annotationVisible;
int annotationStyleOffset;
bool braceHighlightIndicatorSet;
int braceHighlightIndicator;
bool braceBadLightIndicatorSet;
int braceBadLightIndicator;
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void Init(size_t stylesSize_=64);
void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);

View File

@ -1 +1 @@
225
227

View File

@ -11,6 +11,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <limits.h>
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
@ -28,7 +29,7 @@
// Luckily microsoft has done the heavy lifting for us, so we'll just use their stub functions!
#if defined(_MSC_VER) && (_MSC_VER > 1200)
#define COMPILE_MULTIMON_STUBS
#include "MultiMon.h"
#include <MultiMon.h>
#endif
#ifndef IDC_HAND
@ -441,7 +442,7 @@ SurfaceImpl::SurfaceImpl() :
bitmap(0), bitmapOld(0),
paletteOld(0) {
// Windows 9x has only a 16 bit coordinate system so break after 30000 pixels
maxWidthMeasure = IsNT() ? 1000000 : 30000;
maxWidthMeasure = IsNT() ? INT_MAX : 30000;
// There appears to be a 16 bit string length limit in GDI on NT and a limit of
// 8192 characters on Windows 95.
maxLenText = IsNT() ? 65535 : 8192;

View File

@ -5,8 +5,8 @@
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2, 2, 5, 0
PRODUCTVERSION 2, 2, 5, 0
FILEVERSION 2, 2, 7, 0
PRODUCTVERSION 2, 2, 7, 0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Neil Hodgson neilh@scintilla.org\0"
VALUE "FileDescription", "Scintilla.DLL - a Source Editing Component\0"
VALUE "FileVersion", "2.25\0"
VALUE "FileVersion", "2.27\0"
VALUE "InternalName", "Scintilla\0"
VALUE "LegalCopyright", "Copyright 1998-2011 by Neil Hodgson\0"
VALUE "OriginalFilename", "Scintilla.DLL\0"
VALUE "ProductName", "Scintilla\0"
VALUE "ProductVersion", "2.25\0"
VALUE "ProductVersion", "2.27\0"
END
END
END

View File

@ -102,6 +102,29 @@ const TCHAR callClassName[] = TEXT("CallTip");
using namespace Scintilla;
#endif
// Take care of 32/64 bit pointers
#ifdef GetWindowLongPtr
static void *PointerFromWindow(HWND hWnd) {
return reinterpret_cast<void *>(::GetWindowLongPtr(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
::SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(ptr));
}
static void SetWindowID(HWND hWnd, int identifier) {
::SetWindowLongPtr(hWnd, GWLP_ID, identifier);
}
#else
static void *PointerFromWindow(HWND hWnd) {
return reinterpret_cast<void *>(::GetWindowLong(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
::SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(ptr));
}
static void SetWindowID(HWND hWnd, int identifier) {
::SetWindowLong(hWnd, GWL_ID, identifier);
}
#endif
class ScintillaWin; // Forward declaration for COM interface subobjects
typedef void VFunction(void);
@ -211,6 +234,7 @@ class ScintillaWin :
virtual bool ModifyScrollBars(int nMax, int nPage);
virtual void NotifyChange();
virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID();
virtual void NotifyParent(SCNotification scn);
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
@ -750,7 +774,7 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
Platform::IsKeyDown(VK_MENU));
}
break;
case WM_MBUTTONDOWN:
::SetFocus(MainHWND());
break;
@ -1282,6 +1306,10 @@ void ScintillaWin::NotifyFocus(bool focus) {
reinterpret_cast<LPARAM>(MainHWND()));
}
void ScintillaWin::SetCtrlID(int identifier) {
::SetWindowID(reinterpret_cast<HWND>(wMain.GetID()), identifier);
}
int ScintillaWin::GetCtrlID() {
return ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID()));
}
@ -2632,23 +2660,6 @@ BOOL ScintillaWin::DestroySystemCaret() {
return retval;
}
// Take care of 32/64 bit pointers
#ifdef GetWindowLongPtr
static void *PointerFromWindow(HWND hWnd) {
return reinterpret_cast<void *>(::GetWindowLongPtr(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
::SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(ptr));
}
#else
static void *PointerFromWindow(HWND hWnd) {
return reinterpret_cast<void *>(::GetWindowLong(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
::SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(ptr));
}
#endif
sptr_t PASCAL ScintillaWin::CTWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) {
// Find C++ object associated with window.