SynEdit: refactor, all Lines.On* are now event-lists

git-svn-id: trunk@22662 -
This commit is contained in:
martin 2009-11-18 00:07:55 +00:00
parent d4adb75967
commit 18d49dd9cd
4 changed files with 180 additions and 75 deletions

View File

@ -59,6 +59,7 @@ interface
{ $DEFINE VerboseKeys}
{ $DEFINE VerboseSynEditInvalidate}
{ $DEFINE SYNDEBUGPRINT}
uses
{$IFDEF USE_UTF8BIDI_LCL}
@ -213,7 +214,7 @@ type
eoScrollPastEof, // Allows the cursor to go past the end of file marker
eoScrollPastEol, // Allows the cursor to go past the last character into the white space at the end of a line
eoShowScrollHint, // Shows a hint of the visible line numbers when scrolling vertically
eoShowSpecialChars, //TODO Shows the special Characters
eoShowSpecialChars, // Shows the special Characters
eoSmartTabDelete, //TODO similar to Smart Tabs, but when you delete characters
eoSmartTabs, // When tabbing, the cursor will go to the next non-white space character of the previous line
//eoSpecialLineDefaultFg, //TODO disables the foreground text color override when using the OnSpecialLineColor event
@ -1516,14 +1517,12 @@ begin
FCaret.Lines := FTheLinesView;
FInternalCaret.Lines := FTheLinesView;
TSynEditStringList(fLines).AddChangeHandler(senrLineCount,
{$IFDEF FPC}@{$ENDIF}LineCountChanged);
TSynEditStringList(fLines).AddChangeHandler(senrLineChange,
{$IFDEF FPC}@{$ENDIF}LineTextChanged);
with TSynEditStringList(fLines) do begin
OnChange := {$IFDEF FPC}@{$ENDIF}LinesChanged;
OnChanging := {$IFDEF FPC}@{$ENDIF}LinesChanging;
OnCleared := {$IFDEF FPC}@{$ENDIF}ListCleared;
AddChangeHandler(senrLineCount, {$IFDEF FPC}@{$ENDIF}LineCountChanged);
AddChangeHandler(senrLineChange, {$IFDEF FPC}@{$ENDIF}LineTextChanged);
AddNotifyHandler(senrBeginUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanging);
AddNotifyHandler(senrEndUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanged);
AddNotifyHandler(senrCleared, {$IFDEF FPC}@{$ENDIF}ListCleared);
end;
fFontDummy := TFont.Create;
@ -2266,7 +2265,7 @@ begin
// so we we fire the OnKeyPress here
if (ord(key[1])< %11000000) and (key[1]<>#0) and Assigned(OnKeyPress) then
OnKeyPress(Self, Key[1]);
{$IFDEF VerboseKeyboard}
{$IFDEF VerboseKeys}
DebugLn('TCustomSynEdit.UTF8KeyPress ',DbgSName(Self),' Key="',DbgStr(Key),'" UseUTF8=',dbgs(UseUTF8));
{$ENDIF}
CommandProcessor(ecChar, Key, nil);
@ -2287,7 +2286,7 @@ begin
// don't fire the event if key is to be ignored
if not (sfIgnoreNextChar in fStateFlags) then begin
Include(FStateFlags, sfHideCursor);
{$IFDEF VerboseKeyboard}
{$IFDEF VerboseKeys}
DebugLn('TCustomSynEdit.KeyPress ',DbgSName(Self),' Key="',DbgStr(Key),'" UseUTF8=',dbgs(UseUTF8));
{$ENDIF}
if Assigned(OnKeyPress) then OnKeyPress(Self, Key);
@ -3483,6 +3482,16 @@ var
end;
end;
{$IFDEF SYNDEBUGPRINT}
procedure DebugPrint(Txt: String; MinCol: Integer = 0);
begin
if CurPhysPos < MinCol then Txt := StringOfChar(' ', MinCol - CurPhysPos) + txt;
Setlength(CharWidths, length(CharWidths) + length(Txt));
FillChar(CharWidths[length(CharWidths)-length(Txt)], length(Txt), #1);
DrawHiLightMarkupToken(nil, PChar(Pointer(Txt)), Length(Txt));
end;
{$ENDIF}
procedure PaintLines;
var
sLine: string; // the current line

View File

@ -339,6 +339,21 @@ type
property Size: LongInt read GetSize;
end;
{ TSynMethodList }
TSynMethodList = Class(TMethodList)
private
function IndexToObjectIndex(const AnObject: TObject; AnIndex: Integer): integer;
function GetObjectItems(AnObject: TObject; Index: integer): TMethod;
procedure SetObjectItems(AnObject: TObject; Index: integer; const AValue: TMethod);
public
function CountByObject(const AnObject: TObject): integer;
procedure DeleteByObject(const AnObject: TObject; Index: integer);
public
property ItemsByObject[AnObject: TObject; Index: integer]: TMethod
read GetObjectItems write SetObjectItems; default;
end;
const
synClipTagText = TSynClipboardStreamTag(1);
synClipTagExtText = TSynClipboardStreamTag(2);
@ -1086,5 +1101,53 @@ begin
Result := aX;
end;
{ TSynMethodList }
function TSynMethodList.IndexToObjectIndex(const AnObject: TObject; AnIndex: Integer): integer;
var
i, c: Integer;
begin
Result := -1;
if Self = nil then exit;
i := 0;
c := Count;
while i < c do begin
if TObject(Items[AnIndex].Data)=AnObject then begin
if AnIndex = 0 then exit(i);
dec(AnIndex);
end;
inc(i);
end;
end;
function TSynMethodList.GetObjectItems(AnObject: TObject; Index: integer): TMethod;
begin
Result := Items[IndexToObjectIndex(AnObject, Index)];
end;
procedure TSynMethodList.SetObjectItems(AnObject: TObject; Index: integer;
const AValue: TMethod);
begin
Items[IndexToObjectIndex(AnObject, Index)] := AValue;
end;
function TSynMethodList.CountByObject(const AnObject: TObject): integer;
var
i: Integer;
begin
Result := 0;
if Self=nil then exit;
i := Count-1;
while i>=0 do begin
if TObject(Items[i].Data)=AnObject then inc(Result);
dec(i);
end;
end;
procedure TSynMethodList.DeleteByObject(const AnObject: TObject; Index: integer);
begin
Delete(IndexToObjectIndex(AnObject, Index));
end;
end.

View File

@ -33,7 +33,9 @@ type
TStringListLineCountEvent = procedure(Sender: TSynEditStrings;
Index, Count: Integer) of object;
TSynEditNotifyReason = (senrLineCount, senrLineChange, senrEditAction);
TSynEditNotifyReason = (senrLineCount, senrLineChange, senrEditAction,
senrTextEdit, senrBeginUpdate, senrEndUpdate,
senrCleared);
TStringListLineEditEvent = procedure(Sender: TSynEditStrings;
LinePos, BytePos, Count, LineBrkCnt: Integer;
@ -105,12 +107,23 @@ type
procedure RegisterAttribute(const Index: TClass; const Size: Word); virtual; abstract;
property Attribute[Owner: TClass; Index: Integer]: Pointer
read GetAttribute write SetAttribute;
procedure AddGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); virtual; abstract;
procedure AddChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); virtual; abstract;
AHandler: TStringListLineCountEvent);
procedure AddNotifyHandler(AReason: TSynEditNotifyReason;
AHandler: TNotifyEvent);
procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); virtual; abstract;
procedure RemoveChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); virtual; abstract;
procedure AddEditHandler(AHandler: TStringListLineEditEvent); virtual; abstract;
procedure RemoveEditHandler(AHandler: TStringListLineEditEvent); virtual; abstract;
AHandler: TStringListLineCountEvent);
procedure RemoveNotifyHandler(AReason: TSynEditNotifyReason;
AHandler: TNotifyEvent);
procedure AddEditHandler(AHandler: TStringListLineEditEvent);
procedure RemoveEditHandler(AHandler: TStringListLineEditEvent);
public
function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; virtual; abstract;
@ -196,12 +209,10 @@ type
// Size: 0 = Bit (TODO); 1..8 Size In Byte "SizeOf()"
procedure RegisterAttribute(const Index: TClass; const Size: Word); override;
procedure AddChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); override;
procedure RemoveChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); override;
procedure AddEditHandler(AHandler: TStringListLineEditEvent); override;
procedure RemoveEditHandler(AHandler: TStringListLineEditEvent); override;
procedure AddGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); override;
procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); override;
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
property NextLines: TSynEditStrings read fSynStrings;
@ -328,6 +339,40 @@ begin
IsUtf8 := True;
end;
procedure TSynEditStrings.AddChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent);
begin
AddGenericHandler(AReason, TMethod(AHandler));
end;
procedure TSynEditStrings.AddNotifyHandler(AReason: TSynEditNotifyReason;
AHandler: TNotifyEvent);
begin
AddGenericHandler(AReason, TMethod(AHandler));
end;
procedure TSynEditStrings.RemoveChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent);
begin
RemoveGenericHandler(AReason, TMethod(AHandler));
end;
procedure TSynEditStrings.RemoveNotifyHandler(AReason: TSynEditNotifyReason;
AHandler: TNotifyEvent);
begin
RemoveGenericHandler(AReason, TMethod(AHandler));
end;
procedure TSynEditStrings.AddEditHandler(AHandler: TStringListLineEditEvent);
begin
AddGenericHandler(senrTextEdit, TMethod(AHandler));
end;
procedure TSynEditStrings.RemoveEditHandler(AHandler: TStringListLineEditEvent);
begin
RemoveGenericHandler(senrTextEdit, TMethod(AHandler));
end;
function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
begin
Result := GetPhysicalCharWidths(Strings[Index], Index);
@ -564,24 +609,14 @@ begin
fSynStrings.RegisterAttribute(Index, Size);
end;
procedure TSynEditStringsLinked.AddChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent);
procedure TSynEditStringsLinked.AddGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin
fSynStrings.AddChangeHandler(AReason, AHandler);
fSynStrings.AddGenericHandler(AReason, AHandler);
end;
procedure TSynEditStringsLinked.RemoveChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent);
procedure TSynEditStringsLinked.RemoveGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin
fSynStrings.RemoveChangeHandler(AReason, AHandler);
end;
procedure TSynEditStringsLinked.AddEditHandler(AHandler: TStringListLineEditEvent);
begin
fSynStrings.AddEditHandler(AHandler);
end;
procedure TSynEditStringsLinked.RemoveEditHandler(AHandler: TStringListLineEditEvent);
begin
fSynStrings.RemoveEditHandler(AHandler);
fSynStrings.RemoveGenericHandler(AReason, AHandler);
end;
// Count

View File

@ -44,10 +44,10 @@ interface
uses
Classes, SysUtils, SynEditTextBase,
FileUtil, LCLProc, LCLIntf, LCLType,
SynEditTypes, SynEditMiscProcs;
SynEditTypes, SynEditMiscProcs, SynEditMiscClasses;
const
NullRange = TSynEditRange(-1);
NullRange = TSynEditRange(nil);
type
TSynEditFlagsClass = class end; // For Register
@ -69,14 +69,14 @@ type
{ TLineRangeNotificationList }
TLineRangeNotificationList = Class(TMethodList)
TLineRangeNotificationList = Class(TSynMethodList)
public
Procedure CallRangeNotifyEvents(Sender: TSynEditStrings; aIndex, aCount: Integer);
end;
{ TLineEditNotificationList }
TLineEditNotificationList = Class(TMethodList)
TLineEditNotificationList = Class(TSynMethodList)
public
Procedure CallRangeNotifyEvents(Sender: TSynEditStrings;
aLinePos, aBytePos, aCount, aLineBrkCnt: Integer; aText: String);
@ -120,14 +120,17 @@ type
private
FList: TSynEditStringMemory;
FAttributeList: Array of TSynEditStringAttribute;
FLineRangeNotificationList: TLineRangeNotificationList; // LineCount
FLineChangeNotificationList: TLineRangeNotificationList; // ContentChange (not called on add...)
FLineEditNotificationList: TLineEditNotificationList;
FOnChangeList: TSynMethodList;
FOnChangingList: TSynMethodList;
FOnClearedList: TSynMethodList;
FIgnoreSendNotification: array [TSynEditNotifyReason] of Integer;
fDosFileFormat: boolean;
fIndexOfLongestLine: integer;
fOnChange: TNotifyEvent;
fOnChanging: TNotifyEvent;
fRedoList: TSynEditUndoList;
fUndoList: TSynEditUndoList;
FIsUndoing: Boolean;
@ -141,7 +144,6 @@ type
Procedure SetAttributeSize(NewSize: Integer);
procedure SetFlags(Index: Integer; const AValue: TSynEditStringFlags);
protected
fOnCleared: TNotifyEvent;
function GetExpandedString(Index: integer): string; override;
function GetLengthOfLongestLine: integer; override;
@ -192,19 +194,14 @@ type
procedure SetDebugMarks(AFirst, ALast: Integer);
procedure ClearDebugMarks;
{$ENDIF}
procedure AddChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); override;
procedure RemoveChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); override;
procedure AddEditHandler(AHandler: TStringListLineEditEvent); override;
procedure RemoveEditHandler(AHandler: TStringListLineEditEvent); override;
procedure AddGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); override;
procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
AHandler: TMethod); override;
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
public
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
property OnChange: TNotifyEvent read fOnChange write fOnChange;
property OnChanging: TNotifyEvent read fOnChanging write fOnChanging;
property OnCleared: TNotifyEvent read fOnCleared write fOnCleared;
{$IFDEF SYN_LAZARUS}
property Flags[Index: Integer]: TSynEditStringFlags read GetFlags
write SetFlags;
@ -408,6 +405,10 @@ begin
FLineRangeNotificationList := TLineRangeNotificationList.Create;
FLineChangeNotificationList := TLineRangeNotificationList.Create;
FLineEditNotificationList := TLineEditNotificationList.Create;
FOnChangeList := TSynMethodList.Create;
FOnChangingList := TSynMethodList.Create;
FOnClearedList := TSynMethodList.Create;
for r := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
FIgnoreSendNotification[r] := 0;
inherited Create;
@ -421,8 +422,6 @@ end;
destructor TSynEditStringList.Destroy;
begin
fOnChange := nil;
fOnChanging := nil;
fAttributeList := nil;
inherited Destroy;
SetCount(0);
@ -430,6 +429,10 @@ begin
FreeAndNil(FLineRangeNotificationList);
FreeAndNil(FLineChangeNotificationList);
FreeAndNil(FLineEditNotificationList);
FreeAndNil(FOnChangeList);
FreeAndNil(FOnChangingList);
FreeAndNil(FOnClearedList);
FreeAndNil(fList);
end;
@ -480,8 +483,7 @@ begin
BeginUpdate;
SetCount(0);
SetCapacity(0);
if Assigned(fOnCleared) then
fOnCleared(Self);
FOnClearedList.CallNotifyEvents(Self);
FLineRangeNotificationList.CallRangeNotifyEvents(self, 0, -c);
EndUpdate;
end;
@ -861,32 +863,30 @@ begin
Flags[Index] := Flags[Index] - [sfDebugMark];
end;
procedure TSynEditStringList.AddChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent);
procedure TSynEditStringList.AddGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin
case AReason of
senrLineChange : FLineChangeNotificationList.Add(TMethod(AHandler));
senrLineCount : FLineRangeNotificationList.Add(TMethod(AHandler));
senrLineChange : FLineChangeNotificationList.Add(AHandler);
senrLineCount : FLineRangeNotificationList.Add(AHandler);
senrTextEdit: FLineEditNotificationList.Add(TMethod(AHandler));
senrBeginUpdate : FOnChangingList.Add(AHandler);
senrEndUpdate : FOnChangeList.Add(AHandler);
senrCleared : FOnClearedList.Add(AHandler);
end;
end;
procedure TSynEditStringList.RemoveChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent);
procedure TSynEditStringList.RemoveGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin
case AReason of
senrLineChange : FLineChangeNotificationList.Remove(TMethod(AHandler));
senrLineCount : FLineRangeNotificationList.Remove(TMethod(AHandler));
senrLineChange : FLineChangeNotificationList.Remove(AHandler);
senrLineCount : FLineRangeNotificationList.Remove(AHandler);
senrTextEdit: FLineEditNotificationList.Remove(TMethod(AHandler));
senrBeginUpdate : FOnChangingList.Remove(AHandler);
senrEndUpdate : FOnChangeList.Remove(AHandler);
senrCleared : FOnClearedList.Remove(AHandler);
end;
end;
procedure TSynEditStringList.AddEditHandler(AHandler: TStringListLineEditEvent);
begin
FLineEditNotificationList.Add(TMethod(AHandler));
end;
procedure TSynEditStringList.RemoveEditHandler(AHandler: TStringListLineEditEvent);
begin
FLineEditNotificationList.Remove(TMethod(AHandler));
end;
{$ENDIF}
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
@ -897,11 +897,9 @@ end;
procedure TSynEditStringList.SetUpdateState(Updating: Boolean);
begin
if Updating then begin
if Assigned(fOnChanging) then
fOnChanging(Self);
FOnChangingList.CallNotifyEvents(Self);
end else begin
if Assigned(fOnChange) then
fOnChange(Self);
FOnChangeList.CallNotifyEvents(Self);
end;
end;