[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 - (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]; aRect = [self drawingRectForBounds: aRect];
mIsEditingOrSelecting = YES; mIsEditingOrSelecting = YES;

View File

@ -23,6 +23,7 @@
NSRect PRectangleToNSRect(Scintilla::PRectangle& rc); NSRect PRectangleToNSRect(Scintilla::PRectangle& rc);
Scintilla::PRectangle NSRectToPRectangle(NSRect& rc); Scintilla::PRectangle NSRectToPRectangle(NSRect& rc);
CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet);
@interface ScintillaContextMenu : NSMenu @interface ScintillaContextMenu : NSMenu
{ {
@ -47,6 +48,9 @@ private:
/** The text layout instance */ /** The text layout instance */
QuartzTextLayout* textLayout; QuartzTextLayout* textLayout;
int codePage;
int verticalDeviceResolution;
/** If the surface is a bitmap context, contains a reference to the bitmap data. */ /** If the surface is a bitmap context, contains a reference to the bitmap data. */
uint8_t* bitmapData; uint8_t* bitmapData;
/** If the surface is a bitmap context, stores the dimensions of the bitmap. */ /** If the surface is a bitmap context, stores the dimensions of the bitmap. */
@ -111,7 +115,7 @@ public:
void FlushCachedState(); void FlushCachedState();
void SetUnicodeMode(bool unicodeMode_); void SetUnicodeMode(bool unicodeMode_);
void SetDBCSMode(int codePage); void SetDBCSMode(int codePage_);
}; // SurfaceImpl class }; // SurfaceImpl class
} // Scintilla namespace } // Scintilla namespace

File diff suppressed because it is too large Load Diff

View File

@ -15,127 +15,89 @@
#include "QuartzTextStyle.h" #include "QuartzTextStyle.h"
class QuartzTextLayout class QuartzTextLayout
{ {
public: public:
/** Create a text layout for drawing on the specified context. */ /** 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 ); mString = NULL;
if (0 != err) mLine = NULL;
layout = NULL;
setContext(context); 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() ~QuartzTextLayout()
{ {
if (NULL != layout) if ( mString != NULL )
ATSUDisposeTextLayout( layout ); {
layout = NULL; CFRelease(mString);
mString = NULL;
if ( unicode_string != NULL ) }
{ if ( mLine != NULL )
delete[] unicode_string; {
unicode_string = NULL; CFRelease(mLine);
unicode_length = 0; mLine = NULL;
} }
}
/** 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 );
} }
inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r )
{ {
this->setText( buffer, byteLength, kCFStringEncodingUTF8 ); CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, kCFStringEncodingUTF8, false );
ATSUSetRunStyle( layout, r.getATSUStyle(), 0, unicode_length ); 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. */ /** Draw the text layout into the current CGContext at the specified position.
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.
* @param x The x axis position to draw the baseline in the current CGContext. * @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 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 )
void draw( float x, float y, bool flipTextYAxis = false )
{ {
if (NULL == layout || 0 == unicode_length) if (mLine == NULL)
return; return;
if ( flipTextYAxis )
{
CGContextSaveGState( gc );
CGContextScaleCTM( gc, 1.0, -1.0 );
y = -y;
}
OSStatus err; ::CGContextSetTextMatrix(gc, CGAffineTransformMakeScale(1.0, -1.0));
err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) );
if ( flipTextYAxis ) CGContextRestoreGState( gc ); // 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. float MeasureStringWidth()
* @param tag The control to set. {
* @param size The size of the parameter pointed to by value. if (mLine == NULL)
* @param value A pointer to the new value for the control. return 0.0f;
*/
void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) return ::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL);
{ }
ATSUSetLayoutControls( layout, 1, &tag, &size, &value );
CTLineRef getCTLine() {
return mLine;
} }
ATSUTextLayout getLayout() {
return layout;
}
inline CFIndex getLength() const { return unicode_length; }
inline void setContext (CGContextRef context) inline void setContext (CGContextRef context)
{ {
gc = context; gc = context;
if (NULL != layout)
setControl( kATSUCGContextTag, sizeof( gc ), &gc );
} }
private: private:
ATSUTextLayout layout;
UniChar* unicode_string;
int unicode_length;
CGContextRef gc; CGContextRef gc;
CFAttributedStringRef mString;
CTLineRef mLine;
}; };
#endif #endif

View File

@ -15,75 +15,63 @@ class QuartzTextStyle
public: public:
QuartzTextStyle() QuartzTextStyle()
{ {
ATSUCreateStyle( &style ); styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL);
} }
~QuartzTextStyle() ~QuartzTextStyle()
{ {
if ( style != NULL ) if (styleDict != NULL)
ATSUDisposeStyle( style ); {
style = NULL; CFRelease(styleDict);
styleDict = NULL;
}
} }
void setAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) CFMutableDictionaryRef getCTStyle() const
{ {
ATSUSetAttributes( style, 1, &tag, &size, &value ); return styleDict;
} }
void setAttribute( QuartzTextStyleAttribute& attribute ) void setCTStyleColor(CGColor* inColor )
{ {
setAttribute( attribute.getTag(), attribute.getSize(), attribute.getValuePtr() ); CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, inColor);
} }
void getAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value, ByteCount* actualSize ) float getAscent() const
{ {
ATSUGetAttribute( style, tag, size, value, actualSize ); return ::CTFontGetAscent(fontRef);
} }
template <class T> float getDescent() const
T getAttribute( ATSUAttributeTag tag ) {
{ return ::CTFontGetDescent(fontRef);
T value; }
ByteCount actualSize;
ATSUGetAttribute( style, tag, sizeof( T ), &value, &actualSize );
return value;
}
// TODO: Is calling this actually faster than calling setAttribute multiple times? float getLeading() const
void setAttributes( QuartzTextStyleAttribute* attributes[], int number ) {
{ return ::CTFontGetLeading(fontRef);
// 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 ) void setFontRef(CTFontRef inRef)
{ {
tags[i] = attributes[i]->getTag(); fontRef = inRef;
sizes[i] = attributes[i]->getSize();
values[i] = attributes[i]->getValuePtr();
}
ATSUSetAttributes( style, number, tags, sizes, values ); if (styleDict != NULL)
CFRelease(styleDict);
// Free the arrays that were allocated styleDict = CFDictionaryCreateMutable(NULL, 1, NULL, NULL);
delete[] tags;
delete[] sizes;
delete[] values;
}
void setFontFeature( ATSUFontFeatureType featureType, ATSUFontFeatureSelector selector ) CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef);
{ }
ATSUSetFontFeatures( style, 1, &featureType, &selector );
}
const ATSUStyle& getATSUStyle() const CTFontRef getFontRef()
{ {
return style; return fontRef;
} }
private: private:
ATSUStyle style; CFMutableDictionaryRef styleDict;
CTFontRef fontRef;
}; };
#endif #endif

View File

@ -12,131 +12,54 @@
#ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H #ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H
#define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H #define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H
class QuartzTextStyleAttribute class QuartzFont
{
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
{ {
public: public:
/** Create a font style from a name. */ /** 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' ); 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 CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman);
if( err != noErr || fontid == kATSUInvalidFontID ) assert(fontName != NULL);
::ATSUFindFontFromName( "Lucida Grande", 13, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid );
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 CTFontRef getFontID()
{
return sizeof( fontid );
}
ATSUAttributeValuePtr getValuePtr()
{
return &fontid;
}
ATSUAttributeTag getTag() const
{
return kATSUFontTag;
}
ATSUFontID getFontID() const
{ {
return fontid; return fontid;
} }
private: private:
ATSUFontID fontid; CTFontRef fontid;
}; };
#endif #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 scrollSpeed;
int scrollTicks; int scrollTicks;
protected: protected:
NSView* ContentView();
PRectangle GetClientRectangle(); PRectangle GetClientRectangle();
Point ConvertPoint(NSPoint point); Point ConvertPoint(NSPoint point);
virtual void Initialise(); virtual void Initialise();
virtual void Finalise(); virtual void Finalise();
virtual CaseFolder *CaseFolderForEncoding();
virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual std::string CaseMapString(const std::string &s, int caseMapping);
public: public:
NSView* ContentView();
ScintillaCocoa(NSView* view); ScintillaCocoa(NSView* view);
virtual ~ScintillaCocoa(); virtual ~ScintillaCocoa();
@ -160,6 +162,8 @@ public:
virtual bool CanPaste(); virtual bool CanPaste();
virtual void Paste(); virtual void Paste();
virtual void Paste(bool rectangular); virtual void Paste(bool rectangular);
void CTPaint(void* gc, NSRect rc);
void CallTipMouseDown(NSPoint pt);
virtual void CreateCallTipWindow(PRectangle rc); virtual void CreateCallTipWindow(PRectangle rc);
virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
virtual void ClaimSelection(); virtual void ClaimSelection();
@ -199,10 +203,7 @@ public:
virtual NSMenu* CreateContextMenu(NSEvent* event); virtual NSMenu* CreateContextMenu(NSEvent* event);
void HandleCommand(NSInteger command); void HandleCommand(NSInteger command);
// virtual OSStatus ActiveStateChanged(); virtual void ActiveStateChanged(bool isActive);
//
// virtual void CallTipClick();
}; };

View File

@ -32,24 +32,30 @@ NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Define keyboard shortcuts (equivalents) the Mac way. // 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_SCMD ( SCI_CMD | SCI_SHIFT)
#define SCI_META ( SCMOD_META )
#define SCI_SMETA ( SCI_META | SCI_SHIFT)
static const KeyToCommand macMapDefault[] = static const KeyToCommand macMapDefault[] =
{ {
// OS X specific
{SCK_DOWN, SCI_CMD, SCI_DOCUMENTEND}, {SCK_DOWN, SCI_CMD, SCI_DOCUMENTEND},
{SCK_UP, SCI_CMD, SCI_DOCUMENTSTART}, {SCK_UP, SCI_CMD, SCI_DOCUMENTSTART},
{SCK_LEFT, SCI_CMD, SCI_VCHOME}, {SCK_LEFT, SCI_CMD, SCI_VCHOME},
{SCK_LEFT, SCI_SCMD, SCI_VCHOMEEXTEND}, {SCK_LEFT, SCI_SCMD, SCI_VCHOMEEXTEND},
{SCK_RIGHT, SCI_CMD, SCI_LINEEND}, {SCK_RIGHT, SCI_CMD, SCI_LINEEND},
{SCK_RIGHT, SCI_SCMD, SCI_LINEENDEXTEND}, {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_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {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_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
{SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, {SCK_UP, SCI_META, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP}, {'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, {'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
@ -58,13 +64,15 @@ static const KeyToCommand macMapDefault[] =
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
{SCK_LEFT, SCI_ALT, SCI_WORDLEFT}, {SCK_LEFT, SCI_ALT, SCI_WORDLEFT},
{SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND}, {SCK_LEFT, SCI_META, SCI_WORDLEFT},
{SCK_LEFT, SCI_ASHIFT, SCI_WORDLEFTEXTEND}, {SCK_LEFT, SCI_SMETA, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
{SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, {SCK_RIGHT, SCI_META, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_ASHIFT, SCI_WORDRIGHTEXTEND}, {SCK_RIGHT, SCI_SMETA, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT}, {'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
{'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, {'\\', SCI_CTRL, SCI_WORDPARTRIGHT},
@ -253,28 +261,167 @@ void ScintillaCocoa::Finalise()
ScintillaBase::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. * 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) std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping)
{ {
NSString* textToConvert = [NSString stringWithUTF8String: s.c_str()]; CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(),
std::string result; vs.styles[STYLE_DEFAULT].characterSet);
CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(s.c_str()),
s.length(), encoding, false);
NSString *sMapped;
switch (caseMapping) switch (caseMapping)
{ {
case cmUpper: case cmUpper:
result = [[textToConvert uppercaseString] UTF8String]; sMapped = [(NSString *)cfsVal uppercaseString];
break; break;
case cmLower: case cmLower:
result = [[textToConvert lowercaseString] UTF8String]; sMapped = [(NSString *)cfsVal lowercaseString];
break; break;
default: 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; 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); return reinterpret_cast<sptr_t>(this);
case SCI_GRABFOCUS: case SCI_GRABFOCUS:
// TODO: implement it [[ContentView() window] makeFirstResponder:ContentView()];
break;
break; break;
case WM_UNICHAR: case WM_UNICHAR:
@ -396,7 +545,7 @@ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPar
return 0; return 0;
default: default:
unsigned int r = ScintillaBase::WndProc(iMessage, wParam, lParam); sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam);
return r; return r;
} }
@ -545,76 +694,97 @@ void ScintillaCocoa::Paste(bool forceRectangular)
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) void ScintillaCocoa::CTPaint(void* gc, NSRect rc) {
{ Surface *surfaceWindow = Surface::Allocate();
/* if (surfaceWindow) {
// create a calltip window surfaceWindow->Init(gc, wMain.GetID());
if (!ct.wCallTip.Created()) { surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage);
WindowClass windowClass = kHelpWindowClass; surfaceWindow->SetDBCSMode(ct.codePage);
WindowAttributes attributes = kWindowNoAttributes; ct.PaintCT(surfaceWindow);
Rect contentBounds; surfaceWindow->Release();
WindowRef outWindow; delete surfaceWindow;
}
// 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);
}
*/
} }
@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) void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled)
{ {
@ -1178,7 +1348,7 @@ void ScintillaCocoa::NotifyParent(SCNotification scn)
if (notifyProc != NULL) if (notifyProc != NULL)
{ {
scn.nmhdr.hwndFrom = (void*) this; 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); 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? bool consumed = false; // Consumed as command?
// Signal command as control + alt. This leaves us without command + control and command + alt // Signal Control as SCMOD_META
// but that's what we get when we have a modifier key more than other platforms. int modifierKeys =
if (KeyDown(key, shift, control || command, alt || command, &consumed)) (shift ? SCI_SHIFT : 0) |
(command ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0) |
(control ? SCI_META : 0);
if (KeyDownWithModifiers(key, modifierKeys, &consumed))
handled = true; handled = true;
if (consumed) if (consumed)
handled = true; handled = true;
@ -1375,9 +1549,9 @@ void ScintillaCocoa::MouseDown(NSEvent* event)
NSTimeInterval time = [event timestamp]; NSTimeInterval time = [event timestamp];
bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; bool command = ([event modifierFlags] & NSCommandKeyMask) != 0;
bool shift = ([event modifierFlags] & NSShiftKeyMask) != 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() void ScintillaCocoa::ActiveStateChanged(bool isActive)
//{ {
// // If the window is being deactivated, lose the focus and turn off the ticking // If the window is being deactivated, lose the focus and turn off the ticking
// if ( ! this->IsActive() ) { if (!isActive) {
// DropCaret(); DropCaret();
// //SetFocusState( false ); //SetFocusState( false );
// SetTicking( false ); SetTicking( false );
// } else { } else {
// ShowCaretAtCurrentPosition(); ShowCaretAtCurrentPosition();
// } }
// return noErr; }
//}
//
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -936,6 +936,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
@ -954,6 +955,7 @@
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "@executable_path/../Frameworks"; INSTALL_PATH = "@executable_path/../Frameworks";
PRODUCT_NAME = Scintilla; PRODUCT_NAME = Scintilla;
SDKROOT = macosx10.6;
WRAPPER_EXTENSION = framework; WRAPPER_EXTENSION = framework;
}; };
name = Debug; name = Debug;
@ -962,6 +964,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
@ -976,6 +979,7 @@
INFOPLIST_FILE = Info.plist; INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "@executable_path/../Frameworks"; INSTALL_PATH = "@executable_path/../Frameworks";
PRODUCT_NAME = Scintilla; PRODUCT_NAME = Scintilla;
SDKROOT = macosx10.6;
WRAPPER_EXTENSION = framework; WRAPPER_EXTENSION = framework;
}; };
name = Release; 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; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
"\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"",
);
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
@ -311,11 +309,9 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = "$(inherited)";
"$(inherited)",
"\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"",
);
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch;
@ -344,7 +340,7 @@
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = ""; OTHER_LDFLAGS = "";
PREBINDING = NO; PREBINDING = NO;
SDKROOT = macosx10.5; SDKROOT = macosx10.6;
}; };
name = Debug; name = Debug;
}; };
@ -357,7 +353,7 @@
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_LDFLAGS = ""; OTHER_LDFLAGS = "";
PREBINDING = NO; PREBINDING = NO;
SDKROOT = macosx10.5; SDKROOT = macosx10.6;
}; };
name = Release; name = Release;
}; };

View File

@ -127,6 +127,8 @@ extern NSString *SCIUpdateUINotification;
- (void) setLexerProperty: (NSString*) name value: (NSString*) value; - (void) setLexerProperty: (NSString*) name value: (NSString*) value;
- (NSString*) getLexerProperty: (NSString*) name; - (NSString*) getLexerProperty: (NSString*) name;
- (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback;
- (void) setInfoBar: (NSView <InfoBarCommunicator>*) aView top: (BOOL) top; - (void) setInfoBar: (NSView <InfoBarCommunicator>*) aView top: (BOOL) top;
- (void) setStatusText: (NSString*) text; - (void) setStatusText: (NSString*) text;

View File

@ -114,7 +114,6 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI";
[super resetCursorRects]; [super resetCursorRects];
// We only have one cursor rect: our bounds. // We only have one cursor rect: our bounds.
NSRect bounds = [self bounds];
[self addCursorRect: [self bounds] cursor: mCurrentCursor]; [self addCursorRect: [self bounds] cursor: mCurrentCursor];
[mCurrentCursor setOnMouseEntered: YES]; [mCurrentCursor setOnMouseEntered: YES];
} }
@ -239,9 +238,15 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI";
*/ */
- (void) insertText: (id) aString - (void) insertText: (id) aString
{ {
// Remove any previously marked text first. // Remove any previously marked text first.
[self removeMarkedText]; [self removeMarkedText];
mOwner.backend->InsertText((NSString*) aString); 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) // 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. // 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]; int currentPosition = [mOwner getGeneralProperty: SCI_GETCURRENTPOS parameter: 0];
// Replace marked text if there is one. // Replace marked text if there is one.
@ -363,7 +373,8 @@ NSString *SCIUpdateUINotification = @"SCIUpdateUI";
*/ */
- (void) keyDown: (NSEvent *) theEvent - (void) keyDown: (NSEvent *) theEvent
{ {
mOwner.backend->KeyboardInput(theEvent); if (mMarkedTextRange.length == 0)
mOwner.backend->KeyboardInput(theEvent);
NSArray* events = [NSArray arrayWithObject: theEvent]; NSArray* events = [NSArray arrayWithObject: theEvent];
[self interpretKeyEvents: events]; [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 type The type of the notification.
* @param message Carries the new status message if the type is a status message change. * @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]; [self setGeneralProperty: SCI_SETZOOM value: zoom];
break; 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. // Parent notification. Details are passed as SCNotification structure.
SCNotification* scn = reinterpret_cast<SCNotification*>(lParam); 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) switch (scn->nmhdr.code)
{ {
case SCN_MARGINCLICK: 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 // Setup a special indicator used in the editor to provide visual feedback for
// input composition, depending on language, keyboard etc. // 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_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]; [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; 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 - (void) viewDidMoveToWindow
{ {
[super 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) setHorizontalScrollRange: (int) range page: (int) page
{ {
BOOL result = NO; BOOL result = NO;
BOOL hideScroller = page >= range; BOOL hideScroller = (page >= range) ||
(mBackend->WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE);
if ([mHorizontalScroller isHidden] != hideScroller) if ([mHorizontalScroller isHidden] != hideScroller)
{ {
@ -1363,6 +1401,17 @@ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wPa
return [NSString stringWithUTF8String: result]; return [NSString stringWithUTF8String: result];
} }
//--------------------------------------------------------------------------------------------------
/**
* Sets the notification callback
*/
- (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback
{
mBackend->RegisterNotifyCallback(windowid, callback);
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/** /**

View File

@ -112,9 +112,8 @@
</p> </p>
<p> <p>
The <a href="http://astyle.sourceforge.net/">AStyle</a> formatting The <a href="http://astyle.sourceforge.net/">AStyle</a> formatting
program with a '-tapO' argument formats code in much the right way although program with '-taOHUKk3 -M8' arguments formats code in much the right way although
there are a few bugs in AStyle. The scite/scripts/Fixer.py script will run AStyle there are a few bugs in AStyle.
over a C++ source file and fix up some of those bugs.
</p> </p>
<h3> <h3>
Language features Language features
@ -123,17 +122,16 @@
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. compilers on diverse platforms with high performance and low resource usage.
Scintilla has stricter portability requirements to SciTE as it may be ported to 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 low capability platforms.
SciTE will be.
</p> </p>
<p> <p>
To achieve portability, only a subset of C++ features are used. Exceptions are To achieve portability, only a subset of C++ features are used.
not available on some platforms such as Windows CE so exceptions are not used Exceptions and templates may be used but, since Scintilla can be used from C as well as
and thus the standard C++ library can not be used. C++, exceptions may not be thrown out of Scintilla and all exceptions should be caught
Template support differs between compilers so is not used in Scintilla but there before returning from Scintilla.
are some simple uses in SciTE.
Run-time type information adds to memory use so is turned off. Run-time type information adds to memory use so is turned off.
Name spaces are not used. A 'Scintilla' name spaces is optionally used based on the SCI_NAMESPACE
definition. This helps with name clashes on OS X.
</p> </p>
<p> <p>
The goto statement is not used because of bad memories from my first job The goto statement is not used because of bad memories from my first job
@ -176,9 +174,9 @@
Allocation Allocation
</h3> </h3>
<p> <p>
As exceptions are not used, memory exhaustion can occur. Memory exhaustion can occur in many Scintilla methods.
This should be checked for and handled but there is quite a lot of Scintilla and This should be checked for and handled but once it has happened, it is very difficult to do
SciTE code that doesn't yet. 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 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 worry about memory exhaustion but then require that buffer lengths are
respected. respected.

View File

@ -79,7 +79,7 @@
<h1>Scintilla Documentation</h1> <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 <p>There is <a class="jump" href="Design.html">an overview of the internal design of
Scintilla</a>.<br /> Scintilla</a>.<br />
@ -625,10 +625,9 @@ struct Sci_TextRange {
</tbody> </tbody>
</table> </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 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 search range before the start.</p>
from a lower position to a higher position, even if the search range is backwards.</p>
<p>In a regular expression, special characters interpreted are:</p> <p>In a regular expression, special characters interpreted are:</p>
@ -722,6 +721,8 @@ struct Sci_TextRange {
</tbody> </tbody>
</table> </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" <p><b id="SCI_FINDTEXT">SCI_FINDTEXT(int searchFlags, <a class="jump"
href="#Sci_TextToFind">Sci_TextToFind</a> *ttf)</b><br /> 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. 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 <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 <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 to search. You can search backwards by
setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>. If <code>SCFIND_REGEXP</code> setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>.
is included, the search is always forwards (even if <code>chrg.cpMax</code> is less than <code>chrg.cpMin</code>).
Set the <code>lpstrText</code> member of <code>Sci_TextToFind</code> to point at a zero terminated 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> 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> 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 <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 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 the <a class="jump" href="#searchFlags"><code>searchFlags</code></a>. </p>
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>
<p>The return value is -1 if nothing is found, otherwise the return value is the start position <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 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_GETSELECTIONSTART">SCI_GETSELECTIONSTART</a><br />
<a class="message" href="#SCI_SETSELECTIONEND">SCI_SETSELECTIONEND(int position)</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_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_SELECTALL">SCI_SELECTALL</a><br />
<a class="message" href="#SCI_LINEFROMPOSITION">SCI_LINEFROMPOSITION(int position)</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 /> <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_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_TEXTHEIGHT">SCI_TEXTHEIGHT(int line)</a><br />
<a class="message" href="#SCI_CHOOSECARETX">SCI_CHOOSECARETX</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> </code>
<p><b id="SCI_GETTEXTLENGTH">SCI_GETTEXTLENGTH</b><br /> <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 current position or the anchor position. <code>SCI_GETSELECTIONEND</code> returns the larger of
the two values.</p> 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 /> <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> 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. 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> 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> <h2 id="MultipleSelectionAndVirtualSpace">Multiple Selection and Virtual Space</h2>
<code> <code>
@ -1549,7 +1563,8 @@ struct Sci_TextToFind {
<p> <p>
<b id="SCI_SETMULTIPLESELECTION">SCI_SETMULTIPLESELECTION(bool multipleSelection)</b><br /> <b id="SCI_SETMULTIPLESELECTION">SCI_SETMULTIPLESELECTION(bool multipleSelection)</b><br />
<b id="SCI_GETMULTIPLESELECTION">SCI_GETMULTIPLESELECTION</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> <p>
<b id="SCI_SETADDITIONALSELECTIONTYPING">SCI_SETADDITIONALSELECTIONTYPING(bool additionalSelectionTyping)</b><br /> <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_MARGINTEXTCLEARALL">SCI_MARGINTEXTCLEARALL</a><br />
<a class="message" href="#SCI_MARGINSETSTYLEOFFSET">SCI_MARGINSETSTYLEOFFSET(int style)</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_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> </code>
<p><b id="SCI_SETMARGINTYPEN">SCI_SETMARGINTYPEN(int margin, int iType)</b><br /> <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> 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. or <code>SCI_MARGINSETSTYLES</code> has the offset added before looking up the style.
</p> </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> <h2 id="Annotations">Annotations</h2>
@ -3089,6 +3115,8 @@ struct Sci_TextToFind {
<code><a class="message" href="#SCI_BRACEHIGHLIGHT">SCI_BRACEHIGHLIGHT(int pos1, int <code><a class="message" href="#SCI_BRACEHIGHLIGHT">SCI_BRACEHIGHLIGHT(int pos1, int
pos2)</a><br /> pos2)</a><br />
<a class="message" href="#SCI_BRACEBADLIGHT">SCI_BRACEBADLIGHT(int pos1)</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 <a class="message" href="#SCI_BRACEMATCH">SCI_BRACEMATCH(int position, int
maxReStyle)</a><br /> maxReStyle)</a><br />
</code> </code>
@ -3107,6 +3135,12 @@ struct Sci_TextToFind {
that is unmatched. Using a position of <code>INVALID_POSITION</code> (-1) removes the that is unmatched. Using a position of <code>INVALID_POSITION</code> (-1) removes the
highlight.</p> 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 /> <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 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 '(', ')', '[', <code>pos</code>, the position of one brace. The brace characters handled are '(', ')', '[',
@ -3275,6 +3309,9 @@ struct Sci_TextToFind {
colour)</a><br /> colour)</a><br />
<a class="message" href="#SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int <a class="message" href="#SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int
colour)</a><br /> 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 <a class="message" href="#SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int
alpha)</a><br /> alpha)</a><br />
<a class="message" href="#SCI_MARKERADD">SCI_MARKERADD(int line, int markerNumber)</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 /> href="#colour">colour</a>)</b><br />
<b id="SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int <a class="jump" <b id="SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int <a class="jump"
href="#colour">colour</a>)</b><br /> 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" <p><b id="SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int <a class="jump"
href="#alpha">alpha</a>)</b><br /> href="#alpha">alpha</a>)</b><br />
When markers are drawn in the content area, either because there is no margin for them or 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_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_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_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_INDICSETUNDER">SCI_INDICSETUNDER(int indicatorNumber, bool under)</a><br />
<a class="message" href="#SCI_INDICGETUNDER">SCI_INDICGETUNDER(int indicatorNumber)</a><br /> <a class="message" href="#SCI_INDICGETUNDER">SCI_INDICGETUNDER(int indicatorNumber)</a><br />
</code> </code>
@ -3584,7 +3628,7 @@ struct Sci_TextToFind {
<td align="center">1</td> <td align="center">1</td>
<td>A squiggly underline.</td> <td>A squiggly underline. Requires 3 pixels of descender space.</td>
</tr> </tr>
<tr> <tr>
@ -3633,11 +3677,49 @@ struct Sci_TextToFind {
<td align="center">7</td> <td align="center">7</td>
<td>A rectangle with rounded corners around the text using translucent drawing with the <td>A rectangle with rounded corners around the text using translucent drawing with the
interior more transparent than the border. You can use interior usually more transparent than the border. You can use
<a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> <a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and
to control the alpha transparency value. The default alpha value is 30. <a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a>
</td> to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour.</td>
</tr> </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> </tbody>
</table> </table>
@ -3657,7 +3739,14 @@ struct Sci_TextToFind {
<p><b id="SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</b><br /> <p><b id="SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</b><br />
<b id="SCI_INDICGETALPHA">SCI_INDICGETALPHA(int indicatorNumber)</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 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). 0 (completely transparent) to 255 (no transparency).
</p> </p>
@ -3677,8 +3766,8 @@ struct Sci_TextToFind {
<b id="SCI_SETINDICATORCURRENT">SCI_SETINDICATORCURRENT(int indicator)</b><br /> <b id="SCI_SETINDICATORCURRENT">SCI_SETINDICATORCURRENT(int indicator)</b><br />
<b id="SCI_GETINDICATORCURRENT">SCI_GETINDICATORCURRENT</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 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_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE(int position, int fillLength)</a> and
<a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE</a>. <a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE(int position, int clearLength)</a>.
</p> </p>
<p> <p>
@ -4302,6 +4391,12 @@ struct Sci_TextToFind {
<td><code>SCI_VERTICALCENTRECARET</code></td> <td><code>SCI_VERTICALCENTRECARET</code></td>
</tr> </tr>
<tr>
<td><code>SCI_MOVESELECTEDLINESUP</code></td>
<td><code>SCI_MOVESELECTEDLINESDOWN</code></td>
</tr>
</tbody> </tbody>
</table> </table>
@ -4360,7 +4455,10 @@ struct Sci_TextToFind {
<code>SCK_WIN</code>.</p> <code>SCK_WIN</code>.</p>
<p>The modifiers are a combination of zero or more of <code>SCMOD_ALT</code>, <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> 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" <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 constructing the system header information for each document. This is
invoked with the <code>SCI_PRIVATELEXERCALL</code> API.</p> 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> <h4>IDocument</h4>
@ -5677,31 +5780,38 @@ struct NotifyHeader { // This matches the Win32 NMHDR structure
}; };
struct SCNotification { struct SCNotification {
struct NotifyHeader nmhdr; struct Sci_NotifyHeader nmhdr;
int position; int position;
// SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_DWELLSTART, /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
// SCN_DWELLEND, SCN_CALLTIPCLICK, /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
// SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
int ch; // SCN_CHARADDED, SCN_KEY /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
int modifiers; /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
// SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK
int modificationType; // SCN_MODIFIED int ch; /* SCN_CHARADDED, SCN_KEY */
const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION int modifiers;
int length; // SCN_MODIFIED /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
int linesAdded; // SCN_MODIFIED /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
int message; // SCN_MACRORECORD
uptr_t wParam; // SCN_MACRORECORD int modificationType; /* SCN_MODIFIED */
sptr_t lParam; // SCN_MACRORECORD const char *text;
int line; // SCN_MODIFIED, SCN_DOUBLECLICK /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
int foldLevelNow; // SCN_MODIFIED
int foldLevelPrev; // SCN_MODIFIED int length; /* SCN_MODIFIED */
int margin; // SCN_MARGINCLICK int linesAdded; /* SCN_MODIFIED */
int listType; // SCN_USERLISTSELECTION, SCN_AUTOCSELECTION int message; /* SCN_MACRORECORD */
int x; // SCN_DWELLSTART, SCN_DWELLEND uptr_t wParam; /* SCN_MACRORECORD */
int y; // SCN_DWELLSTART, SCN_DWELLEND sptr_t lParam; /* SCN_MACRORECORD */
int token; // SCN_MODIFIED with SC_MOD_CONTAINER int line; /* SCN_MODIFIED */
int annotationLinesAdded; // SC_MOD_CHANGEANNOTATION int foldLevelNow; /* SCN_MODIFIED */
int updated; // SCN_UPDATEUI 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> </pre>
@ -5737,11 +5847,12 @@ struct SCNotification {
</code> </code>
<p>The following <code>SCI_*</code> messages are associated with these notifications:</p> <p>The following <code>SCI_*</code> messages are associated with these notifications:</p>
<code><a class="message" href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int <code><a class="message" href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int eventMask)</a><br />
eventMask)</a><br />
<a class="message" href="#SCI_GETMODEVENTMASK">SCI_GETMODEVENTMASK</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_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> </code>
<p>The following additional notifications are sent using the <code>WM_COMMAND</code> message on <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 /> <a class="message" href="#SCEN_KILLFOCUS">SCEN_KILLFOCUS</a><br />
</code> </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 /> <p><b id="SCN_STYLENEEDED">SCN_STYLENEEDED</b><br />
If you used <code><a class="message" If you used <code><a class="message"
href="#SCI_SETLEXER">SCI_SETLEXER</a>(SCLEX_CONTAINER)</code> to make the container act as the 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 /> <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 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 /> <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. 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. 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"> <table cellpadding="1" cellspacing="2" border="0" summary="Modify notification type flags">
<tbody> <tbody>
<tr> <tr>
@ -6328,7 +6452,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<tbody valign="top"> <tbody valign="top">
<tr> <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 <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 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> <td align="left">The text of the selection.</td>
</tr> </tr>
<tr>
<td align="left"><code>position</code></td>
<td align="left">The position the list was displayed at.</td>
</tr>
</tbody> </tbody>
</table> </table>
<br /> <br />
<br />
<p><b id="SCN_URIDROPPED">SCN_URIDROPPED</b><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> </tbody>
</table> </table>
<br /> <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 /> <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 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 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"> <tbody valign="top">
<tr> <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> <td align="left">The start position of the word being completed.</td>
</tr> </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 /> <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 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 notifications for this instance.
the source of each notification to be found. The value should be small, preferrably less than 16 bits, This is equivalent to <a class="message" href="#SCI_SETIDENTIFIER">SCI_SETIDENTIFIER</a>.</p>
rather than a pointer as some of the functions will only transmit 16 or 32 bits.</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 /> <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> 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"> <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr> <tr>
<td> <td>
<font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.zip?download"> <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla227.zip?download">
Windows</a>&nbsp;&nbsp; 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; GTK+/Linux</a>&nbsp;&nbsp;
</font> </font>
</td> </td>
@ -41,7 +41,7 @@
containing very few restrictions. containing very few restrictions.
</p> </p>
<h3> <h3>
Release 2.25 Release 2.27
</h3> </h3>
<h4> <h4>
Source Code Source Code
@ -49,8 +49,8 @@
The source code package contains all of the source code for Scintilla but no binary The source code package contains all of the source code for Scintilla but no binary
executable code and is available in executable code and is available in
<ul> <ul>
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla225.zip?download">zip format</a> (1200K) commonly used on Windows</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/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.tgz?download">tgz format</a> (1080K) commonly used on Linux and compatible operating systems</li>
</ul> </ul>
Instructions for building on both Windows and Linux are included in the readme file. Instructions for building on both Windows and Linux are included in the readme file.
<h4> <h4>

View File

@ -368,6 +368,16 @@
</tr><tr> </tr><tr>
<td>Dariusz Knociński</td> <td>Dariusz Knociński</td>
<td>Ben Fisher</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> </tr>
</table> </table>
<p> <p>
@ -379,6 +389,251 @@
Icons</a> Copyright(C) 1998 by Dean S. Jones<br /> Icons</a> Copyright(C) 1998 by Dean S. Jones<br />
</li> </li>
</ul> </ul>
<h3>
<a href="http://prdownloads.sourceforge.net/scintilla/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> <h3>
<a href="http://prdownloads.sourceforge.net/scintilla/scite225.zip?download">Release 2.25</a> <a href="http://prdownloads.sourceforge.net/scintilla/scite225.zip?download">Release 2.25</a>
</h3> </h3>

View File

@ -28,6 +28,14 @@
<h3> <h3>
Ports and Bindings of Scintilla Ports and Bindings of Scintilla
</h3> </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> <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> <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. 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 is a Python binding for gtk1.x scintilla that uses
gtkscintilla instead of the default GTK class. gtkscintilla instead of the default GTK class.
</p> </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> <p>
<a href="http://scintilla.cvs.sourceforge.net/viewvc/scintilla/scintillactrl/">ScintillaCtrl</a> <a href="http://scintilla.cvs.sourceforge.net/viewvc/scintilla/scintillactrl/">ScintillaCtrl</a>
is an unmaintained ActiveX control wrapper for Scintilla. is an unmaintained ActiveX control wrapper for Scintilla.
@ -112,7 +115,7 @@
Projects using Scintilla Projects using Scintilla
</h3> </h3>
<p> <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. is an IDE for Assembly programming similar to Visual Studio 6.0.
</p> </p>
<p> <p>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description" <meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20110321" /> <meta name="Date.Modified" content="20110620" />
<style type="text/css"> <style type="text/css">
#versionlist { #versionlist {
margin: 0; margin: 0;
@ -55,8 +55,8 @@
GTK+</font> GTK+</font>
</td> </td>
<td width="40%" align="right"> <td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 2.25<br /> <font color="#FFCC99" size="3"> Release version 2.27<br />
Site last modified March 21 2011</font> Site last modified June 20 2011</font>
</td> </td>
<td width="20%"> <td width="20%">
&nbsp; &nbsp;
@ -71,6 +71,8 @@
</tr> </tr>
</table> </table>
<ul id="versionlist"> <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.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.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> <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 allowing the use of proportional fonts, bold and italics, multiple foreground and background
colours and multiple fonts. colours and multiple fonts.
</p> </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> <p>
<a href="http://www.scintilla.org/SciTE.html">SciTE</a> is a SCIntilla based Text Editor. Originally built to <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 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> <a href="http://www.scintilla.org/Icons.html">Icons that can be used with Scintilla.</a>
</p> </p>
<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 Questions and comments about Scintilla should be directed to the
<a href="http://groups.google.com/group/scintilla-interest">scintilla-interest</a> <a href="http://groups.google.com/group/scintilla-interest">scintilla-interest</a>
mailing list, mailing list,

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -301,8 +301,11 @@ public:
FontID GetID() { return fid; } FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release // Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; } void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface; friend class Surface;
friend class SurfaceImpl; friend class SurfaceImpl;
}; };
/** /**
@ -411,8 +414,8 @@ public:
void SetTitle(const char *s); void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt); PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX #if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; }; void SetWindow(void *ref) { windowRef = ref; }
void SetControl(void *_control) { control = _control; }; void SetControl(void *_control) { control = _control; }
#endif #endif
private: private:
Cursor cursorLast; 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_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041 #define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042 #define SCI_MARKERSETBACK 2042
#define SCI_MARKERSETBACKSELECTED 2292
#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043 #define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044 #define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045 #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_HIDDEN 5
#define INDIC_BOX 6 #define INDIC_BOX 6
#define INDIC_ROUNDBOX 7 #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_MAX 31
#define INDIC_CONTAINER 8 #define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20 #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_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144 #define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145 #define SCI_GETSELECTIONEND 2145
#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146 #define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147 #define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0 #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_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350 #define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351 #define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352 #define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353 #define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355 #define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356 #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_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523 #define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524 #define SCI_INDICGETALPHA 2524
#define SCI_INDICSETOUTLINEALPHA 2558
#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525 #define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526 #define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527 #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_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537 #define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538 #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_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541 #define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542 #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_CHANGELEXERSTATE 2617
#define SCI_CONTRACTEDFOLDNEXT 2618 #define SCI_CONTRACTEDFOLDNEXT 2618
#define SCI_VERTICALCENTRECARET 2619 #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_STARTRECORD 3001
#define SCI_STOPRECORD 3002 #define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001 #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_CTRL 2
#define SCMOD_ALT 4 #define SCMOD_ALT 4
#define SCMOD_SUPER 8 #define SCMOD_SUPER 8
#define SCMOD_META 16
#define SCN_STYLENEEDED 2000 #define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001 #define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002 #define SCN_SAVEPOINTREACHED 2002
@ -964,11 +984,22 @@ struct Sci_NotifyHeader {
struct SCNotification { struct SCNotification {
struct Sci_NotifyHeader nmhdr; 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 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 */ 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 length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */ int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */ int message; /* SCN_MACRORECORD */
@ -982,7 +1013,7 @@ struct SCNotification {
int x; /* SCN_DWELLSTART, SCN_DWELLEND */ int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */ int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ 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 */ int updated; /* SCN_UPDATEUI */
}; };
@ -996,7 +1027,6 @@ struct SearchResultMarkings {
SearchResultMarking *_markings; SearchResultMarking *_markings;
}; };
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
} }
#endif #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. # Set the background colour used for a particular marker number.
fun void MarkerSetBack=2042(int markerNumber, colour back) 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. # 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) fun int MarkerAdd=2043(int line, int markerNumber)
@ -544,6 +550,10 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5 val INDIC_HIDDEN=5
val INDIC_BOX=6 val INDIC_BOX=6
val INDIC_ROUNDBOX=7 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_MAX=31
val INDIC_CONTAINER=8 val INDIC_CONTAINER=8
val INDIC0_MASK=0x20 val INDIC0_MASK=0x20
@ -791,6 +801,9 @@ set void SetSelectionEnd=2144(position pos,)
# Returns the position at the end of the selection. # Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,) 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. # Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,) set void SetPrintMagnification=2146(int magnification,)
@ -1440,9 +1453,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions. # Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2) 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. # Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,) 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. # Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,) 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 the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int 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 extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,) 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 the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,) 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 the annotation text for a line
set void AnnotationSetText=2540(int line, string text) set void AnnotationSetText=2540(int line, string text)
@ -2106,6 +2141,18 @@ fun int ContractedFoldNext=2618(int lineStart,)
# Centre current line in window. # Centre current line in window.
fun void VerticalCentreCaret=2619(,) 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. # Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,) fun void StartRecord=3001(,)
@ -2247,6 +2294,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2 val SCMOD_CTRL=2
val SCMOD_ALT=4 val SCMOD_ALT=4
val SCMOD_SUPER=8 val SCMOD_SUPER=8
val SCMOD_META=16
################################################ ################################################
# For SciLexer.h # For SciLexer.h
@ -3889,22 +3937,22 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void) evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems: # GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers) evt void Key=2005(int ch, int modifiers)
evt void DoubleClick=2006(void) evt void DoubleClick=2006(int modifiers, int position, int line)
evt void UpdateUI=2007(void) 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) 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 MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin) evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length) evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void) 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 URIDropped=2015(string text)
evt void DwellStart=2016(int position) evt void DwellStart=2016(int position, int x, int y)
evt void DwellEnd=2017(int position) evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void) evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position) evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position) evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(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 IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position) evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void) evt void AutoCCancelled=2025(void)

View File

@ -208,6 +208,7 @@ struct OptionsCPP {
bool identifiersAllowDollars; bool identifiersAllowDollars;
bool trackPreprocessor; bool trackPreprocessor;
bool updatePreprocessor; bool updatePreprocessor;
bool triplequotedStrings;
bool fold; bool fold;
bool foldSyntaxBased; bool foldSyntaxBased;
bool foldComment; bool foldComment;
@ -224,6 +225,7 @@ struct OptionsCPP {
identifiersAllowDollars = true; identifiersAllowDollars = true;
trackPreprocessor = true; trackPreprocessor = true;
updatePreprocessor = true; updatePreprocessor = true;
triplequotedStrings = false;
fold = false; fold = false;
foldSyntaxBased = true; foldSyntaxBased = true;
foldComment = false; foldComment = false;
@ -263,6 +265,9 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor, DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
"Set to 1 to update preprocessor definitions when #define found."); "Set to 1 to update preprocessor definitions when #define found.");
DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings,
"Set to 1 to enable highlighting of triple-quoted strings.");
DefineProperty("fold", &OptionsCPP::fold); DefineProperty("fold", &OptionsCPP::fold);
DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased, DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
@ -319,6 +324,7 @@ class LexerCPP : public ILexer {
OptionsCPP options; OptionsCPP options;
OptionSetCPP osCPP; OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators; SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
public: public:
LexerCPP(bool caseSensitive_) : LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_), caseSensitive(caseSensitive_),
@ -363,7 +369,9 @@ public:
static ILexer *LexerFactoryCPPInsensitive() { static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false); return new LexerCPP(false);
} }
static int MaskActive(int style) {
return style & ~activeFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens); void EvaluateTokens(std::vector<std::string> &tokens);
bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions); 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 { struct After {
int line; int line;
After(int line_) : line(line_) {} After(int line_) : line(line_) {}
bool operator() (PPDefinition &p) const { bool operator()(PPDefinition &p) const {
return p.line > line; 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; preprocessorDefinitions[itDef->key] = itDef->value;
} }
const int maskActivity = 0x3F;
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent); SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? 0x40 : 0; int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) { for (; sc.More(); sc.Forward()) {
@ -523,7 +530,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
lastWordWasUUID = false; lastWordWasUUID = false;
isIncludePreprocessor = false; isIncludePreprocessor = false;
if (preproc.IsInactive()) { if (preproc.IsInactive()) {
activitySet = 0x40; activitySet = activeFlag;
sc.SetState(sc.state | activitySet); sc.SetState(sc.state | activitySet);
} }
if (activitySet) { if (activitySet) {
@ -558,7 +565,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
const bool atLineEndBeforeSwitch = sc.atLineEnd; const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate. // Determine if the current state should terminate.
switch (sc.state & maskActivity) { switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR: case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT|activitySet); sc.SetState(SCE_C_DEFAULT|activitySet);
break; break;
@ -734,7 +741,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
break; break;
case SCE_C_TRIPLEVERBATIM: case SCE_C_TRIPLEVERBATIM:
if (sc.Match ("\"\"\"")) { if (sc.Match("\"\"\"")) {
while (sc.Match('"')) { while (sc.Match('"')) {
sc.Forward(); 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. // 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('@', '\"')) { if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM|activitySet); sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward(); sc.Forward();
} else if (sc.Match("\"\"\"")) { } else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet); sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
sc.Forward(2); sc.Forward(2);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { } 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') { if (sc.chPrev == 'R') {
sc.SetState(SCE_C_STRINGRAW|activitySet); sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")"; rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;;termPos++) { for (int termPos = sc.currentPos + 1;; termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '('); char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(') if (chTerminator == '(')
break; break;
@ -839,12 +846,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else if (sc.Match("else")) { } else if (sc.Match("else")) {
if (!preproc.CurrentIfTaken()) { if (!preproc.CurrentIfTaken()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) { } else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|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); bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) { if (ifGood) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} }
} else if (!preproc.IsInactive()) { } else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} }
} else if (sc.Match("endif")) { } else if (sc.Match("endif")) {
preproc.EndSection(); preproc.EndSection();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) { } else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) { 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 levelMinCurrent = levelCurrent;
int levelNext = levelCurrent; int levelNext = levelCurrent;
char chNext = styler[startPos]; char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos); int styleNext = MaskActive(styler.StyleAt(startPos));
int style = initStyle; int style = MaskActive(initStyle);
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) { for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style; int stylePrev = style;
style = styleNext; style = styleNext;
styleNext = styler.StyleAt(i + 1); styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) { if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) { 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, static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) { 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; char chAttr = SCE_HJ_WORD;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
if (wordIsNumber) if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER; chAttr = SCE_HJ_NUMBER;
else { } else if (keywords.InList(s)) {
char s[30 + 1]; chAttr = SCE_HJ_KEYWORD;
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;
} }
styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); 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) { static int StateForScript(script_type scriptLanguage) {
int Result; int Result;
switch (scriptLanguage) { switch (scriptLanguage) {
case eScriptJS: case eScriptJS:
Result = SCE_HJ_START; Result = SCE_HJ_START;
break; break;
case eScriptPython: case eScriptPython:
@ -754,8 +754,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (styler.Match(j, "end")) { } else if (styler.Match(j, "end")) {
levelCurrent--; levelCurrent--;
} }
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) { } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1; levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
} }
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) { } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
levelCurrent--; levelCurrent--;
@ -882,7 +882,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(state != SCE_HPHP_COMMENTLINE) && (state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') && (ch == '<') &&
(chNext == '?') && (chNext == '?') &&
!IsScriptCommentState(state) ) { !IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP); scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue; if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
@ -954,6 +955,36 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue; 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 // handle the start Django template code
else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) { else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
if (chNext == '%') if (chNext == '%')
@ -1024,7 +1055,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') && (ch == '!') &&
(StateToPrint != SCE_H_CDATA) && (StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) && (!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) { (!IsScriptCommentState(StateToPrint))) {
beforePreProc = state; beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint); styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) { if ((chNext == '-') && (chNext2 == '-')) {
@ -1154,7 +1185,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--; levelCurrent--;
} }
scriptLanguage = eScriptNone; scriptLanguage = beforeLanguage;
continue; continue;
} }
///////////////////////////////////// /////////////////////////////////////

View File

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

View File

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

View File

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

View File

@ -58,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators // Tests for BATCH Separators
static bool IsBSeparator(char ch) { static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') || return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')'); (ch == '\"') || (ch == '\'') || (ch == '/');
} }
static void ColouriseBatchLine( static void ColouriseBatchLine(
@ -854,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR); styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return; return;
} }
int varCount = 0;
while (i < lengthLine) { while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') { if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state); styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER; state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') { } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
styler.ColourTo(startLine + i, state); if (--varCount == 0) {
state = SCE_MAKE_DEFAULT; styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
} }
// skip identifier and target styling if this is a command line // 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 #endif
/* kwCDef, kwCTypeName only used for Cython */ /* 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; static const int indicatorWhitespace = 1;
@ -246,7 +246,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME; style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) { } else if (kwLast == kwDef) {
style = SCE_P_DEFNAME; style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) { } else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos; int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0'); unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') { while (ch != '\0') {
@ -277,11 +277,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport; kwLast = kwImport;
else if (0 == strcmp(s, "cdef")) else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef; kwLast = kwCDef;
else if (0 == strcmp(s, "cpdef"))
kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport")) else if (0 == strcmp(s, "cimport"))
kwLast = kwImport; kwLast = kwImport;
else if (kwLast != kwCDef) else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther; kwLast = kwOther;
} else if (kwLast != kwCDef) { } else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther; kwLast = kwOther;
} }
} }
@ -337,8 +339,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true; indentGood = true;
} }
// One cdef line, clear kwLast only at end of line // One cdef or cpdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) { if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther; kwLast = kwOther;
} }

View File

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

View File

@ -29,7 +29,7 @@ using namespace Scintilla;
#endif #endif
static inline bool IsAWordChar(const int ch) { 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) { 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") || if (styler.Match(j, "case") ||
styler.Match(j, "casex") || styler.Match(j, "casex") ||
styler.Match(j, "casez") || styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") || 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, "table") ||
styler.Match(j, "task") || styler.Match(j, "task") ||
styler.Match(j, "generate") || styler.Match(j, "fork") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
(styler.Match(j, "module") && foldAtModule) || (styler.Match(j, "module") && foldAtModule) ||
styler.Match(j, "begin")) { styler.Match(j, "begin")) {
levelNext++; levelNext++;
} else if (styler.Match(j, "endcase") || } else if (styler.Match(j, "endcase") ||
styler.Match(j, "endclass") ||
styler.Match(j, "endfunction") || styler.Match(j, "endfunction") ||
styler.Match(j, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") || styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") || styler.Match(j, "endgroup") ||
styler.Match(j, "endspecify") || styler.Match(j, "endpackage") ||
styler.Match(j, "endprimitive") || 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, "endmodule") && foldAtModule) ||
(styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) { (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
levelNext--; levelNext--;

View File

@ -119,7 +119,6 @@ inline bool iswordstart(int ch) {
inline bool isoperator(int ch) { inline bool isoperator(int ch) {
if (IsASCII(ch) && IsAlphaNumeric(ch)) if (IsASCII(ch) && IsAlphaNumeric(ch))
return false; return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' || 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) { void Set(int position, T value) {
Delete(position); 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)); states.push_back(State(position, value));
} }
} }
T ValueAt(int position) { T ValueAt(int position) {
if (!states.size()) if (states.empty())
return T(); return T();
if (position < states[0].position) if (position < states[0].position)
return T(); return T();

View File

@ -315,7 +315,6 @@ void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore,
// Draw the polygon // Draw the polygon
CGContextAddLines( gc, points, npts ); 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) // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only)
CGContextClosePath( gc ); CGContextClosePath( gc );
CGContextDrawPath( gc, kCGPathFillStroke ); 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) // 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 // 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. // 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 ) ); CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) );
CGContextDrawPath( gc, kCGPathFillStroke ); CGContextDrawPath( gc, kCGPathFillStroke );
} }
@ -407,8 +405,12 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
} }
void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { 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 ); // ::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 // Create a rectangle with semicircles at the corners
const int MAX_RADIUS = 4; 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 // Align the points in the middle of the pixels
// TODO: Should I include these +0.5 in the array creation code above?
for( int i = 0; i < 4*3; ++ i ) for( int i = 0; i < 4*3; ++ i )
{ {
CGPoint* c = (CGPoint*) corners; CGPoint* c = (CGPoint*) corners;
@ -1126,7 +1127,6 @@ public:
int GetSelection(); int GetSelection();
int Find(const char *prefix); int Find(const char *prefix);
void GetValue(int n, char *value, int len); void GetValue(int n, char *value, int len);
void Sort();
void RegisterImage(int type, const char *xpm_data); void RegisterImage(int type, const char *xpm_data);
void ClearRegisteredImages(); void ClearRegisteredImages();
void SetDoubleClickAction(CallBackAction action, void *data) { void SetDoubleClickAction(CallBackAction action, void *data) {
@ -1631,11 +1631,6 @@ void ListBoxImpl::GetValue(int n, char *value, int len) {
delete []text; delete []text;
} }
void ListBoxImpl::Sort() {
// TODO: Implement this
fprintf(stderr, "ListBox::Sort\n");
}
void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
xset.Add(type, 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() { ElapsedTime::ElapsedTime() {
struct timeval curTime; struct timeval curTime;
int retVal; int retVal;

View File

@ -29,7 +29,7 @@ ifeq ($(GCC_MAJOR),3)
ARCHFLAGS=-arch ppc -faltivec -mcpu=7400 -mtune=7400 -mpowerpc -mpowerpc-gfxopt ARCHFLAGS=-arch ppc -faltivec -mcpu=7400 -mtune=7400 -mpowerpc -mpowerpc-gfxopt
else else
ifndef NATIVE 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) ARCHFLAGS=-isysroot $(ARCH_BASE_FLAGS)
LINK_FLAGS=-Wl,-syslibroot,$(ARCH_BASE_FLAGS) LINK_FLAGS=-Wl,-syslibroot,$(ARCH_BASE_FLAGS)
DYN_FLAGS=$(LINK_FLAGS) -framework Carbon -bundle 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]; int ends[numEnds + 2];
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) && if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) { (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0) if (i > 0)
ends[maxEnd++] = i; ends[maxEnd++] = i;
ends[maxEnd++] = i+1; 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 { bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) { if (OneToOne()) {
return true; return true;

View File

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

View File

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

View File

@ -2,7 +2,7 @@
/** @file Document.cxx /** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line. ** 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. // The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h> #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) { int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length()); return Platform::Clamp(pos, 0, Length());
} }
@ -609,6 +713,55 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return false; 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) { void Document::ModifiedAt(int pos) {
if (endStyled > pos) if (endStyled > pos)
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. // the start position is at end of line or between line end characters.
lineRangeStart++; lineRangeStart++;
startPos = doc->LineStart(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 pos = -1;
int lenRet = 0; int lenRet = 0;
char searchEnd = s[*length - 1]; char searchEnd = s[*length - 1];
char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment; int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line); int startOfLine = doc->LineStart(line);
@ -1965,7 +2125,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = startPos; startOfLine = startPos;
} }
if (line == lineRangeEnd) { 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 continue; // Can't match end of line if end position before end of line
endOfLine = endPos; endOfLine = endPos;
} }
@ -1976,7 +2136,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = endPos; startOfLine = endPos;
} }
if (line == lineRangeStart) { 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 continue; // Can't match end of line if start position before end of line
endOfLine = startPos; endOfLine = startPos;
} }
@ -1987,7 +2147,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) { if (success) {
pos = search.bopat[0]; pos = search.bopat[0];
lenRet = search.eopat[0] - 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. // Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) { while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {

View File

@ -2,7 +2,7 @@
/** @file Document.h /** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line. ** 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. // The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H #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 { class CaseFolder {
public: public:
virtual ~CaseFolder() { virtual ~CaseFolder() {
@ -234,6 +275,7 @@ public:
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const; int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const; bool SCI_METHOD IsDBCSLeadByte(char ch) const;
int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document // Gateways to modifying document
void ModifiedAt(int pos); void ModifiedAt(int pos);
@ -299,6 +341,7 @@ public:
void ClearLevels(); void ClearLevels();
int GetLastChild(int lineParent, int level=-1); int GetLastChild(int lineParent, int level=-1);
int GetFoldParent(int line); int GetFoldParent(int line);
void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int topLine, int bottomLine);
void Indent(bool forwards); void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);

View File

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

View File

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

View File

@ -27,6 +27,17 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
y = 2 - y; y = 2 - y;
} }
surface->LineTo(rc.right, rc.top + y); // Finish the line 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) { } else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid); surface->MoveTo(rc.left, ymid);
int x = rc.left + 5; 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.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1); surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1); surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) { } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine; PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1; rcBox.top = rcLine.top + 1;
rcBox.left = rc.left; rcBox.left = rc.left;
rcBox.right = rc.right; 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 } else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid); surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid); surface->LineTo(rc.right, ymid);

View File

@ -20,7 +20,8 @@ public:
bool under; bool under;
ColourPair fore; ColourPair fore;
int fillAlpha; 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); void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
}; };

View File

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

View File

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

View File

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

View File

@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const; bool InLine(int offset, int line) const;
void SetLineStart(int line, int start); void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[], void SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight); char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[]); void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const; int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const; int EndLineStyle() const;
}; };
@ -117,16 +117,10 @@ public:
// Class to break a line of text into shorter runs at sensible places. // Class to break a line of text into shorter runs at sensible places.
class BreakFinder { 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; LineLayout *ll;
int lineStart; int lineStart;
int lineEnd; int lineEnd;
int posLineStart; int posLineStart;
bool utf8;
int nextBreak; int nextBreak;
int *selAndEdge; int *selAndEdge;
unsigned int saeSize; unsigned int saeSize;
@ -134,9 +128,16 @@ class BreakFinder {
unsigned int saeCurrentPos; unsigned int saeCurrentPos;
int saeNext; int saeNext;
int subBreak; int subBreak;
Document *pdoc;
void Insert(int val); void Insert(int val);
public: 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(); ~BreakFinder();
int First() const; int First() const;
int Next(); int Next();
@ -152,9 +153,9 @@ public:
~PositionCache(); ~PositionCache();
void Clear(); void Clear();
void SetSize(size_t size_); 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, 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) { 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) { switch (ch) {
case 'a': return '\a'; case 'a': return '\a';
case 'b': return '\b'; case 'b': return '\b';
@ -888,10 +888,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
return NOTFOUND; return NOTFOUND;
break; break;
case BOT: case BOT:
bopat[*ap++] = lp; bopat[static_cast<int>(*ap++)] = lp;
break; break;
case EOT: case EOT:
eopat[*ap++] = lp; eopat[static_cast<int>(*ap++)] = lp;
break; break;
case BOW: case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp))) if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))

View File

@ -21,7 +21,7 @@ using namespace Scintilla;
#endif #endif
// Find the first run at a position // Find the first run at a position
int RunStyles::RunFromPosition(int position) { int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position); int run = starts->PartitionFromPosition(position);
// Go to first element with this position // Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) { while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
@ -147,6 +147,8 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end); runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd); RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart); RemoveRunIfSameAsPrevious(runStart);
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return true; return true;
} else { } else {
return false; 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 #endif
class RunStyles { class RunStyles {
public: private:
Partitioning *starts; Partitioning *starts;
SplitVector<int> *styles; SplitVector<int> *styles;
int RunFromPosition(int position); int RunFromPosition(int position) const;
int SplitRun(int position); int SplitRun(int position);
void RemoveRun(int run); void RemoveRun(int run);
void RemoveRunIfEmpty(int run); void RemoveRunIfEmpty(int run);
@ -37,6 +37,10 @@ public:
void InsertSpace(int position, int insertLength); void InsertSpace(int position, int insertLength);
void DeleteAll(); void DeleteAll();
void DeleteRange(int position, int deleteLength); 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 #ifdef SCI_NAMESPACE

View File

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

View File

@ -16,14 +16,51 @@
using namespace Scintilla; using namespace Scintilla;
#endif #endif
Style::Style() { FontAlias::FontAlias() {
aliasOfDefaultFont = true; }
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), Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false); 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), Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0, 0, 0, 0,
false, false, false, false, caseMixed, true, true, false); false, false, false, false, caseMixed, true, true, false);
@ -42,11 +79,6 @@ Style::Style(const Style &source) {
} }
Style::~Style() { Style::~Style() {
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
} }
Style &Style::operator=(const Style &source) { 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_, void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
const char *fontName_, int characterSet_, const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_, bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_, bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) { bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_; fore.desired = fore_;
back.desired = back_; back.desired = back_;
characterSet = characterSet_; characterSet = characterSet_;
@ -87,79 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_; visible = visible_;
changeable = changeable_; changeable = changeable_;
hotspot = hotspot_; hotspot = hotspot_;
if (aliasOfDefaultFont) font.ClearFont();
font.SetID(0); FontMeasurements::Clear();
else
font.Release();
aliasOfDefaultFont = false;
sizeZoomed = 2;
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
} }
void Style::ClearTo(const Style &source) { void Style::ClearTo(const Style &source) {
Clear( Clear(
source.fore.desired, source.fore.desired,
source.back.desired, source.back.desired,
source.size, source.size,
source.fontName, source.fontName,
source.characterSet, source.characterSet,
source.bold, source.bold,
source.italic, source.italic,
source.eolFilled, source.eolFilled,
source.underline, source.underline,
source.caseForce, source.caseForce,
source.visible, source.visible,
source.changeable, source.changeable,
source.hotspot); source.hotspot);
} }
bool Style::EquivalentFontTo(const Style *other) const { void Style::Copy(Font &font_, const FontMeasurements &fm_) {
if (bold != other->bold || font.MakeAlias(font_);
italic != other->italic || #if PLAT_WX
size != other->size || font.SetAscent(fm_.ascent);
characterSet != other->characterSet) #endif
return false; (FontMeasurements &)(*this) = fm_;
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, ' ');
} }

View File

@ -12,18 +12,54 @@
namespace Scintilla { namespace Scintilla {
#endif #endif
/** struct FontSpecification {
*/ const char *fontName;
class Style {
public:
ColourPair fore;
ColourPair back;
bool aliasOfDefaultFont;
bool bold; bool bold;
bool italic; bool italic;
int size; int size;
const char *fontName;
int characterSet; 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 eolFilled;
bool underline; bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower}; enum ecaseForced {caseMixed, caseUpper, caseLower};
@ -32,14 +68,7 @@ public:
bool changeable; bool changeable;
bool hotspot; bool hotspot;
Font font; FontAlias font;
int sizeZoomed;
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
Style(); Style();
Style(const Style &source); Style(const Style &source);
@ -52,8 +81,7 @@ public:
bool underline_, ecaseForced caseForce_, bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_); bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source); void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const; void Copy(Font &font_, const FontMeasurements &fm_);
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
bool IsProtected() const { return !(changeable && visible);} bool IsProtected() const { return !(changeable && visible);}
}; };

View File

@ -72,11 +72,66 @@ const char *FontNames::Save(const char *name) {
return names[max-1]; 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() { ViewStyle::ViewStyle() {
Init(); Init();
} }
ViewStyle::ViewStyle(const ViewStyle &source) { ViewStyle::ViewStyle(const ViewStyle &source) {
frFirst = NULL;
Init(source.stylesSize); Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) { for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty]; styles[sty] = source.styles[sty];
@ -151,14 +206,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset; marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible; annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset; annotationStyleOffset = source.annotationStyleOffset;
braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
braceHighlightIndicator = source.braceHighlightIndicator;
braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
braceBadLightIndicator = source.braceBadLightIndicator;
} }
ViewStyle::~ViewStyle() { ViewStyle::~ViewStyle() {
delete []styles; delete []styles;
styles = NULL; styles = NULL;
delete frFirst;
frFirst = NULL;
} }
void ViewStyle::Init(size_t stylesSize_) { void ViewStyle::Init(size_t stylesSize_) {
frFirst = NULL;
stylesSize = 0; stylesSize = 0;
styles = NULL; styles = NULL;
AllocStyles(stylesSize_); AllocStyles(stylesSize_);
@ -257,6 +319,10 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0; marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN; annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0; annotationStyleOffset = 0;
braceHighlightIndicatorSet = false;
braceHighlightIndicator = 0;
braceBadLightIndicatorSet = false;
braceBadLightIndicator = 0;
} }
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@ -292,33 +358,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, 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) { void ViewStyle::Refresh(Surface &surface) {
delete frFirst;
frFirst = NULL;
selbar.desired = Platform::Chrome(); selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight(); selbarlight.desired = Platform::ChromeHighlight();
styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
maxAscent = styles[STYLE_DEFAULT].ascent; for (unsigned int i=0; i<stylesSize; i++) {
maxDescent = styles[STYLE_DEFAULT].descent; 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; someStylesProtected = false;
someStylesForceCase = false; someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) { for (unsigned int l=0; l<stylesSize; l++) {
if (i != STYLE_DEFAULT) { if (styles[l].IsProtected()) {
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()) {
someStylesProtected = true; someStylesProtected = true;
} }
if (styles[i].caseForce != Style::caseMixed) { if (styles[l].caseForce != Style::caseMixed) {
someStylesForceCase = true; someStylesForceCase = true;
} }
} }
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth; aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth; spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@ -363,10 +455,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() { void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
ColourDesired(0xff,0xff,0xff), ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT, SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false); false, false, false, false, Style::caseMixed, true, true, false);
} }
void ViewStyle::ClearStyles() { void ViewStyle::ClearStyles() {

View File

@ -39,6 +39,20 @@ public:
const char *Save(const char *name); 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 IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@ -48,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle { class ViewStyle {
public: public:
FontNames fontNames; FontNames fontNames;
FontRealised *frFirst;
size_t stylesSize; size_t stylesSize;
Style *styles; Style *styles;
LineMarker markers[MARKER_MAX + 1]; LineMarker markers[MARKER_MAX + 1];
@ -115,11 +130,16 @@ public:
int marginStyleOffset; int marginStyleOffset;
int annotationVisible; int annotationVisible;
int annotationStyleOffset; int annotationStyleOffset;
bool braceHighlightIndicatorSet;
int braceHighlightIndicator;
bool braceBadLightIndicatorSet;
int braceBadLightIndicator;
ViewStyle(); ViewStyle();
ViewStyle(const ViewStyle &source); ViewStyle(const ViewStyle &source);
~ViewStyle(); ~ViewStyle();
void Init(size_t stylesSize_=64); void Init(size_t stylesSize_=64);
void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want); void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface); void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew); void AllocStyles(size_t sizeNew);

View File

@ -1 +1 @@
225 227

View File

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

View File

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

View File

@ -102,6 +102,29 @@ const TCHAR callClassName[] = TEXT("CallTip");
using namespace Scintilla; using namespace Scintilla;
#endif #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 class ScintillaWin; // Forward declaration for COM interface subobjects
typedef void VFunction(void); typedef void VFunction(void);
@ -211,6 +234,7 @@ class ScintillaWin :
virtual bool ModifyScrollBars(int nMax, int nPage); virtual bool ModifyScrollBars(int nMax, int nPage);
virtual void NotifyChange(); virtual void NotifyChange();
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID(); virtual int GetCtrlID();
virtual void NotifyParent(SCNotification scn); virtual void NotifyParent(SCNotification scn);
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
@ -1282,6 +1306,10 @@ void ScintillaWin::NotifyFocus(bool focus) {
reinterpret_cast<LPARAM>(MainHWND())); reinterpret_cast<LPARAM>(MainHWND()));
} }
void ScintillaWin::SetCtrlID(int identifier) {
::SetWindowID(reinterpret_cast<HWND>(wMain.GetID()), identifier);
}
int ScintillaWin::GetCtrlID() { int ScintillaWin::GetCtrlID() {
return ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID())); return ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID()));
} }
@ -2632,23 +2660,6 @@ BOOL ScintillaWin::DestroySystemCaret() {
return retval; 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( sptr_t PASCAL ScintillaWin::CTWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) { HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) {
// Find C++ object associated with window. // Find C++ object associated with window.