SourceEditor: allow to lock pages (against topline changes)

git-svn-id: trunk@24725 -
This commit is contained in:
martin 2010-04-20 00:01:36 +00:00
parent e783e90ae8
commit 4e4dced49a
6 changed files with 274 additions and 59 deletions

View File

@ -471,6 +471,8 @@ begin
ecGotoEditor9: SetResult(VK_9,[ssAlt],VK_UNKNOWN,[]);
ecGotoEditor0: SetResult(VK_0,[ssAlt],VK_UNKNOWN,[]);
ecLockEditor: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
EcFoldLevel1: SetResult(VK_1,[ssAlt,ssShift],VK_UNKNOWN,[]);
EcFoldLevel2: SetResult(VK_2,[ssAlt,ssShift],VK_UNKNOWN,[]);
EcFoldLevel3: SetResult(VK_3,[ssAlt,ssShift],VK_UNKNOWN,[]);
@ -903,6 +905,8 @@ begin
ecGotoEditor9: SetResult(VK_9,[ssAlt],VK_UNKNOWN,[],VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecGotoEditor0: SetResult(VK_0,[ssAlt],VK_UNKNOWN,[],VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecLockEditor: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
EcFoldLevel1: SetResult(VK_1,[ssAlt,ssShift],VK_UNKNOWN,[],VK_UNKNOWN,[],VK_UNKNOWN,[]);
EcFoldLevel2: SetResult(VK_2,[ssAlt,ssShift],VK_UNKNOWN,[],VK_UNKNOWN,[],VK_UNKNOWN,[]);
EcFoldLevel3: SetResult(VK_3,[ssAlt,ssShift],VK_UNKNOWN,[],VK_UNKNOWN,[],VK_UNKNOWN,[]);
@ -1515,6 +1519,8 @@ begin
ecGotoEditor9: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecGotoEditor0: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecLockEditor: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
(*
EcFoldLevel1: SetResult(VK_1,[ssMeta,ssShift],VK_UNKNOWN,[]);
EcFoldLevel2: SetResult(VK_2,[ssMeta,ssShift],VK_UNKNOWN,[]);
@ -1967,6 +1973,8 @@ begin
ecCopyEditorPrevWindow: Result := srkmecCopyEditorPrevWindow;
ecCopyEditorNewWindow: Result := srkmecCopyEditorNewWindow;
ecLockEditor: Result := srkmecLockEditor;
ecGotoEditor1..
ecGotoEditor0 : Result:= Format(srkmecGotoEditor,[cmd-ecGotoEditor1]);
EcFoldLevel1..
@ -2722,6 +2730,8 @@ begin
AddDefault(C, 'Copy to prior window', srkmecCopyEditorPrevWindow, ecCopyEditorPrevWindow);
AddDefault(C, 'Copy to new window', srkmecCopyEditorNewWindow, ecCopyEditorNewWindow);
AddDefault(C, 'Lock editor', srkmecLockEditor, ecLockEditor);
// file menu
C:=Categories[AddCategory('FileMenu',srkmCatFileMenu,nil)];
AddDefault(C, 'New', lisMenuTemplateNew, ecNew);

View File

@ -2009,6 +2009,7 @@ resourcestring
uemProcedureJump = 'Procedure Jump';
uemClosePage = '&Close Page';
uemCloseOtherPages = 'Close All &Other Pages';
uemLockPage = '&Lock Page';
uemCopyToNewWindow = 'Copy to new Window';
uemCopyToOtherWindow = 'Copy to other Window';
uemCopyToOtherWindowNew = 'New Window';
@ -2068,6 +2069,7 @@ resourcestring
ueFileROText1='The file "';
ueFileROText2='" is not writable.';
ueModified='Modified';
ueLocked='Locked';
uepReadonly= 'Readonly';
uepIns='INS';
uepOvr='OVR';
@ -2303,6 +2305,7 @@ resourcestring
srkmecCopyEditorNextWindow = 'Copy editor to next free window';
srkmecCopyEditorPrevWindow = 'Copy editor to prior free window';
srkmecCopyEditorNewWindow = 'Copy editor to new window';
srkmecLockEditor = 'Lock Editor';
lisKMGoToSourceEditor1 = 'Go to source editor 1';
lisKMGoToSourceEditor2 = 'Go to source editor 2';
@ -2956,7 +2959,7 @@ resourcestring
lisUEReplaceThisOccurrenceOfWith = 'Replace this occurrence of %s%s%s%s '
+'with %s%s%s?';
lisUESearching = 'Searching: %s';
lisUEReadOnly = '%s/ReadOnly';
lisUEModeSeparator = '/';
lisUEGotoLine = 'Goto line:';
lisGotoLine = 'Goto line';

View File

@ -809,6 +809,9 @@ type
): string; override;
procedure MarkUnitsModifiedUsingSubComponent(SubComponent: TComponent);
function GetAvailableUnitEditorInfo(AnUnitInfo: TUnitInfo;
ACaretPoint: TPoint; WantedTopLine: integer = -1): TUnitEditorInfo;
// project(s)
procedure DoLoadDefaultCompilerOptions(AProject: TProject);
function DoNewProject(ProjectDesc: TProjectDescriptor): TModalResult; override;
@ -7692,7 +7695,10 @@ begin
//DebugLn(['TMainIDE.DoOpenFileInSourceEditor NewCaretXY=',dbgs(NewCaretXY),' NewTopLine=',NewTopLine]);
end;
NewSrcEdit.IsLocked := AnEditorInfo.IsLocked;
AnEditorInfo.EditorComponent := NewSrcEdit;
if (not (ofProjectLoading in Flags)) then
OnSrcNotebookEditorVisibleChanged(NewSrcEdit.SourceNotebook);
//debugln(['TMainIDE.DoOpenFileInSourceEditor ',AnUnitInfo.Filename,' ',AnUnitInfo.EditorIndex]);
// restore source editor settings
@ -7722,8 +7728,8 @@ begin
// update statusbar and focus editor
if (not (ofProjectLoading in Flags)) then begin
SrcNotebook.ShowOnTop;
SrcNotebook.FocusEditor;
SourceEditorManager.ActiveEditor := NewSrcEdit;
SourceEditorManager.ShowActiveWindowOnTop(True);
end;
SrcNoteBook.UpdateStatusBar;
SrcNotebook.BringToFront;
@ -7853,6 +7859,7 @@ begin
MainIDEBar.itmFileCloseAll.Enabled:=True;
NewSrcEdit.SyntaxHighlighterType:=NewUnitInfo.EditorInfo[0].SyntaxHighlighter;
NewUnitInfo.GetClosedOrNewEditorInfo.EditorComponent := NewSrcEdit;
OnSrcNotebookEditorVisibleChanged(NewSrcEdit.SourceNotebook);
// create component
AncestorType:=NewFileDescriptor.ResourceClass;
@ -9031,6 +9038,51 @@ begin
UnitList.Free;
end;
function TMainIDE.GetAvailableUnitEditorInfo(AnUnitInfo: TUnitInfo;
ACaretPoint: TPoint; WantedTopLine: integer = -1): TUnitEditorInfo;
var
i: Integer;
begin
Result := nil;
if AnUnitInfo.OpenEditorInfoCount = 0 then
exit;
// find caret on screen, rather than last focused
i := 0;
while (i < AnUnitInfo.OpenEditorInfoCount) do begin
Result := AnUnitInfo.OpenEditorInfo[i];
if TSourceEditor(Result.EditorComponent).IsCaretOnScreen(ACaretPoint,
not TSourceEditor(Result.EditorComponent).IsLocked)
or (TSourceEditor(Result.EditorComponent).TopLine = WantedTopLine)
then
exit;
inc(i);
end;
// find unlocked
i := 0;
while (i < AnUnitInfo.OpenEditorInfoCount) do begin
Result := AnUnitInfo.OpenEditorInfo[i];
if (not TSourceEditor(Result.EditorComponent).IsLocked) or
TSourceEditor(Result.EditorComponent).IsCaretOnScreen(ACaretPoint)
then
exit;
inc(i);
end;
// open new copy
i := 0;
if AnUnitInfo.OpenEditorInfoCount > 0 then
while (i < SourceEditorManager.SourceWindowCount) and
(SourceEditorManager.SourceWindowByLastFocused[i].IndexOfEditorInShareWith
(TSourceEditor(AnUnitInfo.OpenEditorInfo[0].EditorComponent)) >= 0)
do
inc(i);
if i < SourceEditorManager.SourceWindowCount then
i := SourceEditorManager.IndexOfSourceWindow(SourceEditorManager.SourceWindowByLastFocused[i]);
if DoOpenFileInSourceEditor(AnUnitInfo.GetClosedOrNewEditorInfo, -1, i, []) = mrOk then
Result := AnUnitInfo.OpenEditorInfo[0]
else
Result := nil;
end;
function TMainIDE.LoadIDECodeBuffer(var ACodeBuffer: TCodeBuffer;
const AFilename: string; Flags: TLoadBufferFlags; ShowAbort: boolean
): TModalResult;
@ -12363,9 +12415,10 @@ var
AFileName: string;
SearchedFilename: string;
LogCaretXY: TPoint;
TopLine: integer;
OpenFlags: TOpenFlags;
SrcEdit: TSourceEditor;
AnUnitInfo: TUnitInfo;
AnEditorInfo: TUnitEditorInfo;
begin
Result:=false;
if pos('(',SearchResultsView.GetSelectedText) > 0 then
@ -12382,21 +12435,28 @@ begin
end;
if SearchedFilename<>'' then begin
// open the file in the source editor
Result:=(DoOpenEditorFile(SearchedFilename,-1,-1,OpenFlags)=mrOk);
AnUnitInfo := Project1.UnitInfoWithFilename(SearchedFilename);
AnEditorInfo := nil;
if AnUnitInfo <> nil then
AnEditorInfo := GetAvailableUnitEditorInfo(AnUnitInfo, LogCaretXY);
if AnEditorInfo <> nil then begin
SourceEditorManager.ActiveEditor := TSourceEditor(AnEditorInfo.EditorComponent);
Result := True;
end else
Result:=(DoOpenEditorFile(SearchedFilename,-1,-1,OpenFlags)=mrOk);
if Result then begin
// set caret position
SourceEditorManager.AddJumpPointClicked(Self);
SrcEdit:=SourceEditorManager.ActiveEditor;
if LogCaretXY.Y>SrcEdit.EditorComponent.Lines.Count then
LogCaretXY.Y:=SrcEdit.EditorComponent.Lines.Count;
TopLine:=LogCaretXY.Y-(SrcEdit.EditorComponent.LinesInWindow div 2);
if TopLine<1 then TopLine:=1;
if FocusEditor then begin
SearchResultsView.ShowOnTop;
SourceEditorManager.ShowActiveWindowOnTop(True);
end;
SrcEdit.EditorComponent.LogicalCaretXY:=LogCaretXY;
SrcEdit.EditorComponent.TopLine:=TopLine;
if not SrcEdit.IsLocked then
SrcEdit.CenterCursor(True);
with SrcEdit.EditorComponent do begin
LeftChar:= Math.Max(LogCaretXY.X-CharsInWindow,1);
end;
@ -13638,7 +13698,7 @@ function TMainIDE.DoJumpToCodePos(
AddJumpPoint: boolean; FocusEditor: boolean; MarkLine: Boolean): TModalResult;
var
NewSrcEdit: TSourceEditor;
LinesInWin, MinLines, CurTopLine: Integer;
AnEditorInfo: TUnitEditorInfo;
begin
Result:=mrCancel;
if NewSource=nil then begin
@ -13661,7 +13721,16 @@ begin
if (ActiveUnitInfo = nil) or (NewSource<>ActiveUnitInfo.Source)
then begin
// jump to other file -> open it
Result:=DoOpenEditorFile(NewSource.Filename,-1,-1,[ofOnlyIfExists,ofRegularFile]);
ActiveUnitInfo := Project1.UnitInfoWithFilename(NewSource.Filename);
AnEditorInfo := nil;
if ActiveUnitInfo <> nil then
AnEditorInfo := GetAvailableUnitEditorInfo(ActiveUnitInfo, Point(NewX,NewY), NewTopLine);
if AnEditorInfo <> nil then begin
SourceEditorManager.ActiveEditor := TSourceEditor(AnEditorInfo.EditorComponent);
Result := mrOK;
end
else
Result:=DoOpenEditorFile(NewSource.Filename,-1,-1,[ofOnlyIfExists,ofRegularFile]);
if Result<>mrOk then begin
UpdateSourceNames;
exit;
@ -13669,31 +13738,26 @@ begin
NewSrcEdit := SourceEditorManager.ActiveEditor;
end
else begin
NewSrcEdit:=ActiveSrcEdit;
AnEditorInfo := GetAvailableUnitEditorInfo(ActiveUnitInfo, Point(NewX,NewY), NewTopLine);
if AnEditorInfo <> nil then begin
NewSrcEdit := TSourceEditor(AnEditorInfo.EditorComponent);
SourceEditorManager.ActiveEditor := NewSrcEdit;
end
else
NewSrcEdit:=ActiveSrcEdit;
end;
if NewX<1 then NewX:=1;
if NewY<1 then NewY:=1;
if NewTopLine<1 then begin
CurTopLine := NewSrcEdit.EditorComponent.TopLine;
LinesInWin := NewSrcEdit.EditorComponent.LinesInWindow;
MinLines := Min(Max(LinesInWin div 5, 2), LinesInWin div 3);
if (NewY <= CurTopLine) or (NewY >= CurTopLine + LinesInWin)
then
NewTopLine := Max(1, NewY - (LinesInWin div 2))
else
if NewY < CurTopLine + MinLines then
NewTopLine := Max(1, NewY - MinLines)
else
if NewY > CurTopLine + LinesInWin - MinLines then
NewTopLine := Max(1, NewY - LinesInWin + MinLines)
else
NewTopLine := CurTopLine;
end;
//debugln(['[TMainIDE.DoJumpToCodePos] ',NewX,',',NewY,',',NewTopLine]);
with NewSrcEdit.EditorComponent do
begin
MoveLogicalCaretIgnoreEOL(Point(NewX,NewY));
TopLine:=NewTopLine;
if not NewSrcEdit.IsLocked then begin
if NewTopLine < 1 then
NewSrcEdit.CenterCursor(True)
else
TopLine:=NewTopLine;
end;
//DebugLn('TMainIDE.DoJumpToCodePos NewY=',dbgs(NewY),' ',dbgs(TopLine),' ',dbgs(NewTopLine));
LeftChar:=Max(NewX-CharsInWindow,1);
end;
@ -14641,14 +14705,24 @@ var
function GetSrcEdit(AMark: TProjectBookmark): TSourceEditor;
var
UInf: TUnitInfo;
i: Integer;
i, j: Integer;
begin
if AMark.UnitInfo is TSourceEditor
then Result := TSourceEditor(AMark.UnitInfo)
else begin // find the nearest open View
UInf := TUnitInfo(AMark.UnitInfo);
Result := TSourceEditor(UInf.OpenEditorInfo[0].EditorComponent);
for i := 1 to UInf.OpenEditorInfoCount - 1 do
j := 0;
while (j < UInf.OpenEditorInfoCount) and
(Result.IsLocked) and (not Result.IsCaretOnScreen(AMark.CursorPos))
do begin
inc(j);
if j < UInf.OpenEditorInfoCount then
Result := TSourceEditor(UInf.OpenEditorInfo[j].EditorComponent);
end;
if j >= UInf.OpenEditorInfoCount then
exit(nil);
for i := j + 1 to UInf.OpenEditorInfoCount - 1 do
begin
if (not Backward) and
(GetWinForEdit(Result) > GetWinForEdit(TSourceEditor(UInf.OpenEditorInfo[i].EditorComponent)) )
@ -14697,6 +14771,7 @@ var
i: Integer;
CurPos, CurFound: TProjectBookmark;
AnUnitInfo: TUnitInfo;
AnEditorInfo: TUnitEditorInfo;
begin
if ID < 0 then begin
// ID < 0 => next/prev
@ -14713,7 +14788,8 @@ begin
CurFound := nil;
i := 0;
while (i < Project1.Bookmarks.Count) and
(CompareBookmarkEditorPos(CurPos, Project1.Bookmarks[i]) = 0)
( (GetSrcEdit(Project1.Bookmarks[i]) = nil) or
(CompareBookmarkEditorPos(CurPos, Project1.Bookmarks[i]) = 0) )
do
inc(i);
if i >= Project1.Bookmarks.Count then
@ -14722,15 +14798,17 @@ begin
CurFound := Project1.Bookmarks[i];
inc(i);
while (i < Project1.Bookmarks.Count) do begin
if (CompareBookmarkEditorPos(CurPos, Project1.Bookmarks[i]) <> 0) then begin
if (not Backward) and
(CompareBookmarkEditorPos(Project1.Bookmarks[i], CurFound) > 0)
then
CurFound := Project1.Bookmarks[i];
if (Backward) and
(CompareBookmarkEditorPos(Project1.Bookmarks[i], CurFound) < 0)
then
CurFound := Project1.Bookmarks[i];
if (GetSrcEdit(Project1.Bookmarks[i]) <> nil) then begin
if (CompareBookmarkEditorPos(CurPos, Project1.Bookmarks[i]) <> 0) then begin
if (not Backward) and
(CompareBookmarkEditorPos(Project1.Bookmarks[i], CurFound) > 0)
then
CurFound := Project1.Bookmarks[i];
if (Backward) and
(CompareBookmarkEditorPos(Project1.Bookmarks[i], CurFound) < 0)
then
CurFound := Project1.Bookmarks[i];
end;
end;
inc(i);
end;
@ -14744,17 +14822,22 @@ begin
AnEditor := GetSrcEdit(CurFound);
end
else begin
AnEditor := nil;
AnUnitInfo := TUnitInfo(Project1.Bookmarks.UnitInfoForBookmarkWithIndex(ID));
if (AnUnitInfo <> nil) and (AnUnitInfo.OpenEditorInfoCount > 0) then
AnEditor := TSourceEditor(AnUnitInfo.OpenEditorInfo[0].EditorComponent);
if AnEditor = nil then exit;
AnEditor := nil;
AnUnitInfo := TUnitInfo(Project1.Bookmarks.UnitInfoForBookmarkWithIndex(ID));
AnEditorInfo := nil;
if (AnUnitInfo <> nil) and (AnUnitInfo.OpenEditorInfoCount > 0) then
AnEditorInfo := GetAvailableUnitEditorInfo(AnUnitInfo,
Project1.Bookmarks.BookmarkWithID(ID).CursorPos);
if AnEditorInfo <> nil then
AnEditor := TSourceEditor(AnEditorInfo.EditorComponent);
if AnEditor = nil then exit;
end;
SourceEditorManager.ActiveEditor := AnEditor;
SourceEditorManager.ShowActiveWindowOnTop(True);
AnEditor.EditorComponent.GotoBookMark(ID);
AnEditor.CenterCursor;
if not AnEditor.IsLocked then
AnEditor.CenterCursor(True);
end;
//this is fired when the editor is focused, changed, ?. Anything that causes the status change
@ -14775,6 +14858,7 @@ begin
if p <> nil then begin
p.PageIndex := SrcEdit.PageIndex;
p.WindowIndex := SourceEditorManager.IndexOfSourceWindow(SrcEdit.SourceNotebook);
p.IsLocked := SrcEdit.IsLocked;
end
else if SrcEdit.IsNewSharedEditor then begin
// attach to UnitInfo
@ -15360,6 +15444,7 @@ var DestIndex, UnitIndex: integer;
DestJumpPoint: TProjectJumpHistoryPosition;
CursorPoint, NewJumpPoint: TProjectJumpHistoryPosition;
JumpHistory : TProjectJumpHistory;
AnEditorInfo: TUnitEditorInfo;
begin
DestEditor := nil;
NewCaretXY.Y:=-1;
@ -15423,7 +15508,9 @@ begin
JumpHistory.HistoryIndex:=DestIndex;
NewCaretXY:=DestJumpPoint.CaretXY;
NewTopLine:=DestJumpPoint.TopLine;
DestEditor:=TSourceEditor(Project1.Units[UnitIndex].OpenEditorInfo[0].EditorComponent);
AnEditorInfo := GetAvailableUnitEditorInfo(Project1.Units[UnitIndex], NewCaretXY);
if AnEditorInfo <> nil then
DestEditor:=TSourceEditor(AnEditorInfo.EditorComponent);
{$IFDEF VerboseJumpHistory}
writeln('[TMainIDE.OnSrcNotebookJumpToHistoryPoint] Result Line=',NewCaretXY.Y,' Col=',NewCaretXY.X);
{$ENDIF}

View File

@ -171,6 +171,7 @@ type
FUnitInfo: TUnitInfo;
procedure SetEditorComponent(const AValue: TSourceEditorInterface);
private
FIsLocked: Boolean;
FIsVisibleTab: Boolean;
FPageIndex: integer;
FWindowIndex: integer;
@ -200,6 +201,7 @@ type
property TopLine: Integer read FTopLine write FTopLine;
property CursorPos: TPoint read FCursorPos write FCursorPos;
property FoldState: String read FFoldState write FFoldState;
property IsLocked: Boolean read FIsLocked write FIsLocked;
property CustomHighlighter: Boolean read FCustomHighlighter write FCustomHighlighter; // SetCustomHighlighter
property SyntaxHighlighter: TLazSyntaxHighlighter read FSyntaxHighlighter write FSyntaxHighlighter; // SetSyntaxHighlighter
end;
@ -1093,6 +1095,7 @@ begin
FEditorComponent := AValue;
UnitInfo.FEditorInfoList.MakeUnUsedEditorInfo(Self);
PageIndex := -1; // calls UnitInfo.UpdatePageIndex
IsLocked := False;
end
else begin
PageIndex := -1;
@ -1166,6 +1169,7 @@ begin
CursorPos := Point(XMLConfig.GetValue(Path+'CursorPos/X',-1),
XMLConfig.GetValue(Path+'CursorPos/Y',-1));
FFoldState := XMLConfig.GetValue(Path+'FoldState/Value', '');
FIsLocked := XMLConfig.GetValue(Path+'IsLocked/Value', False);
FSyntaxHighlighter := StrToLazSyntaxHighlighter(
XMLConfig.GetValue(Path+'SyntaxHighlighter/Value',
LazSyntaxHighlighterNames[UnitInfo.DefaultSyntaxHighlighter]));
@ -1179,6 +1183,7 @@ begin
XMLConfig.SetDeleteValue(Path+'TopLine/Value', FTopLine, -1);
XMLConfig.SetDeleteValue(Path+'CursorPos/X', FCursorPos.X, -1);
XMLConfig.SetDeleteValue(Path+'CursorPos/Y', FCursorPos.Y, -1);
XMLConfig.SetDeleteValue(Path+'IsLocked/Value', FIsLocked, False);
XMLConfig.SetDeleteValue(Path+'FoldState/Value', FoldState, '');
XMLConfig.SetDeleteValue(Path+'SyntaxHighlighter/Value',
LazSyntaxHighlighterNames[fSyntaxHighlighter],

View File

@ -201,6 +201,7 @@ type
private
//FAOwner is normally a TSourceNotebook. This is set in the Create constructor.
FAOwner: TComponent;
FIsLocked: Boolean;
FIsNewSharedEditor: Boolean;
FSharedValues: TSourceEditorSharedValues;
FEditor: TIDESynEditor;
@ -245,6 +246,7 @@ type
function GetSharedEditors(Index: Integer): TSourceEditor;
procedure SetCodeBuffer(NewCodeBuffer: TCodeBuffer);
function GetSource: TStrings;
procedure SetIsLocked(const AValue: Boolean);
procedure SetPageName(const AValue: string);
procedure UpdateExecutionSourceMark;
procedure UpdatePageName;
@ -392,7 +394,7 @@ type
function CaretInSelection(const ACaretPos: TPoint): Boolean;
// cursor
procedure CenterCursor;
procedure CenterCursor(SoftCenter: Boolean = False);
function TextToScreenPosition(const Position: TPoint): TPoint; override;
function ScreenToTextPosition(const Position: TPoint): TPoint; override;
function ScreenToPixelPosition(const Position: TPoint): TPoint; override;
@ -407,6 +409,7 @@ type
function GetTopLine: Integer; override;
procedure SetTopLine(const AValue: Integer); override;
function CursorInPixel: TPoint; override;
function IsCaretOnScreen(ACaret: TPoint; UseSoftCenter: Boolean = False): Boolean;
// text
function SearchReplace(const ASearch, AReplace: string;
@ -468,6 +471,7 @@ type
function SharedEditorCount: Integer;
property SharedEditors[Index: Integer]: TSourceEditor read GetSharedEditors;
property IsNewSharedEditor: Boolean read FIsNewSharedEditor write FIsNewSharedEditor;
property IsLocked: Boolean read FIsLocked write SetIsLocked;
end;
//============================================================================
@ -596,6 +600,7 @@ type
procedure SrcEditMenuCopyToExistingWindowClicked(Sender: TObject);
procedure SrcEditMenuMoveToNewWindowClicked(Sender: TObject);
procedure SrcEditMenuMoveToExistingWindowClicked(Sender: TObject);
procedure EditorLockClicked(Sender: TObject);
public
procedure DeleteBreakpointClicked(Sender: TObject);
procedure ToggleBreakpointClicked(Sender: TObject);
@ -668,7 +673,6 @@ type
procedure EditorChanged(Sender: TObject);
procedure DoClose(var CloseAction: TCloseAction); override;
function IndexOfEditorInShareWith(AnOtherEditor: TSourceEditor): Integer;
protected
function GetActiveCompletionPlugin: TSourceEditorCompletionPlugin; override;
function GetCompletionPlugins(Index: integer): TSourceEditorCompletionPlugin; override;
@ -781,6 +785,7 @@ type
EditorComp: TComponent): TSourceEditor;
function GetActiveSE: TSourceEditor; { $note deprecate and use SetActiveEditor}
procedure CheckCurrentCodeBufferChanged;
function IndexOfEditorInShareWith(AnOtherEditor: TSourceEditor): Integer;
procedure UpdateStatusBar;
procedure ClearErrorLines; override;
@ -826,11 +831,13 @@ type
private
FActiveWindow: TSourceNotebook;
FSourceWindowList: TFPList;
FSourceWindowByFocusList: TFPList;
FUpdateLock: Integer;
FShowWindowOnTop: Boolean;
FShowWindowOnTopFocus: Boolean;
procedure FreeSourceWindows;
function GetActiveSourceWindowIndex: integer;
function GetSourceWindowByLastFocused(Index: Integer): TSourceEditorWindowInterface;
procedure SetActiveSourceWindowIndex(const AValue: integer);
protected
FChangeNotifyLists: Array [TsemChangeReason] of TMethodList;
@ -849,6 +856,9 @@ type
function IndexOfSourceWindow(AWindow: TSourceEditorWindowInterface): integer;
property ActiveSourceWindowIndex: integer
read GetActiveSourceWindowIndex write SetActiveSourceWindowIndex;
function IndexOfSourceWindowByLastFocused(AWindow: TSourceEditorWindowInterface): integer;
property SourceWindowByLastFocused[Index: Integer]: TSourceEditorWindowInterface
read GetSourceWindowByLastFocused;
// Editors
function SourceEditorIntfWithFilename(const Filename: string): TSourceEditorInterface;
override;
@ -910,6 +920,7 @@ type
function GetActiveSrcEditor: TSourceEditor;
function GetSourceEditorsByPage(WindowIndex, PageIndex: integer
): TSourceEditor;
function GetSourceNbByLastFocused(Index: Integer): TSourceNotebook;
function GetSrcEditors(Index: integer): TSourceEditor;
procedure SetActiveSourceNotebook(const AValue: TSourceNotebook);
function GetSourceNotebook(Index: integer): TSourceNotebook;
@ -924,6 +935,8 @@ type
function ActiveOrNewSourceWindow: TSourceNotebook;
function NewSourceWindow: TSourceNotebook;
function SourceWindowWithPage(const APage: TPage): TSourceNotebook;
property SourceWindowByLastFocused[Index: Integer]: TSourceNotebook
read GetSourceNbByLastFocused;
// Editors
function SourceEditorCount: integer; override;
function GetActiveSE: TSourceEditor; { $note deprecate and use ActiveEditor}
@ -1174,6 +1187,8 @@ var
SrcEditMenuCopyToOtherWindow: TIDEMenuSection;
SrcEditMenuCopyToOtherWindowNew: TIDEMenuCommand;
SrcEditMenuCopyToOtherWindowList: TIDEMenuSection;
// EditorLocks
SrcEditMenuEditorLock: TIDEMenuCommand;
{$ENDIF}
@ -1242,6 +1257,10 @@ begin
'Close All Other Pages',uemCloseOtherPages, nil, nil, nil);
{$IFnDEF SingleSrcWindow}
// Lock Editor
SrcEditMenuEditorLock := RegisterIDEMenuCommand(SrcEditMenuSectionPages,
'LockEditor', uemLockPage);
SrcEditMenuEditorLock.ShowAlwaysCheckable := True;
// Move to other Window
SrcEditMenuMoveToNewWindow := RegisterIDEMenuCommand(SrcEditMenuSectionPages,
'MoveToNewWindow', uemMoveToNewWindow);
@ -2901,6 +2920,9 @@ Begin
ecInsertCVSSource:
InsertCVSKeyword('Source');
ecLockEditor:
IsLocked := not IsLocked;
else
begin
Handled:=false;
@ -3857,6 +3879,15 @@ Begin
Result := FEditor.Lines;
end;
procedure TSourceEditor.SetIsLocked(const AValue: Boolean);
begin
if FIsLocked = AValue then exit;
FIsLocked := AValue;
UpdatePageName;
SourceNotebook.UpdateStatusBar;
UpdateProjectFile;
end;
procedure TSourceEditor.SetPageName(const AValue: string);
begin
if FPageName=AValue then exit;
@ -3875,6 +3906,7 @@ begin
NewPageName:=Format('%s:%d', [FPageName, (p+1) mod 10])
else
NewPageName:=FPageName;
if IsLocked then NewPageName:='!'+NewPageName;
if Modified then NewPageName:='*'+NewPageName;
if SourceNotebook.NoteBookPages[p] <> NewPageName then begin
SourceNotebook.NoteBookPages[p] := NewPageName;
@ -4182,10 +4214,30 @@ end;
Center the current cursor line in editor.
-------------------------------------------------------------------------------}
procedure TSourceEditor.CenterCursor;
var NewTopLine: integer;
procedure TSourceEditor.CenterCursor(SoftCenter: Boolean = False);
var
NewTopLine: integer;
Y, CurTopLine, LinesInWin, MinLines: Integer;
begin
NewTopLine:=EditorComponent.CaretY-((EditorComponent.LinesInWindow-1) div 2);
if SoftCenter then begin
CurTopLine := EditorComponent.TopLine;
LinesInWin := EditorComponent.LinesInWindow;
MinLines := Min(Max(LinesInWin div 5, 1), 5);
Y := EditorComponent.CaretY;
if (Y <= CurTopLine) or (Y >= CurTopLine + LinesInWin)
then
NewTopLine := Max(1, Y - (LinesInWin div 2))
else
if Y < CurTopLine + MinLines then
NewTopLine := Max(1, Y - MinLines)
else
if Y > CurTopLine + LinesInWin - MinLines then
NewTopLine := Max(1, Y - LinesInWin + MinLines)
else
NewTopLine := CurTopLine;
end
else
NewTopLine:=EditorComponent.CaretY-((EditorComponent.LinesInWindow-1) div 2);
if NewTopLine<1 then NewTopLine:=1;
EditorComponent.TopLine:=NewTopLine;
end;
@ -4316,6 +4368,22 @@ begin
Result:=Point(FEditor.CaretXPix,FEditor.CaretYPix);
end;
function TSourceEditor.IsCaretOnScreen(ACaret: TPoint; UseSoftCenter: Boolean = False): Boolean;
var
LinesInWin, MinLines: Integer;
begin
if UsesoftCenter then begin
LinesInWin := EditorComponent.LinesInWindow;
MinLines := Min(Max(LinesInWin div 5, 1), 5);
end
else
MinLines := 0;
Result := (ACaret.y >= FEditor.TopLine + MinLines) and
(ACaret.Y <= FEditor.TopLine + FEditor.LinesInWindow - MinLines) and
(ACaret.X >= FEditor.LeftChar) and
(ACaret.X <= FEditor.LeftChar + FEditor.CharsInWindow);
end;
function TSourceEditor.SearchReplace(const ASearch, AReplace: string;
SearchOptions: TSrcEditSearchOptions): integer;
const
@ -5002,11 +5070,14 @@ begin
end;
{$IFnDEF SingleSrcWindow}
// Editor locks
SrcEditMenuEditorLock.Checked := ASrcEdit.IsLocked;
// Multi win
SrcEditMenuMoveToOtherWindowList.Clear;
NBAvail := False;
for i := 0 to Manager.SourceWindowCount - 1 do
if (i <> Manager.IndexOfSourceWindow(self)) and
(Manager.SourceWindows[i].IndexOfEditorInShareWith(GetActiveSE) < 0)
(Manager.SourceWindows[i].IndexOfEditorInShareWith(ASrcEdit) < 0)
then begin
NBAvail := True;
with RegisterIDEMenuCommand(SrcEditMenuMoveToOtherWindowList,
@ -5024,7 +5095,7 @@ begin
NBAvail := False;
SrcEditMenuCopyToOtherWindowList.Clear;
for i := 0 to Manager.SourceWindowCount - 1 do
if (Manager.SourceWindows[i].IndexOfEditorInShareWith(GetActiveSE) < 0) and
if (Manager.SourceWindows[i].IndexOfEditorInShareWith(ASrcEdit) < 0) and
(i <> Manager.IndexOfSourceWindow(self))
then begin
NBAvail := True;
@ -5148,6 +5219,9 @@ begin
SrcEditMenuEditorProperties.OnClick:=@EditorPropertiesClicked;
{$IFnDEF SingleSrcWindow}
// EditorLocks
SrcEditMenuEditorLock.OnClick := @EditorLockClicked;
// MultiWin
SrcEditMenuMoveToNewWindow.OnClick := @SrcEditMenuMoveToNewWindowClicked;
SrcEditMenuMoveToOtherWindowNew.OnClick := @SrcEditMenuMoveToNewWindowClicked;
@ -6500,6 +6574,11 @@ begin
MoveEditor(PageIndex, (Sender as TIDEMenuItem).Tag, -1)
end;
procedure TSourceNotebook.EditorLockClicked(Sender: TObject);
begin
GetActiveSE.IsLocked := not GetActiveSE.IsLocked;
end;
Procedure TSourceNotebook.UpdateStatusBar;
var
tempEditor: TSourceEditor;
@ -6543,11 +6622,17 @@ begin
else
PanelFileMode := '';
If TempEditor.ReadOnly then
If TempEditor.ReadOnly then begin
if PanelFileMode <> '' then
PanelFileMode := Format(lisUEReadOnly, [PanelFileMode])
else
PanelFileMode := uepReadonly;
PanelFileMode := PanelFileMode + lisUEModeSeparator;
PanelFileMode := PanelFileMode + uepReadonly;
end;
If TempEditor.IsLocked then begin
if PanelFileMode <> '' then
PanelFileMode := PanelFileMode + lisUEModeSeparator;
PanelFileMode := PanelFileMode + ueLocked;
end;
PanelXY := Format(' %6d:%4d',
[TempEditor.CurrentCursorYLine,TempEditor.CurrentCursorXLine]);
@ -7529,6 +7614,7 @@ procedure TSourceEditorManagerBase.FreeSourceWindows;
var
s: TSourceEditorWindowInterface;
begin
FSourceWindowByFocusList.Clear;
while FSourceWindowList.Count > 0 do begin
s := TSourceEditorWindowInterface(FSourceWindowList[0]);
FSourceWindowList.Delete(0);
@ -7542,6 +7628,11 @@ begin
Result := IndexOfSourceWindow(ActiveSourceWindow);
end;
function TSourceEditorManagerBase.GetSourceWindowByLastFocused(Index: Integer): TSourceEditorWindowInterface;
begin
Result := TSourceEditorWindowInterface(FSourceWindowByFocusList[Index]);
end;
procedure TSourceEditorManagerBase.SetActiveSourceWindowIndex(
const AValue: integer);
begin
@ -7561,6 +7652,8 @@ begin
AValue.SetFocus;
FActiveWindow := AValue as TSourceNotebook;
FSourceWindowByFocusList.Remove(AValue);
FSourceWindowByFocusList.Insert(0, AValue);
// Todo: Each synEdit needs it's own beautifier
if SourceEditorCount > 0 then
@ -7667,6 +7760,11 @@ begin
end;
end;
function TSourceEditorManagerBase.IndexOfSourceWindowByLastFocused(AWindow: TSourceEditorWindowInterface): integer;
begin
Result := FSourceWindowByFocusList.IndexOf(AWindow);
end;
function TSourceEditorManagerBase.SourceEditorIntfWithFilename(
const Filename: string): TSourceEditorInterface;
var
@ -7860,6 +7958,7 @@ begin
FChangeNotifyLists[i] := TMethodList.Create;
SrcEditorIntf.SourceEditorManagerIntf := Self;
FSourceWindowList := TFPList.Create;
FSourceWindowByFocusList := TFPList.Create;
FCompletionPlugins := TFPList.Create;
FUpdateLock := 0;
inherited;
@ -7875,6 +7974,7 @@ begin
SrcEditorIntf.SourceEditorManagerIntf := nil; // xx move down
FreeAndNil(FCompletionPlugins);
FreeAndNil(FSourceWindowList);
FreeAndNil(FSourceWindowByFocusList);
for i := low(TsemChangeReason) to high(TsemChangeReason) do
FChangeNotifyLists[i].Free;;
inherited Destroy;
@ -7963,6 +8063,11 @@ begin
Result := nil;
end;
function TSourceEditorManager.GetSourceNbByLastFocused(Index: Integer): TSourceNotebook;
begin
Result := TSourceNotebook(inherited SourceWindowByLastFocused[Index]);
end;
function TSourceEditorManager.GetSrcEditors(Index: integer): TSourceEditor;
begin
Result := TSourceEditor(inherited SourceEditors[Index]);
@ -8431,7 +8536,8 @@ begin
ActiveEditor := NewEditor;
ShowActiveWindowOnTop(True);
with NewEditor.EditorComponent do begin
TopLine:=NewTopLine;
if not NewEditor.IsLocked then
TopLine:=NewTopLine;
LogicalCaretXY:=NewCaretXY;
end;
end;
@ -8698,6 +8804,7 @@ begin
Result.IncUpdateLock;
FSourceWindowList.Add(Result);
FSourceWindowList.Sort(TListSortCompare(@SortSourceWindows));
FSourceWindowByFocusList.Add(Result);
if Activate then begin
ActiveSourceWindow := Result;
ShowActiveWindowOnTop(False);
@ -8712,6 +8819,7 @@ begin
if FSourceWindowList = nil then exit;
i := FSourceWindowList.IndexOf(AWindow);
FSourceWindowList.Remove(AWindow);
FSourceWindowByFocusList.Remove(AWindow);
if SourceWindowCount = 0 then
ActiveSourceWindow := nil
else if ActiveSourceWindow = AWindow then

View File

@ -220,6 +220,8 @@ const
ecGotoEditor9 = ecGotoEditor8 + 1;
ecGotoEditor0 = ecGotoEditor9 + 1;
ecLockEditor = ecFirstLazarus + 370;
// marker
ecSetFreeBookmark = ecFirstLazarus + 381;
ecPrevBookmark = ecFirstLazarus + 382;