mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 04:18:48 +02:00
IDE: added sourcemarklings
git-svn-id: trunk@27646 -
This commit is contained in:
parent
0274574004
commit
8e7ba111c3
@ -43,12 +43,23 @@ uses
|
||||
LCLProc, LCLType, ClipBrd, Controls, Dialogs, FileUtil, Forms,
|
||||
Menus, ExtCtrls, StdCtrls, ComCtrls, Graphics,
|
||||
CodeToolManager,
|
||||
IDEImagesIntf, IDEExternToolIntf, IDECommands, MenuIntf, IDEMsgIntf, LazIDEIntf,
|
||||
DialogProcs, EnvironmentOpts,
|
||||
IDEImagesIntf, IDEExternToolIntf, IDECommands, MenuIntf, IDEMsgIntf,
|
||||
SrcEditorIntf, LazIDEIntf,
|
||||
DialogProcs, EnvironmentOpts, SourceMarks,
|
||||
LazarusIDEStrConsts, IDEOptionDefs, IDEProcs, InputHistory, infobuild,
|
||||
KeyMapping;
|
||||
|
||||
type
|
||||
|
||||
{ TMessageViewMarklings }
|
||||
|
||||
TMessageViewMarklings = class(TSourceMarklingProducer)
|
||||
private
|
||||
public
|
||||
function GetMarklings(aFilename: string;
|
||||
out FreeList, FreeMarklings: boolean): TFPList; override;
|
||||
end;
|
||||
|
||||
TLazMsgLineFlag = (
|
||||
lmlfHasQuickFixValid,
|
||||
lmlfHasQuickFix
|
||||
@ -99,6 +110,7 @@ type
|
||||
procedure OnQuickFixClick(Sender: TObject);
|
||||
private
|
||||
FItems: TFPList; // list of TLazMessageLine
|
||||
FMarklings: TMessageViewMarklings;
|
||||
FVisibleItems: TFPList; // list of TLazMessageLine (visible Items of FItems)
|
||||
FSrcPositions: TAVLTree;// tree of TLazMessageLine sorted for Filename and LineNumber
|
||||
FLastLineIsProgress: boolean;
|
||||
@ -176,6 +188,7 @@ type
|
||||
read FOnSelectionChanged write FOnSelectionChanged;
|
||||
property Items[Index: integer]: TLazMessageLine read GetItems;
|
||||
property VisibleItems[Index: integer]: TLazMessageLine read GetVisibleItems;
|
||||
property Marklings: TMessageViewMarklings read FMarklings;
|
||||
end;
|
||||
|
||||
var
|
||||
@ -335,6 +348,9 @@ begin
|
||||
MsgCopyAllIDEMenuCommand.OnClick := @CopyAllMenuItemClick;
|
||||
MsgCopyAllAndHiddenIDEMenuCommand.OnClick := @CopyAllAndHiddenMenuItemClick;
|
||||
MsgSaveAllToFileIDEMenuCommand.OnClick := @SaveAllToFileMenuItemClick;
|
||||
|
||||
FMarklings:=TMessageViewMarklings.Create(Self);
|
||||
SourceEditorManagerIntf.RegisterMarklingProducer(FMarklings);
|
||||
end;
|
||||
|
||||
destructor TMessagesView.Destroy;
|
||||
@ -429,7 +445,7 @@ begin
|
||||
NewMsg := TLazMessageLine.Create;
|
||||
FItems.Add(NewMsg);
|
||||
end;
|
||||
|
||||
|
||||
NewMsg.Msg := Msg;
|
||||
NewMsg.Directory := CurDir;
|
||||
NewMsg.Position := FItems.Count-1;
|
||||
@ -439,6 +455,7 @@ begin
|
||||
if NewMsg.Parts=nil then
|
||||
NewMsg.Parts:=TStringList.Create;
|
||||
NewMsg.Parts.Assign(Parts);
|
||||
NewMsg.Filename:=Parts.Values['Filename'];
|
||||
end;
|
||||
//DebugLn('TMessagesView.Add FItems.Count=',dbgs(FItems.Count),' OriginalIndex=',dbgs(OriginalIndex));
|
||||
|
||||
@ -467,6 +484,10 @@ begin
|
||||
end;
|
||||
//ConsistencyCheck;
|
||||
Changed;
|
||||
|
||||
//debugln(['TMessagesView.Add ',NewMsg.Filename,' ',NewMsg.LineNumber,',',NewMsg.Column,' ',NewMsg.Msg]);
|
||||
if NewMsg.Filename<>'' then
|
||||
Marklings.InvalidateFile(NewMsg.Filename);
|
||||
end;
|
||||
|
||||
procedure TMessagesView.AddMsg(const Msg, CurDir: string; OriginalIndex: integer;
|
||||
@ -1309,4 +1330,41 @@ begin
|
||||
GetSourcePosition(FFilename, FLineNumber, FColumn);
|
||||
end;
|
||||
|
||||
{ TMessageViewMarklings }
|
||||
|
||||
function TMessageViewMarklings.GetMarklings(aFilename: string; out FreeList,
|
||||
FreeMarklings: boolean): TFPList;
|
||||
var
|
||||
i: Integer;
|
||||
Msg: TLazMessageLine;
|
||||
aType: TSourceMarklingType;
|
||||
Markling: TSourceMarkling;
|
||||
TypeStr: string;
|
||||
begin
|
||||
Result:=TFPList.Create;
|
||||
FreeList:=true;
|
||||
FreeMarklings:=true;
|
||||
for i:=0 to MessagesView.VisibleItemCount-1 do
|
||||
begin
|
||||
Msg:=MessagesView.VisibleItems[i];
|
||||
//debugln(['TMessageViewMarklings.GetMarklings ',CompareFilenames(Msg.Filename,aFilename),' ',Msg.Filename,' ',Msg.LineNumber,',',Msg.Column,' ',Msg.Msg]);
|
||||
if CompareFilenames(Msg.Filename,aFilename)=0 then
|
||||
begin
|
||||
aType:=smtHint;
|
||||
if Msg.Parts<>nil then
|
||||
begin
|
||||
TypeStr:=Msg.Parts.Values['Type'];
|
||||
if TypeStr='Error' then
|
||||
aType:=smtError
|
||||
else if TypeStr='Warning' then
|
||||
aType:=smtWarning
|
||||
else if TypeStr='Note' then
|
||||
aType:=smtNote;
|
||||
end;
|
||||
Markling:=TSourceMarkling.Create(Self,i,Msg.LineNumber,Msg.Column,aType);
|
||||
Result.Add(Markling);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -147,6 +147,7 @@ type
|
||||
end;
|
||||
|
||||
TSourceEditor = class;
|
||||
|
||||
{ TSourceEditorSharedValues }
|
||||
|
||||
TSourceEditorSharedValues = class
|
||||
@ -168,6 +169,7 @@ type
|
||||
FExecutionMark: TSourceMark;
|
||||
FExecutionLine: integer;
|
||||
FMarksRequested: Boolean;
|
||||
FMarklingsValid: boolean;
|
||||
public
|
||||
UpdatingExecutionMark: Integer;
|
||||
procedure CreateExecutionMark;
|
||||
@ -835,6 +837,7 @@ type
|
||||
function GetSourceWindowByLastFocused(Index: Integer): TSourceEditorWindowInterface;
|
||||
procedure SetActiveSourceWindowIndex(const AValue: integer);
|
||||
protected
|
||||
fProducers: TFPList; // list of TSourceMarklingProducer
|
||||
FChangeNotifyLists: Array [TsemChangeReason] of TMethodList;
|
||||
function GetActiveSourceWindow: TSourceEditorWindowInterface; override;
|
||||
procedure SetActiveSourceWindow(const AValue: TSourceEditorWindowInterface); override;
|
||||
@ -846,6 +849,7 @@ type
|
||||
procedure DoEditorStatusChanged(AEditor: TSourceEditor);
|
||||
function GetSourceEditors(Index: integer): TSourceEditorInterface; override;
|
||||
function GetUniqueSourceEditors(Index: integer): TSourceEditorInterface; override;
|
||||
function GetMarklingProducers(Index: integer): TSourceMarklingProducer; override;
|
||||
public
|
||||
// Windows
|
||||
function SourceWindowWithEditor(const AEditor: TSourceEditorInterface): TSourceEditorWindowInterface;
|
||||
@ -894,6 +898,12 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure RegisterChangeEvent(AReason: TsemChangeReason; AHandler: TNotifyEvent); override;
|
||||
procedure UnRegisterChangeEvent(AReason: TsemChangeReason; AHandler: TNotifyEvent); override;
|
||||
// producers
|
||||
function MarklingProducerCount: integer; override;
|
||||
procedure RegisterMarklingProducer(aProducer: TSourceMarklingProducer); override;
|
||||
procedure UnregisterMarklingProducer(aProducer: TSourceMarklingProducer); override;
|
||||
procedure InvalidateMarklingsOfAllFiles(aProducer: TSourceMarklingProducer); override;
|
||||
procedure InvalidateMarklings(aProducer: TSourceMarklingProducer; aFilename: string); override;
|
||||
public
|
||||
procedure IncUpdateLock;
|
||||
procedure DecUpdateLock;
|
||||
@ -995,6 +1005,7 @@ type
|
||||
function FindUniquePageName(FileName:string; IgnoreEditor: TSourceEditor):string;
|
||||
function SomethingModified: boolean;
|
||||
procedure HideHint;
|
||||
procedure OnIdle(Sender: TObject; var Done: Boolean);
|
||||
procedure LockAllEditorsInSourceChangeCache;
|
||||
procedure UnlockAllEditorsInSourceChangeCache;
|
||||
procedure CloseFile(AEditor: TSourceEditorInterface);
|
||||
@ -7865,6 +7876,12 @@ begin
|
||||
FCompletionPlugins.Clear;
|
||||
end;
|
||||
|
||||
function TSourceEditorManagerBase.GetMarklingProducers(Index: integer
|
||||
): TSourceMarklingProducer;
|
||||
begin
|
||||
Result:=TSourceMarklingProducer(fProducers[Index]);
|
||||
end;
|
||||
|
||||
function TSourceEditorManagerBase.GetActiveCompletionPlugin: TSourceEditorCompletionPlugin;
|
||||
begin
|
||||
Result := FActiveCompletionPlugin;
|
||||
@ -7983,6 +8000,8 @@ begin
|
||||
fCompletionPlugins.Remove(AComponent);
|
||||
if ActiveCompletionPlugin = AComponent then
|
||||
DeactivateCompletionForm;
|
||||
if AComponent is TSourceMarklingProducer then
|
||||
fProducers.Remove(AComponent);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -7998,13 +8017,18 @@ begin
|
||||
FCompletionPlugins := TFPList.Create;
|
||||
FUpdateLock := 0;
|
||||
FActiveEditorLock := 0;
|
||||
fProducers := TFPList.Create;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
destructor TSourceEditorManagerBase.Destroy;
|
||||
var
|
||||
i: TsemChangeReason;
|
||||
i: integer;
|
||||
cr: TsemChangeReason;
|
||||
begin
|
||||
for i:=MarklingProducerCount-1 downto 0 do
|
||||
MarklingProducers[i].Free;
|
||||
FreeAndNil(fProducers);
|
||||
FActiveWindow := nil;
|
||||
FreeCompletionPlugins;
|
||||
FreeSourceWindows;
|
||||
@ -8012,8 +8036,8 @@ begin
|
||||
FreeAndNil(FCompletionPlugins);
|
||||
FreeAndNil(FSourceWindowList);
|
||||
FreeAndNil(FSourceWindowByFocusList);
|
||||
for i := low(TsemChangeReason) to high(TsemChangeReason) do
|
||||
FChangeNotifyLists[i].Free;;
|
||||
for cr := low(TsemChangeReason) to high(TsemChangeReason) do
|
||||
FChangeNotifyLists[cr].Free;;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -8029,6 +8053,72 @@ begin
|
||||
FChangeNotifyLists[AReason].Remove(TMethod(AHandler));
|
||||
end;
|
||||
|
||||
function TSourceEditorManagerBase.MarklingProducerCount: integer;
|
||||
begin
|
||||
Result:=fProducers.Count;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManagerBase.RegisterMarklingProducer(
|
||||
aProducer: TSourceMarklingProducer);
|
||||
begin
|
||||
if fProducers.IndexOf(aProducer)>=0 then
|
||||
RaiseException('TSourceEditorManagerBase.RegisterProducer already registered');
|
||||
fProducers.Add(aProducer);
|
||||
FreeNotification(aProducer);
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManagerBase.UnregisterMarklingProducer(
|
||||
aProducer: TSourceMarklingProducer);
|
||||
var
|
||||
i: LongInt;
|
||||
begin
|
||||
i:=fProducers.IndexOf(aProducer);
|
||||
if i<0 then exit;
|
||||
fProducers.Delete(i);
|
||||
RemoveFreeNotification(aProducer);
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManagerBase.InvalidateMarklingsOfAllFiles(
|
||||
aProducer: TSourceMarklingProducer);
|
||||
var
|
||||
SrcWnd: TSourceEditorWindowInterface;
|
||||
i: Integer;
|
||||
j: Integer;
|
||||
SrcEdit: TSourceEditor;
|
||||
begin
|
||||
if aProducer=nil then exit;
|
||||
for i := 0 to SourceWindowCount - 1 do
|
||||
begin
|
||||
SrcWnd:=SourceWindows[i];
|
||||
for j:=0 to SrcWnd.Count-1 do
|
||||
begin
|
||||
SrcEdit:=TSourceEditor(SrcWnd[j]);
|
||||
SrcEdit.FSharedValues.FMarklingsValid:=false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManagerBase.InvalidateMarklings(
|
||||
aProducer: TSourceMarklingProducer; aFilename: string);
|
||||
var
|
||||
SrcWnd: TSourceEditorWindowInterface;
|
||||
i: Integer;
|
||||
j: Integer;
|
||||
SrcEdit: TSourceEditor;
|
||||
begin
|
||||
if aProducer=nil then exit;
|
||||
for i := 0 to SourceWindowCount - 1 do
|
||||
begin
|
||||
SrcWnd:=SourceWindows[i];
|
||||
for j:=0 to SrcWnd.Count-1 do
|
||||
begin
|
||||
SrcEdit:=TSourceEditor(SrcWnd[j]);
|
||||
if CompareFilenames(SrcEdit.FileName,aFilename)=0 then
|
||||
SrcEdit.FSharedValues.FMarklingsValid:=false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManagerBase.IncUpdateLock;
|
||||
var
|
||||
i: Integer;
|
||||
@ -8547,6 +8637,44 @@ begin
|
||||
SourceWindows[i].HideHint;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManager.OnIdle(Sender: TObject; var Done: Boolean);
|
||||
var
|
||||
SrcEdit: TSourceEditor;
|
||||
i: Integer;
|
||||
aFilename: String;
|
||||
FreeList, FreeMarklings: boolean;
|
||||
Marklings: TFPList;
|
||||
j: Integer;
|
||||
Markling: TSourceMarkling;
|
||||
begin
|
||||
SrcEdit:=ActiveEditor;
|
||||
if not SrcEdit.FSharedValues.FMarklingsValid then
|
||||
begin
|
||||
//debugln(['TSourceEditorManager.OnIdle ',MarklingProducerCount]);
|
||||
aFilename:=SrcEdit.FileName;
|
||||
SrcEdit.EditorComponent.BeginUpdate;
|
||||
for i:=0 to MarklingProducerCount-1 do
|
||||
begin
|
||||
Marklings:=MarklingProducers[i].GetMarklings(aFilename,FreeList,FreeMarklings);
|
||||
for j:=0 to Marklings.Count-1 do
|
||||
begin
|
||||
Markling:=TSourceMarkling(Marklings[j]);
|
||||
if Markling=nil then ;
|
||||
// ToDo: add mark to synedit
|
||||
//debugln(['TSourceEditorManager.OnIdle ',Markling.Id,' ',Markling.Line,',',Markling.Column]);
|
||||
|
||||
end;
|
||||
if FreeMarklings then
|
||||
for j:=0 to Marklings.Count-1 do
|
||||
TObject(Marklings[j]).Free;
|
||||
if FreeList then
|
||||
Marklings.Free;
|
||||
end;
|
||||
SrcEdit.EditorComponent.EndUpdate;
|
||||
SrcEdit.FSharedValues.FMarklingsValid:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditorManager.LockAllEditorsInSourceChangeCache;
|
||||
// lock all sourceeditors that are to be modified by the CodeToolBoss
|
||||
var
|
||||
@ -8848,10 +8976,13 @@ begin
|
||||
nil,@CreateSourceWindow,'250','100','+70%','+70%',
|
||||
NonModalIDEWindowNames[nmiwMainIDEName],alBottom,
|
||||
true,@GetDefaultLayout);
|
||||
|
||||
Application.AddOnIdleHandler(@OnIdle);
|
||||
end;
|
||||
|
||||
destructor TSourceEditorManager.Destroy;
|
||||
begin
|
||||
Application.RemoveAllHandlersOfObject(Self);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
@ -39,7 +39,9 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, LResources, Graphics, GraphType, Controls, Menus,
|
||||
AVL_Tree, SynEdit, SynEditMarks, IDEProcs, MenuIntf, SrcEditorIntf, EditorOptions;
|
||||
AVL_Tree, FileProcs, SynEdit, SynEditMarks,
|
||||
MenuIntf, SrcEditorIntf,
|
||||
IDEProcs, EditorOptions;
|
||||
|
||||
type
|
||||
TSourceMarks = class;
|
||||
|
@ -23,6 +23,43 @@ uses
|
||||
Classes, SysUtils, LCLProc, FileUtil, LCLType, Forms, Controls, Graphics,
|
||||
ProjectIntf;
|
||||
|
||||
type
|
||||
TSourceMarklingType = (
|
||||
smtHint, // something is unusual or awkward
|
||||
smtNote, // something could be wrong or is not optimized
|
||||
smtWarning, // something is probably wrong or likely to fail
|
||||
smtError // something is definitely wrong
|
||||
);
|
||||
|
||||
{ TSourceMarklingProducer }
|
||||
|
||||
TSourceMarklingProducer = class(TComponent)
|
||||
public
|
||||
procedure InvalidateAllFiles;
|
||||
procedure InvalidateFile(aFilename: string);
|
||||
function GetMarklings(aFilename: string;
|
||||
out FreeList, FreeMarklings: boolean): TFPList; virtual; abstract;
|
||||
end;
|
||||
|
||||
{ TSourceMarkling }
|
||||
|
||||
TSourceMarkling = class
|
||||
private
|
||||
FColumn: integer;
|
||||
FProducer: TSourceMarklingProducer;
|
||||
FId: integer;
|
||||
FLine: integer;
|
||||
fType: TSourceMarklingType;
|
||||
public
|
||||
constructor Create(aProducer: TSourceMarklingProducer;
|
||||
TheID, aLine, aColumn: integer; aType: TSourceMarklingType);
|
||||
property Producer: TSourceMarklingProducer read FProducer;
|
||||
property Id: integer read FId;
|
||||
property Line: integer read FLine;
|
||||
property Column: integer read FColumn;
|
||||
property TheType: TSourceMarklingType read fType;
|
||||
end;
|
||||
|
||||
type
|
||||
TSrcEditSearchOption = (
|
||||
sesoMatchCase,
|
||||
@ -219,18 +256,19 @@ type
|
||||
TSourceEditorManagerInterface = class(TComponent)
|
||||
protected
|
||||
function GetActiveSourceWindow: TSourceEditorWindowInterface; virtual; abstract;
|
||||
virtual; abstract;
|
||||
procedure SetActiveSourceWindow(const AValue: TSourceEditorWindowInterface);
|
||||
virtual; abstract;
|
||||
virtual; abstract;
|
||||
function GetSourceWindows(Index: integer): TSourceEditorWindowInterface;
|
||||
virtual; abstract;
|
||||
virtual; abstract;
|
||||
function GetActiveEditor: TSourceEditorInterface; virtual; abstract;
|
||||
procedure SetActiveEditor(const AValue: TSourceEditorInterface);
|
||||
virtual; abstract;
|
||||
virtual; abstract;
|
||||
function GetSourceEditors(Index: integer): TSourceEditorInterface;
|
||||
virtual; abstract;
|
||||
virtual; abstract;
|
||||
function GetUniqueSourceEditors(Index: integer): TSourceEditorInterface;
|
||||
virtual; abstract;
|
||||
virtual; abstract;
|
||||
function GetMarklingProducers(Index: integer): TSourceMarklingProducer;
|
||||
virtual; abstract;
|
||||
public
|
||||
// List of SourceEditorWindows
|
||||
function SourceWindowWithEditor(const AEditor: TSourceEditorInterface): TSourceEditorWindowInterface;
|
||||
@ -274,6 +312,14 @@ type
|
||||
public
|
||||
procedure RegisterChangeEvent(AReason: TsemChangeReason; AHandler: TNotifyEvent); virtual; abstract;
|
||||
procedure UnRegisterChangeEvent(AReason: TsemChangeReason; AHandler: TNotifyEvent); virtual; abstract;
|
||||
public
|
||||
// source marklings
|
||||
function MarklingProducerCount: integer; virtual; abstract;
|
||||
property MarklingProducers[Index: integer]: TSourceMarklingProducer read GetMarklingProducers;
|
||||
procedure RegisterMarklingProducer(aProducer: TSourceMarklingProducer); virtual; abstract;
|
||||
procedure UnregisterMarklingProducer(aProducer: TSourceMarklingProducer); virtual; abstract;
|
||||
procedure InvalidateMarklingsOfAllFiles(aProducer: TSourceMarklingProducer); virtual; abstract;
|
||||
procedure InvalidateMarklings(aProducer: TSourceMarklingProducer; aFilename: string); virtual; abstract;
|
||||
end;
|
||||
|
||||
|
||||
@ -563,5 +609,29 @@ begin
|
||||
Result:=Point(0,0);
|
||||
end;
|
||||
|
||||
{ TSourceMarkling }
|
||||
|
||||
constructor TSourceMarkling.Create(aProducer: TSourceMarklingProducer; TheID,
|
||||
aLine, aColumn: integer; aType: TSourceMarklingType);
|
||||
begin
|
||||
FProducer:=aProducer;
|
||||
FLine:=aLine;
|
||||
FColumn:=aColumn;
|
||||
FId:=TheID;
|
||||
fType:=aType;
|
||||
end;
|
||||
|
||||
{ TSourceMarklingProducer }
|
||||
|
||||
procedure TSourceMarklingProducer.InvalidateAllFiles;
|
||||
begin
|
||||
SourceEditorManagerIntf.InvalidateMarklingsOfAllFiles(Self);
|
||||
end;
|
||||
|
||||
procedure TSourceMarklingProducer.InvalidateFile(aFilename: string);
|
||||
begin
|
||||
SourceEditorManagerIntf.InvalidateMarklings(Self,aFilename);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user