synedit: allow to set/clear debug execution marks

git-svn-id: trunk@18992 -
This commit is contained in:
paul 2009-03-14 19:01:35 +00:00
parent 6526ca074b
commit 25fc0e9b9c
3 changed files with 113 additions and 39 deletions

View File

@ -805,6 +805,9 @@ type
procedure SetSelWord; procedure SetSelWord;
procedure Undo; procedure Undo;
function GetLineState(ALine: Integer): TSynLineState; function GetLineState(ALine: Integer): TSynLineState;
function HasDebugMark(ALine: Integer): Boolean;
procedure SetDebugMarks(AFirst, ALast: Integer);
procedure ClearDebugMarks;
procedure UnregisterCommandHandler(AHandlerProc: THookedCommandEvent); procedure UnregisterCommandHandler(AHandlerProc: THookedCommandEvent);
{$IFDEF SYN_COMPILER_4_UP} {$IFDEF SYN_COMPILER_4_UP}
function UpdateAction(TheAction: TBasicAction): boolean; override; function UpdateAction(TheAction: TBasicAction): boolean; override;
@ -4992,6 +4995,21 @@ begin
Result := slsNone; Result := slsNone;
end; end;
function TCustomSynEdit.HasDebugMark(ALine: Integer): Boolean;
begin
Result := sfDebugMark in TSynEditStringList(fLines).Flags[ALine];
end;
procedure TCustomSynEdit.SetDebugMarks(AFirst, ALast: Integer);
begin
TSynEditStringList(fLines).SetDebugMarks(AFirst, ALast);
end;
procedure TCustomSynEdit.ClearDebugMarks;
begin
TSynEditStringList(fLines).ClearDebugMarks;
end;
procedure TCustomSynEdit.UndoItem; procedure TCustomSynEdit.UndoItem;
{end} //sbs 2000-11-19 {end} //sbs 2000-11-19
var var

View File

@ -60,7 +60,8 @@ type
TSynEditStringFlag = ( TSynEditStringFlag = (
sfModified, // a line is modified and not saved after sfModified, // a line is modified and not saved after
sfSaved // a line is modified and saved after sfSaved, // a line is modified and saved after
sfDebugMark // a line where debugger can stop (for lazarus only)
); );
TSynEditStringFlags = set of TSynEditStringFlag; TSynEditStringFlags = set of TSynEditStringFlag;
@ -192,6 +193,8 @@ type
procedure ClearRanges(ARange: TSynEditRange); override; procedure ClearRanges(ARange: TSynEditRange); override;
procedure MarkModified(AFirst, ALast: Integer; AUndo: Boolean; AReason: TSynChangeReason); procedure MarkModified(AFirst, ALast: Integer; AUndo: Boolean; AReason: TSynChangeReason);
procedure MarkSaved; procedure MarkSaved;
procedure SetDebugMarks(AFirst, ALast: Integer);
procedure ClearDebugMarks;
{$ENDIF} {$ENDIF}
procedure AddChangeHandler(AReason: TSynEditNotifyReason; procedure AddChangeHandler(AReason: TSynEditNotifyReason;
AHandler: TStringListLineCountEvent); override; AHandler: TStringListLineCountEvent); override;
@ -745,6 +748,23 @@ begin
Flags[Index] := Flags[Index] + [sfSaved]; Flags[Index] := Flags[Index] + [sfSaved];
end; end;
procedure TSynEditStringList.SetDebugMarks(AFirst, ALast: Integer);
var
Index: Integer;
begin
for Index := AFirst to ALast do
if (Index >= 0) and (Index < Count) then
Flags[Index] := Flags[Index] + [sfDebugMark];
end;
procedure TSynEditStringList.ClearDebugMarks;
var
Index: Integer;
begin
for Index := 0 to Count - 1 do
Flags[Index] := Flags[Index] - [sfDebugMark];
end;
procedure TSynEditStringList.AddChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent); procedure TSynEditStringList.AddChangeHandler(AReason: TSynEditNotifyReason; AHandler: TStringListLineCountEvent);
begin begin
case AReason of case AReason of

View File

@ -14,6 +14,7 @@ type
TSynGutterMarks = class(TSynGutterPartBase) TSynGutterMarks = class(TSynGutterPartBase)
private private
FDebugMarksImageIndex: Integer;
FFoldView: TSynEditFoldedView; FFoldView: TSynEditFoldedView;
FBookMarkOpt: TSynBookMarkOpt; FBookMarkOpt: TSynBookMarkOpt;
FInternalImage: TSynInternalImage; FInternalImage: TSynInternalImage;
@ -23,9 +24,9 @@ type
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure Paint(Canvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer); procedure Paint(Canvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer); override;
override;
function RealGutterWidth(CharWidth: integer): integer; override; function RealGutterWidth(CharWidth: integer): integer; override;
property DebugMarksImageIndex: Integer read FDebugMarksImageIndex write FDebugMarksImageIndex;
end; end;
implementation implementation
@ -48,13 +49,14 @@ begin
FFoldView := Gutter.FoldView; FFoldView := Gutter.FoldView;
FBookMarkOpt := TSynEdit(SynEdit).BookMarkOptions; FBookMarkOpt := TSynEdit(SynEdit).BookMarkOptions;
FInternalImage := nil; FInternalImage := nil;
FDebugMarksImageIndex := -1;
FWidth := 23; FWidth := 23;
end; end;
destructor TSynGutterMarks.Destroy; destructor TSynGutterMarks.Destroy;
begin begin
FreeAndNil(fInternalImage); FreeAndNil(FInternalImage);
inherited Destroy; inherited Destroy;
end; end;
@ -68,11 +70,12 @@ end;
procedure TSynGutterMarks.Paint(Canvas : TCanvas; AClip : TRect; FirstLine, LastLine : integer); procedure TSynGutterMarks.Paint(Canvas : TCanvas; AClip : TRect; FirstLine, LastLine : integer);
var var
i: integer; i, j, iLine: integer;
aGutterOffs: PIntArray; aGutterOffs: PIntArray;
dc: HDC; dc: HDC;
LineHeight: Integer; LineHeight: Integer;
LineMarks: TList; Marks: TSynEditMarks;
HasAnyMark: Boolean;
procedure DrawMark(CurMark: TSynEditMark); procedure DrawMark(CurMark: TSynEditMark);
var var
@ -83,38 +86,68 @@ var
if (CurMark.Line<1) or (CurMark.Line > SynEdit.Lines.Count) then exit; if (CurMark.Line<1) or (CurMark.Line > SynEdit.Lines.Count) then exit;
if FFoldView.FoldedAtTextIndex[CurMark.Line-1] then exit; if FFoldView.FoldedAtTextIndex[CurMark.Line-1] then exit;
iLine := FFoldView.TextIndexToScreenLine(CurMark.Line-1); iLine := FFoldView.TextIndexToScreenLine(CurMark.Line-1);
if iLine < 0 then Exit;
if Assigned(fBookMarkOpt.BookmarkImages) and not CurMark.InternalImage if Assigned(FBookMarkOpt.BookmarkImages) and not CurMark.InternalImage then
then begin begin
if (CurMark.ImageIndex <= FBookMarkOpt.BookmarkImages.Count) then begin if (CurMark.ImageIndex <= FBookMarkOpt.BookmarkImages.Count) and
(CurMark.ImageIndex >= 0) then
begin
if CurMark.IsBookmark = FBookMarkOpt.DrawBookmarksFirst then if CurMark.IsBookmark = FBookMarkOpt.DrawBookmarksFirst then
aGutterOffs^[iLine] := AClip.Left aGutterOffs^[iLine] := AClip.Left
else if aGutterOffs^[iLine] = 0 then else
aGutterOffs^[iLine] := fBookMarkOpt.BookmarkImages.Width + AClip.Left; if aGutterOffs^[iLine] = 0 then
if LineHeight > fBookMarkOpt.BookmarkImages.Height then aGutterOffs^[iLine] := FBookMarkOpt.BookmarkImages.Width + AClip.Left;
iTop := (LineHeight - fBookMarkOpt.BookmarkImages.Height) div 2; if LineHeight > FBookMarkOpt.BookmarkImages.Height then
with fBookMarkOpt do iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
with FBookMarkOpt do
BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs^[iLine], BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs^[iLine],
iTop + iLine * LineHeight, CurMark.ImageIndex, true); iTop + iLine * LineHeight, CurMark.ImageIndex, True);
Inc(aGutterOffs^[iLine], fBookMarkOpt.BookmarkImages.Width); Inc(aGutterOffs^[iLine], FBookMarkOpt.BookmarkImages.Width);
end; end;
end else end
else
begin begin
if CurMark.ImageIndex in [0..9] then begin if CurMark.ImageIndex in [0..9] then
if not Assigned(fInternalImage) then begin begin
fInternalImage := TSynInternalImage.Create('SynEditInternalImages',10); if not Assigned(FInternalImage) then
end; FInternalImage := TSynInternalImage.Create('SynEditInternalImages',10);
if aGutterOffs^[iLine] = 0 then if aGutterOffs^[iLine] = 0 then
aGutterOffs^[iLine] := AClip.Left; aGutterOffs^[iLine] := AClip.Left;
fInternalImage.DrawMark(Canvas, CurMark.ImageIndex, FInternalImage.DrawMark(Canvas, CurMark.ImageIndex,
fBookMarkOpt.LeftMargin + aGutterOffs^[iLine], iLine * LineHeight, FBookMarkOpt.LeftMargin + aGutterOffs^[iLine], iLine * LineHeight,
LineHeight); LineHeight);
Inc(aGutterOffs^[iLine], fBookMarkOpt.Xoffset); Inc(aGutterOffs^[iLine], FBookMarkOpt.Xoffset);
end; end;
end; end;
end; end;
procedure DrawDebugMark(Line: Integer);
var
itop : Longint;
begin
iTop := 0;
if Line < 0 then Exit;
if Assigned(FBookMarkOpt.BookmarkImages) and
(DebugMarksImageIndex <= FBookMarkOpt.BookmarkImages.Count) and
(DebugMarksImageIndex >= 0) then
begin
if not FBookMarkOpt.DrawBookmarksFirst then
aGutterOffs^[Line] := AClip.Left
else
if aGutterOffs^[Line] = 0 then
aGutterOffs^[Line] := FBookMarkOpt.BookmarkImages.Width + AClip.Left;
if LineHeight > FBookMarkOpt.BookmarkImages.Height then
iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
with FBookMarkOpt do
BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs^[Line],
iTop + Line * LineHeight, DebugMarksImageIndex, True);
Inc(aGutterOffs^[Line], FBookMarkOpt.BookmarkImages.Width);
end
end;
begin begin
if not Visible then exit; if not Visible then exit;
LineHeight := TSynEdit(SynEdit).LineHeight; LineHeight := TSynEdit(SynEdit).LineHeight;
@ -129,23 +162,26 @@ begin
// now the gutter marks // now the gutter marks
if FBookMarkOpt.GlyphsVisible and (TSynEdit(SynEdit).Marks.Count > 0) and (LastLine >= FirstLine) then if FBookMarkOpt.GlyphsVisible and (LastLine >= FirstLine) then
begin begin
aGutterOffs := AllocMem((LastLine+1{$IFNDEF SYN_LAZARUS}-TopLine{$ENDIF}) * SizeOf(integer)); aGutterOffs := AllocMem((LastLine + 1) * SizeOf(integer));
try try
LineMarks := TList.Create; for i := FirstLine to LastLine do
try begin
for i := 0 to TSynEdit(SynEdit).Marks.Count - 1 do with TSynEdit(SynEdit).Marks[i] do iLine := FFoldView.TextIndex[i] + 1;
if Visible and (Line >= FFoldView.TextIndex[FirstLine] + 1) and (Line <= FFoldView.TextIndex[LastLine] + 1) then TSynEdit(SynEdit).Marks.GetMarksForLine(iLine, Marks);
LineMarks.Add(TSynEdit(SynEdit).Marks[i]); HasAnyMark := False;
if fBookMarkOpt.DrawBookmarksFirst then for j := Low(Marks) to High(Marks) do
LineMarks.Sort(@DoMarksCompareBookmarksFirst) begin
else if Marks[j] = nil then
LineMarks.Sort(@DoMarksCompareBookmarksLast); break;
for i := 0 to LineMarks.Count - 1 do if not Marks[j].Visible then
DrawMark(TSynEditMark(LineMarks[i])); continue;
finally DrawMark(Marks[j]);
LineMarks.Free; HasAnyMark := HasAnyMark or not Marks[j].IsBookmark;
end;
if not HasAnyMark and TSynEdit(SynEdit).HasDebugMark(iLine) then
DrawDebugMark(i);
end; end;
finally finally
FreeMem(aGutterOffs); FreeMem(aGutterOffs);