IDE: added jump history from Martin

git-svn-id: trunk@15389 -
This commit is contained in:
mattias 2008-06-11 16:01:49 +00:00
parent efb0e8990c
commit c30b81fb48
9 changed files with 315 additions and 51 deletions

3
.gitattributes vendored
View File

@ -2091,6 +2091,9 @@ ide/initialsetupdlgs.pas svneol=native#text/pascal
ide/inputfiledialog.pas svneol=native#text/pascal
ide/inputhistory.pas svneol=native#text/pascal
ide/invertassigntool.pas svneol=native#text/pascal
ide/jumphistoryview.lfm svneol=native#text/plain
ide/jumphistoryview.lrs svneol=native#text/plain
ide/jumphistoryview.pas svneol=native#text/plain
ide/keymapping.pp svneol=native#text/pascal
ide/keymapschemedlg.lfm svneol=native#text/plain
ide/keymapschemedlg.lrs svneol=native#text/pascal

View File

@ -93,7 +93,8 @@ type
nmiwSearchResultsViewName,
nmiwAnchorEditor,
nmiwCodeBrowser,
mniwIssueBrowser
nmiwIssueBrowser,
nmiwJumpHistory
);
const
@ -132,7 +133,8 @@ const
'SearchResults',
'AnchorEditor',
'CodeBrowser',
'IssueBrowser'
'IssueBrowser',
'JumpHistory'
);
type

24
ide/jumphistoryview.lfm Normal file
View File

@ -0,0 +1,24 @@
object JumpHistoryViewWin: TJumpHistoryViewWin
Left = 336
Height = 426
Top = 228
Width = 400
ActiveControl = listHistory
Caption = 'JumpHistoryViewWin'
ClientHeight = 426
ClientWidth = 400
OnCreate = FormCreate
OnDestroy = FormDestroy
ShowHint = True
LCLVersion = '0.9.25'
object listHistory: TListBox
Height = 426
Width = 400
Align = alClient
ClickOnSelChange = False
OnClick = listHistoryClick
OnDblClick = listHistoryDblClick
TabOrder = 0
TopIndex = -1
end
end

10
ide/jumphistoryview.lrs Normal file
View File

@ -0,0 +1,10 @@
LazarusResources.Add('TJumpHistoryViewWin','FORMDATA',[
'TPF0'#19'TJumpHistoryViewWin'#18'JumpHistoryViewWin'#4'Left'#3'P'#1#6'Height'
+#3#170#1#3'Top'#3#228#0#5'Width'#3#144#1#13'ActiveControl'#7#11'listHistory'
+#7'Caption'#6#18'JumpHistoryViewWin'#12'ClientHeight'#3#170#1#11'ClientWidth'
+#3#144#1#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11'FormDestroy'#8'ShowH'
+'int'#9#10'LCLVersion'#6#6'0.9.25'#0#8'TListBox'#11'listHistory'#6'Height'#3
+#170#1#5'Width'#3#144#1#5'Align'#7#8'alClient'#16'ClickOnSelChange'#8#7'OnCl'
+'ick'#7#16'listHistoryClick'#10'OnDblClick'#7#19'listHistoryDblClick'#8'TabO'
+'rder'#2#0#8'TopIndex'#2#255#0#0#0
]);

181
ide/jumphistoryview.pas Normal file
View File

@ -0,0 +1,181 @@
{
***************************************************************************
* *
* This source is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This code is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* A copy of the GNU General Public License is available on the World *
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
* obtain it by writing to the Free Software Foundation, *
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
***************************************************************************
}
unit JumpHistoryView;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Menus, LCLProc,
CodeToolManager, CodeCache,
IDEOptionDefs, EnvironmentOpts, IDEProcs, LazarusIDEStrConsts,
Project, ProjectDefs;
type
{ TJumpHistoryViewWin }
TJumpHistoryViewWin = class(TForm)
listHistory : TListBox;
procedure FormCreate(Sender : TObject);
procedure FormDestroy(Sender : TObject);
procedure listHistoryClick(Sender : TObject);
procedure listHistoryDblClick(Sender : TObject);
procedure OnIdle(Sender : TObject; var Done: Boolean);
private
{ private declarations }
fOnSelectionChanged : TNotifyEvent;
fProjectChangeStamp: integer;
function GetSelectedIndex : Integer;
function BeautifyLine(const Filename: string; X, Y: integer;
const Line: string): string;
procedure InitDisplay;
protected
procedure IndexChanged(Sender: TObject; Index: Integer);
procedure ListChanged(Sender: TObject; Index: Integer);
public
{ public declarations }
property SelectedIndex : Integer read GetSelectedIndex;
property OnSelectionChanged: TNotifyEvent read fOnSelectionChanged
write fOnSelectionChanged;
end;
var
JumpHistoryViewWin : TJumpHistoryViewWin = nil;
implementation
const
MaxTextLen = 80;
{ TJumpHistoryViewWin }
procedure TJumpHistoryViewWin.FormCreate(Sender : TObject);
var
ALayout: TIDEWindowLayout;
begin
Caption := lisMenuViewJumpHistory;
Name := NonModalIDEWindowNames[nmiwJumpHistory];
ALayout:=EnvironmentOptions.IDEWindowLayoutList.
ItemByEnum(nmiwJumpHistory);
ALayout.Form:=TForm(Self);
ALayout.Apply;
Application.AddOnIdleHandler(@OnIdle);
InitDisplay;
end;
procedure TJumpHistoryViewWin.FormDestroy(Sender : TObject);
begin
end;
procedure TJumpHistoryViewWin.listHistoryClick(Sender : TObject);
begin
if EnvironmentOptions.MsgViewDblClickJumps then exit;
if Assigned(fOnSelectionChanged) then fOnSelectionChanged(self);
end;
procedure TJumpHistoryViewWin.listHistoryDblClick(Sender : TObject);
begin
if not EnvironmentOptions.MsgViewDblClickJumps then exit;
if Assigned(fOnSelectionChanged) then fOnSelectionChanged(self);
end;
procedure TJumpHistoryViewWin.OnIdle(Sender: TObject; var Done: Boolean);
begin
if (Project1<>nil)
and (Project1.JumpHistory.ChangeStamp<>fProjectChangeStamp) then
InitDisplay;
end;
function TJumpHistoryViewWin.GetSelectedIndex : Integer;
begin
Result := listHistory.ItemIndex;
end;
function TJumpHistoryViewWin.BeautifyLine(const Filename : string; X, Y : integer;
const Line : string) : string;
begin
Result:=SpecialCharsToHex(Line);
if UTF8Length(Result)>MaxTextLen then
Result:=UTF8Copy(Result,1,MaxTextLen)+'...';
Result:=Filename
+' ('+IntToStr(Y)
+','+IntToStr(X)+')'
+' '+Result;
end;
procedure TJumpHistoryViewWin.InitDisplay;
var
i : integer;
jh_item : TProjectJumpHistoryPosition;
SrcLine: String;
CodeBuf: TCodeBuffer;
Filename: String;
begin
if (Project1<>nil)
and (fProjectChangeStamp=Project1.JumpHistory.ChangeStamp) then exit;
listHistory.Items.BeginUpdate;
listHistory.Clear;
if (Project1<>nil) then begin
fProjectChangeStamp:=Project1.JumpHistory.ChangeStamp;
for i := 0 to Project1.JumpHistory.Count -1 do begin
jh_item := Project1.JumpHistory.Items[i];
SrcLine:='';
CodeBuf:=CodeToolBoss.FindFile(jh_item.Filename);
if CodeBuf<>nil then
SrcLine:=CodeBuf.GetLine(jh_item.CaretXY.Y);
Filename:=jh_item.Filename;
if Project1<>nil then
Project1.ShortenFilename(Filename);
listHistory.Items.Append
(BeautifyLine(Filename,
jh_item.CaretXY.X,
jh_item.CaretXY.Y,
SrcLine
)
);
end;
DebugLn(['TJumpHistoryViewWin.InitDisplay Project1.JumpHistory.HistoryIndex=',Project1.JumpHistory.HistoryIndex]);
listHistory.ItemIndex := Project1.JumpHistory.HistoryIndex;
end;
listHistory.Items.EndUpdate;
end;
procedure TJumpHistoryViewWin.IndexChanged(Sender : TObject; Index : Integer);
begin
listHistory.ItemIndex := Project1.JumpHistory.HistoryIndex;
end;
procedure TJumpHistoryViewWin.ListChanged(Sender : TObject; Index : Integer);
begin
InitDisplay;
end;
initialization
{$I jumphistoryview.lrs}
end.

View File

@ -514,6 +514,9 @@ type
// SearchResultsView events
procedure SearchResultsViewSelectionChanged(sender: TObject);
// JumpHistoryView events
procedure JumpHistoryViewSelectionChanged(sender: TObject);
// External Tools events
procedure OnExtToolNeedsOutputFilter(var OutputFilter: TOutputFilter;
var Abort: boolean);
@ -932,7 +935,7 @@ var
implementation
uses
Math;
Math, JumpHistoryView;
var
SkipAutoLoadingLastProject: boolean = false;
@ -1236,6 +1239,7 @@ begin
TheControlSelection.OnSelectionFormChanged:=nil;
end;
FreeAndNil(JumpHistoryViewWin);
FreeAndNil(ComponentListForm);
FreeThenNil(ProjInspector);
FreeThenNil(CodeExplorerView);
@ -12721,6 +12725,13 @@ begin
DoJumpToSearchResult(True);
end;
procedure TMainIDE.JumpHistoryViewSelectionChanged(sender : TObject);
begin
SourceNotebook.HistoryJump(self, jhaViewWindow);
SourceNoteBook.ShowOnTop;
SourceNotebook.FocusEditor;
end;
Procedure TMainIDE.OnSrcNotebookEditorVisibleChanged(Sender: TObject);
var
ActiveUnitInfo: TUnitInfo;
@ -13288,41 +13299,40 @@ var DestIndex, UnitIndex: integer;
AnUnitInfo: TUnitInfo;
DestJumpPoint: TProjectJumpHistoryPosition;
CursorPoint, NewJumpPoint: TProjectJumpHistoryPosition;
JumpHistory : TProjectJumpHistory;
begin
NewPageIndex:=-1;
NewCaretXY.Y:=-1;
JumpHistory:=Project1.JumpHistory;
{$IFDEF VerboseJumpHistory}
writeln('');
writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] A Back=',JumpAction=jhaBack);
Project1.JumpHistory.WriteDebugReport;
JumpHistory.WriteDebugReport;
{$ENDIF}
// update jump history (e.g. delete jumps to closed editors)
Project1.JumpHistory.DeleteInvalidPositions;
JumpHistory.DeleteInvalidPositions;
// get destination jump point
DestIndex:=Project1.JumpHistory.HistoryIndex;
if JumpAction=jhaForward then
inc(DestIndex);
if (DestIndex<0) or (DestIndex>=Project1.JumpHistory.Count) then exit;
DestIndex:=JumpHistory.HistoryIndex;
CursorPoint:=nil;
if (SourceNoteBook<>nil) then begin
// get current cursor position
GetCurrentUnit(ASrcEdit,AnUnitInfo);
if (ASrcEdit<>nil) and (AnUnitInfo<>nil) then begin
CursorPoint:=TProjectJumpHistoryPosition.Create(AnUnitInfo.Filename,
ASrcEdit.EditorComponent.LogicalCaretXY,
ASrcEdit.EditorComponent.TopLine);
{$IFDEF VerboseJumpHistory}
writeln(' Current Position: ',CursorPoint.Filename,
' ',CursorPoint.CaretXY.X,',',CursorPoint.CaretXY.Y);
{$ENDIF}
end;
// get current cursor position
GetCurrentUnit(ASrcEdit,AnUnitInfo);
if (ASrcEdit<>nil) and (AnUnitInfo<>nil) then begin
CursorPoint:=TProjectJumpHistoryPosition.Create
(AnUnitInfo.Filename,
ASrcEdit.EditorComponent.LogicalCaretXY,
ASrcEdit.EditorComponent.TopLine
);
{$IFDEF VerboseJumpHistory}
writeln(' Current Position: ',CursorPoint.Filename,
' ',CursorPoint.CaretXY.X,',',CursorPoint.CaretXY.Y-1);
{$ENDIF}
end;
if (JumpAction=jhaBack) and (Project1.JumpHistory.Count=DestIndex+1)
if (JumpAction=jhaBack) and (JumpHistory.Count=DestIndex+1)
and (CursorPoint<>nil) then begin
// this is the first back jump
// -> insert current source position into history
@ -13330,16 +13340,19 @@ begin
writeln(' First back jump -> add current cursor position');
{$ENDIF}
NewJumpPoint:=TProjectJumpHistoryPosition.Create(CursorPoint);
Project1.JumpHistory.InsertSmart(Project1.JumpHistory.HistoryIndex+1,
NewJumpPoint);
JumpHistory.InsertSmart(JumpHistory.HistoryIndex+1, NewJumpPoint);
end;
// find the next jump point that is not where the cursor is
DestIndex:=Project1.JumpHistory.HistoryIndex;
if JumpAction=jhaForward then
inc(DestIndex);
while (DestIndex>=0) and (DestIndex<Project1.JumpHistory.Count) do begin
DestJumpPoint:=Project1.JumpHistory[DestIndex];
case JumpAction of
jhaForward : inc(DestIndex);
// jhaBack : if (CursorPoint<>nil) and (JumpHistory[DestIndex].IsSimilar(CursorPoint))
// then dec(DestIndex);
jhaViewWindow : DestIndex := JumpHistoryViewWin.SelectedIndex;
end;
while (DestIndex>=0) and (DestIndex<JumpHistory.Count) do begin
DestJumpPoint:=JumpHistory[DestIndex];
UnitIndex:=Project1.IndexOfFilename(DestJumpPoint.Filename);
{$IFDEF VerboseJumpHistory}
writeln(' DestIndex=',DestIndex,' UnitIndex=',UnitIndex);
@ -13347,9 +13360,7 @@ begin
if (UnitIndex>=0) and (Project1.Units[UnitIndex].EditorIndex>=0)
and ((CursorPoint=nil) or not DestJumpPoint.IsSimilar(CursorPoint)) then
begin
if JumpAction=jhaBack then
dec(DestIndex);
Project1.JumpHistory.HistoryIndex:=DestIndex;
JumpHistory.HistoryIndex:=DestIndex;
NewCaretXY:=DestJumpPoint.CaretXY;
NewTopLine:=DestJumpPoint.TopLine;
NewPageIndex:=Project1.Units[UnitIndex].EditorIndex;
@ -13358,17 +13369,18 @@ begin
{$ENDIF}
break;
end;
if JumpAction=jhaBack then
dec(DestIndex)
else
inc(DestIndex);
case JumpAction of
jhaForward : inc(DestIndex);
jhaBack : dec(DestIndex);
jhaViewWindow : break;
end;
end;
CursorPoint.Free;
{$IFDEF VerboseJumpHistory}
writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] END Count=',Project1.JumpHistory.Count,',HistoryIndex=',Project1.JumpHistory.HistoryIndex);
Project1.JumpHistory.WriteDebugReport;
writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] END Count=',JumpHistory.Count,',HistoryIndex=',JumpHistory.HistoryIndex);
JumpHistory.WriteDebugReport;
writeln('');
{$ENDIF}
end;
@ -13390,9 +13402,13 @@ end;
Procedure TMainIDE.OnSrcNotebookViewJumpHistory(Sender: TObject);
begin
// ToDo
MessageDlg(ueNotImplCap, lisSorryNotImplementedYet, mtInformation,
[mbOk],0);
if JumpHistoryViewWin=nil then begin
JumpHistoryViewWin:=TJumpHistoryViewWin.Create(OwningComponent);
with JumpHistoryViewWin do begin
OnSelectionChanged := @JumpHistoryViewSelectionChanged;
end;
end;
JumpHistoryViewWin.ShowOnTop;
end;
procedure TMainIDE.OnSrcNotebookShowSearchResultsView(Sender: TObject);

View File

@ -227,15 +227,20 @@ type
TCheckPositionEvent =
function(APosition:TProjectJumpHistoryPosition): boolean of object;
{ TProjectJumpHistory }
TProjectJumpHistory = class
private
FChangeStamp: integer;
FHistoryIndex: integer;
FOnCheckPosition: TCheckPositionEvent;
FPositions:TList; // list of TProjectJumpHistoryPosition
FMaxCount: integer;
fOnLoadSaveFilename: TOnLoadSaveFilename;
function GetPositions(Index:integer):TProjectJumpHistoryPosition;
procedure SetHistoryIndex(const AIndex : integer);
procedure SetPositions(Index:integer; APosition: TProjectJumpHistoryPosition);
procedure IncreaseChangeStamp;
public
function Add(APosition: TProjectJumpHistoryPosition):integer;
function AddSmart(APosition: TProjectJumpHistoryPosition):integer;
@ -256,7 +261,7 @@ type
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
procedure WriteDebugReport;
property HistoryIndex: integer read FHistoryIndex write FHistoryIndex;
property HistoryIndex: integer read FHistoryIndex write SetHistoryIndex;
property Items[Index:integer]:TProjectJumpHistoryPosition
read GetPositions write SetPositions; default;
property MaxCount: integer read FMaxCount write FMaxCount;
@ -264,6 +269,7 @@ type
read FOnCheckPosition write FOnCheckPosition;
property OnLoadSaveFilename: TOnLoadSaveFilename
read fOnLoadSaveFilename write fOnLoadSaveFilename;
property ChangeStamp: integer read FChangeStamp;
end;
//---------------------------------------------------------------------------
@ -526,6 +532,13 @@ begin
Result:=TProjectJumpHistoryPosition(FPositions[Index]);
end;
procedure TProjectJumpHistory.SetHistoryIndex(const AIndex : integer);
begin
if FHistoryIndex=AIndex then exit;
FHistoryIndex := AIndex;
IncreaseChangeStamp;
end;
procedure TProjectJumpHistory.SetPositions(Index:integer;
APosition: TProjectJumpHistoryPosition);
begin
@ -533,6 +546,15 @@ begin
raise Exception.Create('TProjectJumpHistory.SetPositions: Index '
+IntToStr(Index)+' out of bounds. Count='+IntToStr(Count));
Items[Index].Assign(APosition);
IncreaseChangeStamp;
end;
procedure TProjectJumpHistory.IncreaseChangeStamp;
begin
if FChangeStamp<High(FChangeStamp) then
inc(FChangeStamp)
else
FChangeStamp:=Low(FChangeStamp);
end;
function TProjectJumpHistory.Add(
@ -540,7 +562,8 @@ function TProjectJumpHistory.Add(
begin
Result:=FPositions.Add(APosition);
APosition.OnLoadSaveFilename:=OnLoadSaveFilename;
FHistoryIndex:=Count-1;
IncreaseChangeStamp;
HistoryIndex:=Count-1;
if Count>MaxCount then DeleteFirst;
end;
@ -560,7 +583,7 @@ constructor TProjectJumpHistory.Create;
begin
inherited Create;
FPositions:=TList.Create;
FHistoryIndex:=-1;
HistoryIndex:=-1;
FMaxCount:=30;
end;
@ -570,7 +593,8 @@ begin
for i:=0 to Count-1 do
Items[i].Free;
FPositions.Clear;
FHistoryIndex:=-1;
HistoryIndex:=-1;
IncreaseChangeStamp;
end;
function TProjectJumpHistory.Count:integer;
@ -582,7 +606,8 @@ procedure TProjectJumpHistory.Delete(Index:integer);
begin
Items[Index].Free;
FPositions.Delete(Index);
if FHistoryIndex>=Index then dec(FHistoryIndex);
IncreaseChangeStamp;
if FHistoryIndex>=Index then HistoryIndex := FHistoryIndex - 1;
end;
destructor TProjectJumpHistory.Destroy;
@ -625,7 +650,7 @@ begin
if NewPosition<>nil then NewPosition.Free;
if (NewHistoryIndex<0) or (NewHistoryIndex>=Count) then
NewHistoryIndex:=Count-1;
FHistoryIndex:=NewHistoryIndex;
HistoryIndex:=NewHistoryIndex;
end;
procedure TProjectJumpHistory.SaveToXMLConfig(XMLConfig: TXMLConfig;
@ -692,10 +717,11 @@ begin
if Index<0 then Index:=0;
if Index>Count then Index:=Count;
FPositions.Insert(Index,APosition);
IncreaseChangeStamp;
if (FHistoryIndex<0) and (Count=1) then
FHistoryIndex:=0
HistoryIndex:=0
else if FHistoryIndex>=Index then
inc(FHistoryIndex);
HistoryIndex := FHistoryIndex + 1;
end;
procedure TProjectJumpHistory.InsertSmart(Index: integer;
@ -713,6 +739,7 @@ begin
// ' New=',APosition.CaretXY.X,',',APosition.CaretXY.Y,' ',APosition.Filename,
// ' ');
Items[Index-1]:=APosition;
IncreaseChangeStamp;
NewIndex:=Index-1;
APosition.Free;
end else if (Index<Count) and Items[Index].IsSimilar(APosition) then begin
@ -721,6 +748,7 @@ begin
// ' New=',APosition.CaretXY.X,',',APosition.CaretXY.Y,' ',APosition.Filename,
// ' ');
Items[Index]:=APosition;
IncreaseChangeStamp;
NewIndex:=Index;
APosition.Free;
end else begin

View File

@ -72,7 +72,7 @@ var
begin
FIssueList := GetRestrictedList;
Name := NonModalIDEWindowNames[mniwIssueBrowser];
Name := NonModalIDEWindowNames[nmiwIssueBrowser];
Caption := lisMenuViewRestrictionBrowser;
EnvironmentOptions.IDEWindowLayoutList.Apply(Self, Name);

View File

@ -378,7 +378,7 @@ type
{ TSourceNotebook }
TJumpHistoryAction = (jhaBack, jhaForward);
TJumpHistoryAction = (jhaBack, jhaForward, jhaViewWindow);
TOnJumpToHistoryPoint = procedure(var NewCaretXY: TPoint;
var NewTopLine, NewPageIndex: integer;