lazarus/ide/uniteditor.pp
mattias 5e5c1122a7 renamed LCLLinux to LCLIntf
git-svn-id: trunk@4637 -
2003-09-18 09:21:03 +00:00

4491 lines
133 KiB
ObjectPascal

{
/***************************************************************************
UnitEditor.pp
-------------------
***************************************************************************/
***************************************************************************
* *
* 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. *
* *
***************************************************************************
}
{This unit builds the TSourceNotebook that the editors are held on. It also has
a class that controls the editors (TSourceEditor)
}
unit UnitEditor;
{$mode objfpc}
{$H+}
interface
{$I ide.inc}
uses
{$IFDEF IDE_MEM_CHECK}
MemCheck,
{$ENDIF}
Classes, Controls, LCLProc, LCLType, LCLIntf, FileCtrl, LMessages, Forms,
Buttons, ComCtrls, SysUtils, Dialogs, StdCtrls, GraphType, Graphics, Extctrls,
Menus,
// codetools
CodeToolManager, CodeCache, SourceLog,
// synedit
SynEditTypes, SynEdit, SynRegExpr, SynEditHighlighter, SynHighlighterPas,
SynEditAutoComplete, SynEditKeyCmds, SynCompletion,
// IDE units
EditorOptions, CustomFormEditor, KeyMapping, FormEditor, Project,
FindReplaceDialog, WordCompletion, FindInFilesDlg, IDEProcs, IDEOptionDefs,
MsgView, InputHistory, LazarusIDEStrConsts, BaseDebugManager, Debugger,
TypInfo, LResources, LazConf, EnvironmentOpts, Compiler,
SortSelectionDlg, EncloseSelectionDlg, ClipBoardHistory, DiffDialog,
SourceEditProcs, SourceMarks, CharacterMapDlg;
type
TSourceNoteBook = class;
TNotifyFileEvent = procedure(Sender: TObject; Filename : AnsiString) of object;
TOnAddWatch = function(Sender: TObject): boolean of object;
TOnProcessUserCommand = procedure(Sender: TObject;
Command: word; var Handled: boolean) of object;
TOnUserCommandProcessed = procedure(Sender: TObject;
Command: word; var Handled: boolean) of object;
TOnLinesInsertedDeleted = procedure(Sender : TObject;
FirstLine,Count : Integer) of Object;
TSynEditPlugin1 = class(TSynEditPlugin)
private
FOnLinesInserted : TOnLinesInsertedDeleted;
FOnLinesDeleted : TOnLinesInsertedDeleted;
protected
procedure AfterPaint(ACanvas: TCanvas; AClip: TRect;
FirstLine, LastLine: integer); override;
procedure LinesInserted(FirstLine, Count: integer); override;
procedure LinesDeleted(FirstLine, Count: integer); override;
public
property OnLinesInserted : TOnLinesInsertedDeleted
read FOnLinesinserted write FOnLinesInserted;
property OnLinesDeleted : TOnLinesInsertedDeleted
read FOnLinesDeleted write FOnLinesDeleted;
constructor Create(AOwner: TCustomSynEdit);
// destructor Destroy; override;
end;
TCharSet = set of Char;
{---- TSource Editor ---
TSourceEditor is the class that controls access for the Editor.
---- TSource Editor ---}
TSourceEditor = class
private
//FAOwner is normally a TSourceNotebook. This is set in the Create constructor.
FAOwner: TComponent;
FEditor: TSynEdit;
FEditPlugin: TSynEditPlugin1; // used to get the LinesInserted and
// LinesDeleted messages
FCodeTemplates: TSynEditAutoComplete;
FPageName: string;
FCodeBuffer: TCodeBuffer;
FIgnoreCodeBufferLock: integer;
FPopUpMenu: TPopupMenu;
FSyntaxHighlighterType: TLazSyntaxHighlighter;
FErrorLine: integer;
FErrorColumn: integer;
FExecutionLine: integer;
FModified: boolean;
FOnAfterClose: TNotifyEvent;
FOnAfterOpen: TNotifyEvent;
FOnAfterSave: TNotifyEvent;
FOnBeforeClose: TNotifyEvent;
FOnBeforeOpen: TNotifyEvent;
FOnBeforeSave: TNotifyEvent;
FOnEditorChange: TNotifyEvent;
FVisible: Boolean;
FOnMouseMove: TMouseMoveEvent;
FOnMouseDown: TMouseEvent;
FOnMouseUp: TMouseEvent;
FOnKeyDown: TKeyEvent;
FSourceNoteBook: TSourceNotebook;
Procedure EditorMouseMoved(Sender: TObject; Shift: TShiftState; X,Y:Integer);
Procedure EditorMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X,Y: Integer);
Procedure EditorMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X,Y: Integer);
Procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Procedure EditorStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
procedure SetCodeBuffer(NewCodeBuffer: TCodeBuffer);
Function GetSource : TStrings;
procedure SetPageName(const AValue: string);
procedure UpdatePageName;
Procedure SetSource(Value : TStrings);
Function GetCurrentCursorXLine : Integer;
Procedure SetCurrentCursorXLine(num : Integer);
Function GetCurrentCursorYLine : Integer;
Procedure SetCurrentCursorYLine(num : Integer);
Function GetModified : Boolean;
procedure SetModified(NewValue:boolean);
Function GetInsertMode : Boolean;
Function GetReadOnly : Boolean;
procedure SetReadOnly(NewValue: boolean);
procedure SetCodeTemplates(
NewCodeTemplates: TSynEditAutoComplete);
procedure SetPopupMenu(NewPopupMenu: TPopupMenu);
function GetFilename: string;
Function GotoLine(Value : Integer) : Integer;
Procedure CreateEditor(AOwner : TComponent; AParent: TWinControl);
procedure SetVisible(Value: boolean);
protected
FindText : String;
ErrorMsgs : TStrings;
Procedure ReParent(AParent : TWinControl);
Procedure ProcessCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
Procedure ProcessUserCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
Procedure UserCommandProcessed(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
Procedure ccOnTimer(sender : TObject);
Procedure ccAddMessage(Texts : String);
Procedure FocusEditor;// called by TSourceNotebook when the Notebook page
// changes so the editor is focused
procedure OnGutterClick(Sender: TObject; X, Y, Line: integer;
mark: TSynEditMark);
procedure OnEditorSpecialLineColor(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor);
Function RefreshEditorSettings : Boolean;
procedure SetSyntaxHighlighterType(
ASyntaxHighlighterType: TLazSyntaxHighlighter);
procedure SetErrorLine(NewLine: integer);
procedure SetExecutionLine(NewLine: integer);
procedure OnCodeBufferChanged(Sender: TSourceLog;
SrcLogEntry: TSourceLogEntry);
procedure LinesInserted(sender : TObject; FirstLine,Count : Integer);
procedure LinesDeleted(sender : TObject; FirstLine,Count : Integer);
property Visible : Boolean read FVisible write SetVisible default False;
public
constructor Create(AOwner : TComponent; AParent : TWinControl);
destructor Destroy; override;
Function Close : Boolean;
// codebuffer
procedure IncreaseIgnoreCodeBufferLock;
procedure DecreaseIgnoreCodeBufferLock;
procedure UpdateCodeBuffer; // copy the source from EditorComponent
// dialogs
procedure StartFindAndReplace(Replace:boolean);
procedure OnReplace(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var Action: TSynReplaceAction);
procedure DoFindAndReplace;
procedure FindNext;
procedure FindPrevious;
procedure ShowGotoLineDialog;
procedure GetDialogPosition(Width, Height:integer; var Left,Top:integer);
procedure ActivateHint(ClientPos: TPoint; const TheHint: string);
// selections
function SelectionAvailable: boolean;
function GetText(OnlySelection: boolean): string;
Procedure SelectText(LineNum,CharStart,LineNum2,CharEnd : Integer);
procedure ReplaceLines(StartLine, EndLine: integer; const NewText: string);
procedure EncloseSelection;
procedure UpperCaseSelection;
procedure LowerCaseSelection;
procedure TabsToSpacesInSelection;
procedure CommentSelection;
procedure UncommentSelection;
procedure SortSelection;
procedure SelectToBrace;
procedure SelectCodeBlock;
procedure SelectLine;
procedure SelectParagraph;
function CommentText(const Txt: string; CommentType: TCommentType): string;
procedure InsertCharacterFromMap;
procedure InsertGPLNotice(CommentType: TCommentType);
procedure InsertLGPLNotice(CommentType: TCommentType);
procedure InsertUsername;
procedure InsertDateTime;
procedure InsertChangeLogEntry;
procedure InsertCVSKeyword(const AKeyWord: string);
// editor commands
procedure DoEditorExecuteCommand(EditorCommand: integer);
// used to get the word at the mouse cursor
Function GetWordAtPosition(Position : TPoint) : String;
function GetWordFromCaret(const ACaretPos: TPoint) : String;
function GetWordFromCaretEx(const ACaretPos: TPoint;
const ALeftLimit, ARightLimit: TCharSet): String;
Function GetWordAtCurrentCaret: String;
function CaretInSelection(const ACaretPos: TPoint): Boolean;
function PositionInSelection(const APosition: TPoint): Boolean;
// cursor
Function GetCaretPosFromCursorPos(CursorPos : TPoint) : TPoint;
procedure CenterCursor;
// notebook
procedure Activate;
function PageIndex: integer;
function IsActiveOnNoteBook: boolean;
public
// properties
property CodeBuffer: TCodeBuffer read FCodeBuffer write SetCodeBuffer;
property CodeTemplates: TSynEditAutoComplete
read FCodeTemplates write SetCodeTemplates;
property CurrentCursorXLine : Integer
read GetCurrentCursorXLine write SetCurrentCursorXLine;
property CurrentCursorYLine : Integer
read GetCurrentCursorYLine write SetCurrentCursorYLine;
property EditorComponent: TSynEdit read FEditor;
property ErrorLine: integer read FErrorLine write SetErrorLine;
property ExecutionLine: integer read FExecutionLine write SetExecutionLine;
property FileName: AnsiString read GetFileName;
property InsertMode: Boolean read GetInsertmode;
property Modified: Boolean read GetModified write SetModified;
property OnAfterClose: TNotifyEvent read FOnAfterClose write FOnAfterClose;
property OnBeforeClose: TNotifyEvent read FOnBeforeClose
write FOnBeforeClose;
property OnAfterOpen: TNotifyEvent read FOnAfterOpen write FOnAfterOpen;
property OnBeforeOpen: TNotifyEvent read FOnBeforeOpen write FOnBeforeOpen;
property OnAfterSave: TNotifyEvent read FOnAfterSave write FOnAfterSave;
property OnBeforeSave: TNotifyEvent read FOnBeforeSave write FOnBeforeSave;
property OnEditorChange: TNotifyEvent read FOnEditorChange
write FOnEditorChange;
property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
property Owner: TComponent read FAOwner;
property PageName: string read FPageName write SetPageName;
property PopupMenu: TPopupMenu read FPopUpMenu write SetPopUpMenu;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
property Source: TStrings read GetSource write SetSource;
property SourceNoteBook: TSourceNotebook read FSourceNoteBook;
property SyntaxHighlighterType: TLazSyntaxHighlighter
read fSyntaxHighlighterType write SetSyntaxHighlighterType;
end;
//============================================================================
{ TSourceNotebook }
TJumpHistoryAction = (jhaBack, jhaForward);
TOnJumpToHistoryPoint = procedure(var NewCaretXY: TPoint;
var NewTopLine, NewPageIndex: integer; Action: TJumpHistoryAction) of object;
TOnAddJumpPoint = procedure(ACaretXY: TPoint; ATopLine: integer;
APageIndex: integer; DeleteForwardHistory: boolean) of object;
TOnMovingPage = procedure(Sender: TObject;
OldPageIndex, NewPageIndex: integer) of object;
TOnShowHintForSource = procedure(SrcEdit: TSourceEditor; ClientPos: TPoint;
CaretPos: TPoint) of object;
TOnInitIdentCompletion = procedure(Sender: TObject;
var Handled, Abort: boolean) of object;
TSourceNotebookState = (snIncrementalFind);
TSourceNotebookStates = set of TSourceNotebookState;
TSourceNotebook = class(TForm)
ClosePageMenuItem: TMenuItem;
FindDeclarationMenuItem: TMenuItem;
GotoBookmarkMenuItem : TMenuItem;
MoveEditorLeftMenuItem: TMenuItem;
MoveEditorRightMenuItem: TMenuItem;
Notebook: TNotebook;
OpenFileAtCursorMenuItem: TMenuItem;
ReadOnlyMenuItem: TMenuItem;
SetBookmarkMenuItem : TMenuItem;
ShowLineNumbersMenuItem: TMenuItem;
ShowUnitInfoMenuItem: TMenuItem;
SrcPopUpMenu: TPopupMenu;
StatusBar: TStatusBar;
DebugMenuItem: TMenuItem;
AddBreakpointMenuItem: TMenuItem;
AddWatchAtCursorMenuItem: TMenuItem;
RunToCursorMenuItem: TMenuItem;
ViewCallStackMenuItem: TMenuItem;
EditorPropertiesMenuItem: TMenuItem;
Procedure AddBreakpointClicked(Sender: TObject);
procedure RunToClicked(Sender: TObject);
procedure ViewCallStackClick(Sender: TObject);
Procedure AddWatchAtCursor(Sender : TObject);
Procedure BookmarkGoTo(Index: Integer);
Procedure BookMarkGotoClicked(Sender : TObject);
Procedure BookMarkSet(Value : Integer);
Procedure BookMarkSetClicked(Sender : TObject);
Procedure BookMarkToggle(Value : Integer);
procedure EditorPropertiesClicked(Sender: TObject);
Procedure FindDeclarationClicked(Sender : TObject);
procedure MoveEditorLeftClicked(Sender: TObject);
procedure MoveEditorRightClicked(Sender: TObject);
Procedure NotebookPageChanged(Sender : TObject);
procedure NotebookShowTabHint(Sender: TObject; HintInfo: Pointer);
Procedure OpenAtCursorClicked(Sender : TObject);
Procedure ReadOnlyClicked(Sender : TObject);
Procedure ShowUnitInfo(Sender : TObject);
procedure SrcPopUpMenuPopup(Sender: TObject);
Procedure ToggleLineNumbersClicked(Sender : TObject);
private
FCodeTemplateModul: TSynEditAutoComplete;
FFormEditor : TFormEditor;
fIncrementalSearchStartPos: TPoint;
FIncrementalSearchStr: string;
FKeyStrokes: TSynEditKeyStrokes;
FMainIDE : TComponent;
FProcessingCommand: boolean;
FSourceEditorList : TList; // list of TSourceEditor
FOnAddJumpPoint: TOnAddJumpPoint;
FOnAddWatchAtCursor: TOnAddWatch;
FOnCloseClicked: TNotifyEvent;
FOnCtrlMouseUp: TMouseEvent;
FOnDeleteLastJumpPoint: TNotifyEvent;
FOnEditorVisibleChanged: TNotifyEvent;
FOnEditorChanged: TNotifyEvent;
FOnEditorPropertiesClicked: TNotifyEvent;
FOnFindDeclarationClicked: TNotifyEvent;
FOnInitIdentCompletion: TOnInitIdentCompletion;
FOnJumpToHistoryPoint: TOnJumpToHistoryPoint;
FOnMovingPage: TOnMovingPage;
FOnNewClicked: TNotifyEvent;
FOnOpenClicked: TNotifyEvent;
FOnOpenFileAtCursorClicked: TNotifyEvent;
FOnProcessUserCommand: TOnProcessUserCommand;
fOnReadOnlyChanged: TNotifyEvent;
FOnSaveAsClicked: TNotifyEvent;
FOnSaveAllClicked: TNotifyEvent;
FOnSaveClicked: TNotifyEvent;
FOnShowHintForSource: TOnShowHintForSource;
FOnShowUnitInfo: TNotifyEvent;
FOnToggleFormUnitClicked: TNotifyEvent;
FOnToggleObjectInspClicked: TNotifyEvent;
FOnUserCommandProcessed: TOnProcessUserCommand;
FOnViewJumpHistory: TNotifyEvent;
FUnUsedEditorComponents: TList; // list of TSynEdit
private
// colors for the completion form (popup form, e.g. word completion)
FActiveEditDefaultFGColor: TColor;
FActiveEditDefaultBGColor: TColor;
FActiveEditSelectedFGColor: TColor;
FActiveEditSelectedBGColor: TColor;
FActiveEditKeyFGColor: TColor;
FActiveEditKeyBGColor: TColor;
FActiveEditSymbolFGColor: TColor;
FActiveEditSymbolBGColor: TColor;
fAutoFocusLock: integer;
fCustomPopupMenuItems: TList;
// PopupMenu
Procedure BuildPopupMenu;
procedure RemoveUserDefinedMenuItems;
function AddUserDefinedPopupMenuItem(const NewCaption: string;
const NewEnabled: boolean;
const NewOnClick: TNotifyEvent): TMenuItem;
procedure UpdateActiveEditColors;
procedure SetIncrementalSearchStr(const AValue: string);
protected
ccSelection: String;
States: TSourceNotebookStates;
Function CreateNotebook : Boolean;
Function NewSE(Pagenum : Integer) : TSourceEditor;
Procedure EditorChanged(Sender: TObject);
Procedure ccExecute(Sender : TObject);
Procedure ccCancel(Sender : TObject);
procedure ccComplete(var Value: ansistring; Shift: TShiftState);
function OnSynCompletionPaintItem(const AKey: string; ACanvas: TCanvas;
X, Y: integer; ItemSelected: boolean; Index: integer): boolean;
procedure OnSynCompletionSearchPosition(var APosition:integer);
procedure DeactivateCompletionForm;
procedure InitIdentCompletion(S: TStrings);
Procedure EditorMouseMove(Sender : TObject; Shift: TShiftstate;
X,Y : Integer);
Procedure EditorMouseDown(Sender : TObject; Button : TMouseButton;
Shift: TShiftstate; X,Y : Integer);
Procedure EditorMouseUp(Sender : TObject; Button : TMouseButton;
Shift: TShiftstate; X,Y : Integer);
//hintwindow stuff
FHintWindow: THintWindow;
FHintTimer: TTimer;
Procedure HintTimer(Sender: TObject);
procedure OnApplicationUserInput(Sender: TObject; Msg: Cardinal);
procedure ShowSynEditHint(const MousePos: TPoint);
Procedure NextEditor;
Procedure PrevEditor;
procedure MoveEditor(OldPageIndex, NewPageIndex: integer);
procedure MoveEditorLeft(PageIndex: integer);
procedure MoveEditorRight(PageIndex: integer);
procedure MoveActivePageLeft;
procedure MoveActivePageRight;
Procedure ProcessParentCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer;
var Handled: boolean);
Procedure ParentCommandProcessed(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer;
var Handled: boolean);
// marks
function FindBookmark(BookmarkID: integer): TSourceEditor;
function OnSourceMarksGetSourceEditor(ASynEdit: TCustomSynEdit): TObject;
function OnSourceMarksGetFilename(ASourceEditor: TObject): string;
function GetEditors(Index:integer): TSourceEditor;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure BeginAutoFocusLock;
procedure EndAutoFocusLock;
public
FindReplaceDlgHistoryIndex: array[TFindDlgComponent] of integer;
FindReplaceDlgUserText: array[TFindDlgComponent] of string;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Editors[Index:integer]:TSourceEditor read GetEditors;
function EditorCount:integer;
function FindSourceEditorWithPageIndex(PageIndex:integer):TSourceEditor;
function FindPageWithEditor(ASourceEditor: TSourceEditor):integer;
function FindSourceEditorWithEditorComponent(
EditorComp: TComponent): TSourceEditor;
function FindSourceEditorWithFilename(const Filename: string): TSourceEditor;
Function GetActiveSE : TSourceEditor;
procedure SetActiveSE(SrcEdit: TSourceEditor);
procedure LockAllEditorsInSourceChangeCache;
procedure UnlockAllEditorsInSourceChangeCache;
function GetDiffFiles: TDiffFiles;
procedure GetSourceText(PageIndex: integer; OnlySelection: boolean;
var Source: string);
Function ActiveFileName : AnsiString;
Function FindUniquePageName(FileName:string; IgnorePageIndex:integer):string;
function SomethingModified: boolean;
procedure UpdateStatusBar;
Procedure ClearUnUsedEditorComponents(Force: boolean);
procedure ClearErrorLines;
procedure ClearExecutionLines;
Procedure NewClicked(Sender: TObject);
procedure OpenClicked(Sender : TObject);
procedure SaveClicked(Sender : TObject);
procedure SaveAllClicked(Sender : TObject);
procedure SaveAsClicked(Sender : TObject);
procedure CloseClicked(Sender : TObject);
procedure ToggleFormUnitClicked(Sender: TObject);
procedure ToggleObjectInspClicked(Sender: TObject);
procedure InitFindDialog;
procedure FindClicked(Sender : TObject);
procedure FindNextClicked(Sender : TObject);
procedure FindPreviousClicked(Sender : TObject);
procedure ReplaceClicked(Sender : TObject);
procedure IncrementalFindClicked(Sender : TObject);
procedure FindInFiles(AProject: TProject);
procedure GotoLineClicked(Sender: TObject);
procedure HistoryJump(Sender: TObject; Action: TJumpHistoryAction);
procedure JumpBackClicked(Sender: TObject);
procedure JumpForwardClicked(Sender: TObject);
procedure AddJumpPointClicked(Sender: TObject);
procedure DeleteLastJumpPointClicked(Sender: TObject);
procedure ViewJumpHistoryClicked(Sender: TObject);
procedure ActivateHint(const ScreenPos: TPoint; const TheHint: string);
procedure HideHint;
Procedure NewFile(const NewShortName: String; ASource : TCodeBuffer;
FocusIt: boolean);
Procedure CloseFile(PageIndex:integer);
procedure FocusEditor;
Procedure ToggleBookmark(Value : Integer);
Procedure SetBookmark(Value : Integer);
Procedure GotoBookmark(Value: Integer);
Procedure ReloadEditorOptions;
Procedure GetSynEditPreviewSettings(APreviewEditor: TObject);
Property CodeTemplateModul: TSynEditAutoComplete
read FCodeTemplateModul write FCodeTemplateModul;
procedure OnCodeTemplateTokenNotFound(Sender: TObject; AToken: string;
AnEditor: TCustomSynEdit; var Index:integer);
procedure OnWordCompletionGetSource(
var Source:TStrings; SourceIndex:integer);
function Empty: boolean;
property FormEditor : TFormEditor read FFormEditor write FFormEditor;
property MainIDE : TComponent read FMainIDE;
procedure FindReplaceDlgKey(Sender: TObject; var Key: Word;
Shift:TShiftState; FindDlgComponent: TFindDlgComponent);
procedure EndIncrementalFind;
property IncrementalSearchStr: string
read FIncrementalSearchStr write SetIncrementalSearchStr;
published
property OnAddJumpPoint: TOnAddJumpPoint
read FOnAddJumpPoint write FOnAddJumpPoint;
property OnCloseClicked : TNotifyEvent
read FOnCloseClicked write FOnCloseClicked;
property OnCtrlMouseUp: TMouseEvent
read FOnCtrlMouseUp write FOnCtrlMouseUp;
property OnDeleteLastJumpPoint: TNotifyEvent
read FOnDeleteLastJumpPoint write FOnDeleteLastJumpPoint;
property OnEditorVisibleChanged: TNotifyEvent
read FOnEditorVisibleChanged write FOnEditorVisibleChanged;
property OnEditorChanged: TNotifyEvent
read FOnEditorChanged write FOnEditorChanged;
property OnEditorPropertiesClicked: TNotifyEvent
read FOnEditorPropertiesClicked write FOnEditorPropertiesClicked;
property OnFindDeclarationClicked : TNotifyEvent
read FOnFindDeclarationClicked write FOnFindDeclarationClicked;
property OnInitIdentCompletion: TOnInitIdentCompletion
read FOnInitIdentCompletion write FOnInitIdentCompletion;
property OnJumpToHistoryPoint: TOnJumpToHistoryPoint
read FOnJumpToHistoryPoint write FOnJumpToHistoryPoint;
property OnMovingPage: TOnMovingPage read FOnMovingPage write FOnMovingPage;
property OnNewClicked: TNotifyEvent read FOnNewClicked write FOnNewClicked;
property OnOpenClicked: TNotifyEvent
read FOnOPenClicked write FOnOpenClicked;
property OnOpenFileAtCursorClicked : TNotifyEvent
read FOnOpenFileAtCursorClicked write FOnOpenFileAtCursorClicked;
property OnReadOnlyChanged: TNotifyEvent
read fOnReadOnlyChanged write fOnReadOnlyChanged;
property OnSaveAsClicked: TNotifyEvent
read FOnSaveAsClicked write FOnSaveAsClicked;
property OnSaveAllClicked: TNotifyEvent
read FOnSaveAllClicked write FOnSaveAllClicked;
property OnSaveClicked: TNotifyEvent
read FOnSaveClicked write FOnSaveClicked;
property OnShowHintForSource: TOnShowHintForSource
read FOnShowHintForSource write FOnShowHintForSource;
property OnShowUnitInfo: TNotifyEvent
read FOnShowUnitInfo write FOnShowUnitInfo;
property OnToggleFormUnitClicked : TNotifyEvent
read FOnToggleFormUnitClicked write FOnToggleFormUnitClicked;
property OnToggleObjectInspClicked : TNotifyEvent
read FOnToggleObjectInspClicked write FOnToggleObjectInspClicked;
property OnProcessUserCommand: TOnProcessUserCommand
read FOnProcessUserCommand write FOnProcessUserCommand;
property OnUserCommandProcessed: TOnUserCommandProcessed
read FOnUserCommandProcessed write FOnUserCommandProcessed;
property OnViewJumpHistory: TNotifyEvent
read FOnViewJumpHistory write FOnViewJumpHistory;
property OnAddWatchAtCursor: TOnAddWatch
read FOnAddWatchAtCursor write FOnAddWatchAtCursor;
end;
//=============================================================================
{Goto dialog}
TfrmGoto = class(TForm)
Label1 : TLabel;
Edit1 : TEdit;
btnOK : TBitbtn;
btnCancel : TBitBtn;
procedure Edit1KeyDown(Sender: TObject; var Key:Word; Shift:TShiftState);
public
constructor Create(AOwner : TComponent); override;
end;
implementation
var
Highlighters: array[TLazSyntaxHighlighter] of TSynCustomHighlighter;
// aCompletion:
// The component controlling the completion form. It is created on demand
// and killed when the IDE ends.
aCompletion : TSynCompletion;
// CurCompletionControl contains aCompletion whenever the completion form is
// active
CurCompletionControl : TSynBaseCompletion;
CurrentCompletionType: TCompletionType;
IdentCompletionTimer : TTimer;
AWordCompletion : TWordCompletion;
GotoDialog : TfrmGoto;
{ TSourceEditor }
{The constructor for @link(TSourceEditor). AOwner is the @link(TSOurceNotebook)
and the AParent is usually a page of a @link(TNotebook)
}
constructor TSourceEditor.Create(AOwner : TComponent; AParent : TWinControl);
Begin
//writeln('TSourceEditor.Create A ',AOwner.ClassName);
inherited Create;
FAOwner := AOwner;
if (FAOwner<>nil) and (FAOwner is TSourceNotebook) then
FSourceNoteBook:=TSourceNotebook(FAOwner)
else
FSourceNoteBook:=nil;
FSyntaxHighlighterType:=lshNone;
FErrorLine:=-1;
FErrorColumn:=-1;
FExecutionLine:=-1;
// FControl := nil; //commented out on 11-14-2001
//writeln('TSourceEditor.Create B ');
CreateEditor(AOwner,AParent);
FEditPlugin := TSynEditPlugin1.Create(FEditor);
FEditPlugin.OnLinesInserted := @LinesInserted;
FEditPlugin.OnLinesDeleted := @LinesDeleted;
//writeln('TSourceEditor.Create END ');
end;
destructor TSourceEditor.Destroy;
begin
//writeln('TSourceEditor.Destroy A ',FEditor.Name);
if (FAOwner<>nil) and (FEditor<>nil) then begin
FEditor.Visible:=false;
FEditor.Parent:=nil;
if SourceEditorMarks<>nil then
SourceEditorMarks.DeleteAllForEditor(FEditor);
TSourceNoteBook(FAOwner).FSourceEditorList.Remove(Self);
TSourceNoteBook(FAOwner).FUnUsedEditorComponents.Add(FEditor);
end;
//writeln('TSourceEditor.Destroy B ');
inherited Destroy;
//writeln('TSourceEditor.Destroy END ');
end;
{------------------------------G O T O L I N E -----------------------------}
Function TSourceEditor.GotoLine(Value : Integer) : Integer;
Var
P : TPoint;
TopLine: integer;
Begin
TSourceNotebook(Owner).AddJumpPointClicked(Self);
P.X := 0;
P.Y := Value;
TopLine := P.Y - (FEditor.LinesInWindow div 2);
if TopLine < 1 then TopLine:=1;
FEditor.CaretXY := P;
with FEditor do begin
BlockBegin:=CaretXY;
BlockEnd:=CaretXY;
end;
FEditor.TopLine := TopLine;
Result:=FEditor.CaretY;
end;
procedure TSourceEditor.ShowGotoLineDialog;
begin
GotoDialog.Edit1.Text:='';
if (GotoDialog.ShowModal = mrOK) then
GotoLine(StrToIntDef(GotoDialog.Edit1.Text,1));
end;
procedure TSourceEditor.GetDialogPosition(Width, Height:integer;
var Left,Top:integer);
var P:TPoint;
begin
with EditorComponent do
P := ClientToScreen(Point(CaretXPix, CaretYPix));
Left:=EditorComponent.ClientOrigin.X+(EditorComponent.Width - Width) div 2;
Top:=P.Y-Height-2*EditorComponent.LineHeight;
if Top<10 then Top:=P.y+2*EditorComponent.LineHeight;
end;
procedure TSourceEditor.ActivateHint(ClientPos: TPoint; const TheHint: string);
var
ScreenPos: TPoint;
begin
if SourceNoteBook=nil then exit;
ScreenPos:=EditorComponent.ClientToScreen(ClientPos);
SourceNoteBook.ActivateHint(ScreenPos,TheHint);
end;
{------------------------------S T A R T F I N D-----------------------------}
procedure TSourceEditor.StartFindAndReplace(Replace:boolean);
var ALeft,ATop:integer;
begin
if SourceNotebook<>nil then
SourceNotebook.InitFindDialog;
if Replace then
FindReplaceDlg.Options :=
FindReplaceDlg.Options + [ssoReplace, ssoReplaceAll, ssoPrompt]
else
FindReplaceDlg.Options :=
FindReplaceDlg.Options - [ssoReplace, ssoReplaceAll, ssoPrompt];
// Fill in history items
FindReplaceDlg.TextToFindComboBox.Items.Assign(InputHistories.FindHistory);
if Replace then
FindReplaceDlg.ReplaceTextComboBox.Items.Assign(
InputHistories.ReplaceHistory);
with EditorComponent do begin
if EditorOpts.FindTextAtCursor then begin
if SelAvail and (BlockBegin.Y = BlockEnd.Y) then
FindReplaceDlg.FindText := SelText
else
FindReplaceDlg.FindText := GetWordAtRowCol(CaretXY);
end else begin
FindReplaceDlg.FindText:='';
end;
end;
GetDialogPosition(FindReplaceDlg.Width,FindReplaceDlg.Height,ALeft,ATop);
FindReplaceDlg.Left:=ALeft;
FindReplaceDlg.Top:=ATop;
if (FindReplaceDlg.ShowModal = mrCancel) then begin
exit;
end;
if Replace then
InputHistories.AddToReplaceHistory(FindReplaceDlg.ReplaceText);
InputHistories.AddToFindHistory(FindReplaceDlg.FindText);
InputHistories.Save;
DoFindAndReplace;
End;
{------------------------------F I N D A G A I N ----------------------------}
procedure TSourceEditor.FindNext;
var OldOptions: TSynSearchOptions;
Begin
OldOptions:=FindReplaceDlg.Options;
FindReplaceDlg.Options:=FindReplaceDlg.Options-[ssoEntireScope];
DoFindAndReplace;
FindReplaceDlg.Options:=OldOptions;
End;
{---------------------------F I N D P R E V I O U S ------------------------}
procedure TSourceEditor.FindPrevious;
var OldOptions: TSynSearchOptions;
Begin
OldOptions:=FindReplaceDlg.Options;
FindReplaceDlg.Options:=FindReplaceDlg.Options-[ssoEntireScope];
if ssoBackwards in FindReplaceDlg.Options then
FindReplaceDlg.Options:=FindReplaceDlg.Options-[ssoBackwards]
else
FindReplaceDlg.Options:=FindReplaceDlg.Options+[ssoBackwards];
DoFindAndReplace;
FindReplaceDlg.Options:=OldOptions;
End;
procedure TSourceEditor.DoFindAndReplace;
var OldCaretXY:TPoint;
AText,ACaption:AnsiString;
TopLine: integer;
begin
if SourceNotebook<>nil then
SourceNotebook.AddJumpPointClicked(Self);
OldCaretXY:=EditorComponent.CaretXY;
if EditorComponent.SelAvail then begin
if ssoBackwards in FindReplaceDlg.Options then
EditorComponent.CaretXY:=EditorComponent.BlockBegin
else
EditorComponent.CaretXY:=EditorComponent.BlockEnd
end;
try
EditorComponent.SearchReplace(
FindReplaceDlg.FindText,FindReplaceDlg.ReplaceText,FindReplaceDlg.Options);
except
on E: ERegExpr do begin
MessageDlg(lisUEErrorInRegularExpression,
E.Message,mtError,[mbCancel],0);
exit;
end;
end;
if (OldCaretXY.X=EditorComponent.CaretX)
and (OldCaretXY.Y=EditorComponent.CaretY)
and not (ssoReplaceAll in FindReplaceDlg.Options) then begin
ACaption:=lisUENotFound;
AText:=Format(lisUESearchStringNotFound, [FindReplaceDlg.FindText]);
MessageDlg(ACaption,AText,mtInformation,[mbOk],0);
TSourceNotebook(Owner).DeleteLastJumpPointClicked(Self);
end else begin
TopLine := EditorComponent.CaretY - (EditorComponent.LinesInWindow div 2);
if TopLine < 1 then TopLine:=1;
EditorComponent.TopLine := TopLine;
end;
end;
procedure TSourceEditor.OnReplace(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var Action: TSynReplaceAction);
var a,x,y:integer;
AText:AnsiString;
begin
if FAOwner<>nil then
TSourceNotebook(FAOwner).UpdateStatusBar;
AText:=Format(lisUEReplaceThisOccurrenceOfWith, ['"', ASearch, '"', #13, '"',
AReplace, '"']);
GetDialogPosition(300,150,X,Y);
a:=MessageDlgPos(AText,mtconfirmation,
[mbYes,mbYesToAll,mbNo,mbCancel],0,X,Y);
case a of
mrYes:Action:=raReplace;
mrNo :Action:=raSkip;
mrAll,mrYesToAll:Action:=raReplaceAll;
else
Action:=raCancel;
end;
end;
//-----------------------------------------------------------------------------
Procedure TSourceEditor.FocusEditor;
Begin
{$IFDEF VerboseFocus}
writeln('TSourceEditor.FocusEditor A ',PageName,' ',FEditor.Name);
{$ENDIF}
if SourceNotebook<>nil then SourceNotebook.Visible:=true;
FEditor.SetFocus;
{$IFDEF VerboseFocus}
writeln('TSourceEditor.FocusEditor END ',PageName,' ',FEditor.Name);
{$ENDIF}
end;
Function TSourceEditor.GetReadOnly : Boolean;
Begin
Result:=FEditor.ReadOnly;
End;
procedure TSourceEditor.SetReadOnly(NewValue: boolean);
begin
FEditor.ReadOnly:=NewValue;
end;
Procedure TSourceEditor.ProcessCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
begin
if (FSourceNoteBook<>nil)
and (snIncrementalFind in FSourceNoteBook.States) then begin
case Command of
ecChar:
begin
FSourceNoteBook.IncrementalSearchStr:=
FSourceNoteBook.IncrementalSearchStr+AChar;
Command:=ecNone;
end;
ecDeleteLastChar:
begin
FSourceNoteBook.IncrementalSearchStr:=
LeftStr(FSourceNoteBook.IncrementalSearchStr,
length(FSourceNoteBook.IncrementalSearchStr)-1);
Command:=ecNone;
end;
ecLineBreak:
begin
FSourceNoteBook.EndIncrementalFind;
Command:=ecNone;
end;
else
FSourceNoteBook.EndIncrementalFind;
end;
end;
case Command of
ecSelEditorTop, ecSelEditorBottom, ecEditorTop, ecEditorBottom:
begin
if FaOwner<>nil then
TSourceNotebook(FaOwner).AddJumpPointClicked(Self);
end;
ecCopy:
begin
if (not FEditor.SelAvail) then begin
// nothing selected
if EditorOpts.CopyWordAtCursorOnCopyNone then begin
FEditor.SetSelWord;
end;
end;
end;
else
if (CurCompletionControl<>nil)
and (not (AChar in ['a'..'z','A'..'Z','0'..'9',#128..#255])) then begin
end;
end;
end;
Procedure TSourceEditor.ProcessUserCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
var
Y,I : Integer;
P: TPoint;
Texts, Texts2 : String;
Handled: boolean;
Begin
Handled:=true;
case Command of
ecIdentCompletion :
if not TCustomSynEdit(Sender).ReadOnly then begin
CurrentCompletionType:=ctIdentCompletion;
TextS := FEditor.LineTextExtended;
i := FEditor.CaretX - 1;
if i > length(TextS) then
TextS2 := ''
else begin
while (i > 0) and (TextS[i] in ['a'..'z','A'..'Z','0'..'9','_']) do
dec(i);
TextS2 := Trim(copy(TextS, i + 1, FEditor.CaretX - i - 1));
end;
with TCustomSynEdit(Sender) do
P := ClientToScreen(Point(CaretXPix - length(TextS2)*CharWidth
, CaretYPix + LineHeight));
aCompletion.Editor:=TCustomSynEdit(Sender);
aCompletion.Execute(TextS2,P.X,P.Y);
end;
ecWordCompletion :
if not TCustomSynEdit(Sender).ReadOnly then begin
CurrentCompletionType:=ctWordCompletion;
TextS := FEditor.LineTextExtended;
i := FEditor.CaretX - 1;
if i > length(TextS) then
TextS2 := ''
else begin
while (i > 0) and (TextS[i] in ['a'..'z','A'..'Z','0'..'9','_']) do
dec(i);
TextS2 := Trim(copy(TextS, i + 1, FEditor.CaretX - i - 1));
end;
with TCustomSynEdit(Sender) do
P := ClientToScreen(Point(CaretXPix - length(TextS2)*CharWidth
, CaretYPix + LineHeight));
aCompletion.Editor:=TCustomSynEdit(Sender);
aCompletion.Execute(TextS2,P.X,P.Y);
end;
ecFind:
StartFindAndReplace(false);
ecFindNext:
FindNext;
ecFindPrevious:
FindPrevious;
ecIncrementalFind:
if FSourceNoteBook<>nil then FSourceNoteBook.IncrementalFindClicked(Self);
ecFindInFiles:
// ToDo
;
ecReplace:
StartFindAndReplace(true);
ecGotoLineNumber :
ShowGotoLineDialog;
ecPeriod :
Begin
Y := CurrentCursorYLine;
Texts := Lowercase(Source.Strings[Y-1]);
if InsertMode then
Texts := Copy(Texts,1,CurrentCursorXLine)+'.'
+Copy(Texts,CurrentCursorXLine+1,Length(Texts))
else
Texts[CurrentCursorXLine] := '.';
Source.Strings[Y-1] := Texts;
IdentCompletionTimer.OnTimer := @CCOnTimer;
IdentCompletionTimer.Enabled := True;
end;
ecSelectionEnclose:
EncloseSelection;
ecSelectionUpperCase:
UpperCaseSelection;
ecSelectionLowerCase:
LowerCaseSelection;
ecSelectionTabs2Spaces:
TabsToSpacesInSelection;
ecSelectionComment:
CommentSelection;
ecSelectionUnComment:
UncommentSelection;
ecSelectionSort:
SortSelection;
ecSelectToBrace:
SelectToBrace;
ecSelectCodeBlock:
SelectCodeBlock;
ecSelectLine:
SelectLine;
ecSelectParagraph:
SelectParagraph;
ecInsertCharacter:
InsertCharacterFromMap;
ecInsertGPLNotice:
InsertGPLNotice(comtDefault);
ecInsertLGPLNotice:
InsertLGPLNotice(comtDefault);
ecInsertUserName:
InsertUsername;
ecInsertDateTime:
InsertDateTime;
ecInsertChangeLogEntry:
InsertChangeLogEntry;
ecInsertCVSAuthor:
InsertCVSKeyword('Author');
ecInsertCVSDate:
InsertCVSKeyword('Date');
ecInsertCVSHeader:
InsertCVSKeyword('Header');
ecInsertCVSID:
InsertCVSKeyword('ID');
ecInsertCVSLog:
InsertCVSKeyword('Log');
ecInsertCVSName:
InsertCVSKeyword('Name');
ecInsertCVSRevision:
InsertCVSKeyword('Revision');
ecInsertCVSSource:
InsertCVSKeyword('Source');
else
begin
Handled:=false;
if FaOwner<>nil then
TSourceNotebook(FaOwner).ProcessParentCommand(self,Command,aChar,Data,
Handled);
end;
end; //case
if Handled then Command:=ecNone;
end;
Procedure TSourceEditor.UserCommandProcessed(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
var Handled: boolean;
begin
Handled:=true;
case Command of
ecNone: ;
ecUndo:
if (FEditor.Modified=false) and (CodeBuffer<>nil) then
CodeBuffer.Assign(FEditor.Lines);
else
begin
Handled:=false;
if FaOwner<>nil then
TSourceNotebook(FaOwner).ParentCommandProcessed(self,Command,aChar,Data,
Handled);
end;
end;
if Handled then Command:=ecNone;
end;
Procedure TSourceEditor.EditorStatusChanged(Sender: TObject;
Changes: TSynStatusChanges);
Begin
If Assigned(OnEditorChange) then
OnEditorChange(Sender);
UpdatePageName;
end;
function TSourceEditor.SelectionAvailable: boolean;
begin
Result:=CompareCaret(EditorComponent.BlockBegin,EditorComponent.BlockEnd)<>0;
end;
function TSourceEditor.GetText(OnlySelection: boolean): string;
begin
if OnlySelection then
Result:=EditorComponent.SelText
else
Result:=EditorComponent.Lines.Text;
end;
{-------------------------------------------------------------------------------
method TSourceEditor.UpperCaseSelection
Turns current text selection uppercase.
-------------------------------------------------------------------------------}
procedure TSourceEditor.UpperCaseSelection;
var OldBlockBegin, OldBlockEnd: TPoint;
begin
if not EditorComponent.SelAvail then exit;
OldBlockBegin:=FEditor.BlockBegin;
OldBlockEnd:=FEditor.BlockEnd;
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
FEditor.SelText:=UpperCase(EditorComponent.SelText);
FEditor.BlockBegin:=OldBlockBegin;
FEditor.BlockEnd:=OldBlockEnd;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end;
{-------------------------------------------------------------------------------
method TSourceEditor.LowerCaseSelection
Turns current text selection lowercase.
-------------------------------------------------------------------------------}
procedure TSourceEditor.LowerCaseSelection;
var OldBlockBegin, OldBlockEnd: TPoint;
begin
if not EditorComponent.SelAvail then exit;
OldBlockBegin:=FEditor.BlockBegin;
OldBlockEnd:=FEditor.BlockEnd;
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
FEditor.SelText:=LowerCase(EditorComponent.SelText);
FEditor.BlockBegin:=OldBlockBegin;
FEditor.BlockEnd:=OldBlockEnd;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end;
{-------------------------------------------------------------------------------
method TSourceEditor.TabsToSpacesInSelection
Convert all tabs into spaces in current text selection.
-------------------------------------------------------------------------------}
procedure TSourceEditor.TabsToSpacesInSelection;
var OldBlockBegin, OldBlockEnd: TPoint;
begin
if not EditorComponent.SelAvail then exit;
OldBlockBegin:=FEditor.BlockBegin;
OldBlockEnd:=FEditor.BlockEnd;
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
// ToDo: replace step by step to keep bookmarks and breakpoints
FEditor.SelText:=TabsToSpaces(EditorComponent.SelText,EditorComponent.TabWidth);
FEditor.BlockBegin:=OldBlockBegin;
FEditor.BlockEnd:=OldBlockEnd;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end;
procedure TSourceEditor.CommentSelection;
var OldBlockBegin, OldBlockEnd: TPoint;
begin
if not EditorComponent.SelAvail then exit;
OldBlockBegin:=FEditor.BlockBegin;
OldBlockEnd:=FEditor.BlockEnd;
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
// ToDo: replace step by step to keep bookmarks and breakpoints
FEditor.SelText:=CommentLines(EditorComponent.SelText);
FEditor.BlockBegin:=OldBlockBegin;
FEditor.BlockEnd:=OldBlockEnd;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end;
procedure TSourceEditor.UncommentSelection;
var OldBlockBegin, OldBlockEnd: TPoint;
begin
if not EditorComponent.SelAvail then exit;
OldBlockBegin:=FEditor.BlockBegin;
OldBlockEnd:=FEditor.BlockEnd;
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
// ToDo: replace step by step to keep bookmarks and breakpoints
FEditor.SelText:=UncommentLines(EditorComponent.SelText);
FEditor.BlockBegin:=OldBlockBegin;
FEditor.BlockEnd:=OldBlockEnd;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end;
procedure TSourceEditor.SortSelection;
var
OldSelText, NewSortedText: string;
begin
OldSelText:=EditorComponent.SelText;
if OldSelText='' then exit;
if ShowSortSelectionDialog(OldSelText,EditorComponent.Highlighter,
NewSortedText)=mrOk
then
EditorComponent.SelText:=NewSortedText;
end;
procedure TSourceEditor.SelectToBrace;
begin
EditorComponent.SelectToBrace;
end;
procedure TSourceEditor.SelectCodeBlock;
begin
// ToDo:
writeln('TSourceEditor.SelectCodeBlock: not implemented yet');
end;
procedure TSourceEditor.SelectLine;
begin
EditorComponent.SelectLine;
end;
procedure TSourceEditor.SelectParagraph;
begin
EditorComponent.SelectParagraph;
end;
function TSourceEditor.CommentText(const Txt: string; CommentType: TCommentType
): string;
var
i: integer;
begin
Result:=Txt;
case CommentType of
comtNone: exit;
comtDefault:
begin
i:=EditorOpts.HighlighterList.FindByHighlighter(FEditor.Highlighter);
if i>=0 then
CommentType:=EditorOpts.HighlighterList[i].DefaultCommentType;
end;
end;
Result:=IDEProcs.CommentText(Txt,CommentType);
end;
procedure TSourceEditor.InsertCharacterFromMap;
var
NewChars: string;
begin
if not ShowCharacterMap(NewChars) then exit;
FEditor.SelText:=NewChars;
end;
procedure TSourceEditor.InsertGPLNotice(CommentType: TCommentType);
var
Txt: string;
begin
Txt:=CommentText(LCLProc.BreakString(
Format(lisGPLNotice,[#13#13,#13#13,#13#13]),
FEditor.RightEdge-2,0),CommentType);
FEditor.SelText:=Txt;
end;
procedure TSourceEditor.InsertLGPLNotice(CommentType: TCommentType);
var
Txt: string;
begin
Txt:=CommentText(LCLProc.BreakString(
Format(lisLGPLNotice,[#13#13,#13#13,#13#13]),
FEditor.RightEdge-2,0),CommentType);
FEditor.SelText:=Txt;
end;
procedure TSourceEditor.InsertUsername;
begin
FEditor.SelText:=GetCurrentUserName;
end;
procedure TSourceEditor.InsertDateTime;
begin
FEditor.SelText:=DateTimeToStr(now);
end;
procedure TSourceEditor.InsertChangeLogEntry;
var s: string;
begin
s:=DateToStr(now)+' '+GetCurrentUserName+' '+GetCurrentMailAddress;
FEditor.SelText:=s;
end;
procedure TSourceEditor.InsertCVSKeyword(const AKeyWord: string);
begin
FEditor.SelText:='$'+AKeyWord+'$'+EndOfLine;
end;
procedure TSourceEditor.OnGutterClick(Sender: TObject; X, Y, Line: integer;
mark: TSynEditMark);
var
BreakPtMark: TSourceMark;
begin
// create or delete breakpoint
// find breakpoint mark at line
BreakPtMark := SourceEditorMarks.FindBreakPointMark(FEditor,Line);
if BreakPtMark = nil then
DebugBoss.DoCreateBreakPoint(Filename,Line)
else
DebugBoss.DoDeleteBreakPointAtMark(BreakPtMark);
end;
procedure TSourceEditor.OnEditorSpecialLineColor(Sender: TObject; Line: integer;
var Special: boolean; var FG, BG: TColor);
var
i:integer;
aha: TAdditionalHilightAttribute;
CurMarks: PSourceMark;
CurMarkCount: integer;
CurFG: TColor;
CurBG: TColor;
begin
aha := ahaNone;
if ErrorLine = Line
then begin
aha := ahaErrorLine
end
else if ExecutionLine = Line
then begin
aha := ahaExecutionPoint;
end
else begin
SourceEditorMarks.GetMarksForLine(FEditor,Line,CurMarks,CurMarkCount);
if CurMarkCount>0 then begin
for i := 0 to CurMarkCount-1 do begin
// check highlight attribute
aha := CurMarks[i].LineColorAttrib;
if aha<>ahaNone then break;
// check custom colors
CurFG:=CurMarks[i].LineColorForeGround;
CurBG:=CurMarks[i].LineColorBackGround;
if (CurFG<>clNone) or (CurBG<>clNone) then begin
FG:=CurFG;
BG:=CurBG;
Special:=true;
break;
end;
end;
// clean up
FreeMem(CurMarks);
end;
end;
if aha <> ahaNone
then begin
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter, aha,
Special, FG, BG);
end;
end;
procedure TSourceEditor.SetSyntaxHighlighterType(
ASyntaxHighlighterType: TLazSyntaxHighlighter);
begin
if (ASyntaxHighlighterType=fSyntaxHighlighterType)
and ((FEditor.Highlighter=nil) xor EditorOpts.UseSyntaxHighlight) then exit;
if EditorOpts.UseSyntaxHighlight then begin
if Highlighters[ASyntaxHighlighterType]=nil then begin
Highlighters[ASyntaxHighlighterType]:=
EditorOpts.CreateSyn(ASyntaxHighlighterType);
end;
FEditor.Highlighter:=Highlighters[ASyntaxHighlighterType];
end else
FEditor.Highlighter:=nil;
if ASyntaxHighlighterType<>fSyntaxHighlighterType then begin
fSyntaxHighlighterType:=ASyntaxHighlighterType;
end;
EditorOpts.GetSynEditSelectedColor(FEditor);
TSourceNoteBook(FAOwner).UpdateActiveEditColors;
end;
procedure TSourceEditor.SetErrorLine(NewLine: integer);
begin
//writeln('[TSourceEditor.SetErrorLine] ',NewLine,',',fErrorLine);
if fErrorLine=NewLine then exit;
fErrorLine:=NewLine;
fErrorColumn:=EditorComponent.CaretX;
EditorComponent.Invalidate;
end;
procedure TSourceEditor.SetExecutionLine(NewLine: integer);
begin
if fExecutionLine=NewLine then exit;
fExecutionLine:=NewLine;
EditorComponent.Invalidate;
end;
Function TSourceEditor.RefreshEditorSettings : Boolean;
Begin
Result:=true;
SetSyntaxHighlighterType(fSyntaxHighlighterType);
EditorOpts.GetSynEditSettings(FEditor);
if EditorOpts.CtrlMouseLinks then
FEditor.Options:=FEditor.Options+[eoShowCtrlMouseLinks]
else
FEditor.Options:=FEditor.Options-[eoShowCtrlMouseLinks];
end;
Procedure TSourceEditor.ccAddMessage(Texts : String);
Begin
ErrorMsgs.Add(Texts);
End;
Procedure TSourceEditor.ccOnTimer(sender : TObject);
Begin
IdentCompletionTimer.Enabled := False;
End;
Procedure TSourceEditor.CreateEditor(AOwner : TComponent; AParent: TWinControl);
var
NewName: string;
i: integer;
Begin
{$IFDEF IDE_DEBUG}
writeln('TSourceEditor.CreateEditor A ');
{$ENDIF}
if not assigned(FEditor) then Begin
i:=0;
repeat
inc(i);
NewName:='SynEdit'+IntToStr(i);
until (AOwner.FindComponent(NewName)=nil);
FEditor:=TSynEdit.Create(AOwner);
FEditor.BeginUpdate;
with FEditor do begin
Name:=NewName;
Parent := AParent;
Align := alClient;
BookMarkOptions.EnableKeys := false;
BookMarkOptions.LeftMargin:=1;
OnStatusChange := @EditorStatusChanged;
OnProcessCommand := @ProcessCommand;
OnProcessUserCommand := @ProcessUserCommand;
OnCommandProcessed := @UserCommandProcessed;
OnReplaceText := @OnReplace;
OnGutterClick := @Self.OnGutterClick;
OnSpecialLineColors:=@OnEditorSpecialLineColor;
OnMouseMove := @EditorMouseMoved;
OnMouseDown := @EditorMouseDown;
OnMouseUp := @EditorMouseUp;
OnKeyDown := @EditorKeyDown;
end;
if FCodeTemplates<>nil then
FCodeTemplates.AddEditor(FEditor);
aCompletion.AddEditor(FEditor);
RefreshEditorSettings;
FEditor.EndUpdate;
end else begin
FEditor.Parent:=AParent;
end;
end;
procedure TSourceEditor.SetCodeBuffer(NewCodeBuffer: TCodeBuffer);
begin
if NewCodeBuffer=FCodeBuffer then exit;
if FCodeBuffer<>nil then
FCodeBuffer.RemoveChangeHook(@OnCodeBufferChanged);
FCodeBuffer:=NewCodeBuffer;
if FCodeBuffer<>nil then begin
FCodeBuffer.AddChangeHook(@OnCodeBufferChanged);
if (FIgnoreCodeBufferLock<=0) and (not FCodeBuffer.IsEqual(FEditor.Lines))
then begin
{$IFDEF IDE_DEBUG}
writeln('');
writeln('WARNING: TSourceEditor.SetCodeBuffer - loosing marks');
writeln('');
{$ENDIF}
FEditor.BeginUpdate;
FCodeBuffer.AssignTo(FEditor.Lines);
FEditor.EndUpdate;
end;
if IsActiveOnNoteBook then SourceNoteBook.UpdateStatusBar;
end;
end;
procedure TSourceEditor.OnCodeBufferChanged(Sender: TSourceLog;
SrcLogEntry: TSourceLogEntry);
procedure InsertTxt(StartPos: TPoint; const Txt: string);
begin
FEditor.CaretXY:=StartPos;
FEditor.BlockBegin:=StartPos;
FEditor.BlockEnd:=StartPos;
FEditor.SelText:=Txt;
end;
procedure DeleteTxt(StartPos, EndPos: TPoint);
begin
FEditor.CaretXY:=StartPos;
FEditor.BlockBegin:=StartPos;
FEditor.BlockEnd:=EndPos;
FEditor.SelText:='';
end;
procedure MoveTxt(StartPos, EndPos, MoveToPos: TPoint;
DirectionForward: boolean);
var Txt: string;
begin
FEditor.CaretXY:=StartPos;
FEditor.BlockBegin:=StartPos;
FEditor.BlockEnd:=EndPos;
Txt:=FEditor.SelText;
if DirectionForward then begin
FEditor.CaretXY:=MoveToPos;
FEditor.BlockBegin:=MoveToPos;
FEditor.BlockEnd:=MoveToPos;
FEditor.SelText:=Txt;
FEditor.CaretXY:=StartPos;
FEditor.BlockBegin:=StartPos;
FEditor.BlockEnd:=EndPos;
FEditor.SelText:='';
end else begin
FEditor.SelText:='';
FEditor.CaretXY:=MoveToPos;
FEditor.BlockBegin:=MoveToPos;
FEditor.BlockEnd:=MoveToPos;
FEditor.SelText:=Txt;
end;
end;
var StartPos, EndPos, MoveToPos: TPoint;
begin
{$IFDEF IDE_DEBUG}
writeln('[TSourceEditor.OnCodeBufferChanged] A ',FIgnoreCodeBufferLock,' ',SrcLogEntry<>nil);
{$ENDIF}
if FIgnoreCodeBufferLock>0 then exit;
if SrcLogEntry<>nil then begin
FEditor.BeginUpdate;
FEditor.BeginUndoBlock;
case SrcLogEntry.Operation of
sleoInsert:
begin
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
if StartPos.Y>=1 then
InsertTxt(StartPos,SrcLogEntry.Txt);
end;
sleoDelete:
begin
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
EndPos.Y,EndPos.X);
if (StartPos.Y>=1) and (EndPos.Y>=1) then
DeleteTxt(StartPos,EndPos);
end;
sleoMove:
begin
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
EndPos.Y,EndPos.X);
Sender.AbsoluteToLineCol(SrcLogEntry.MoveTo,MoveToPos.Y,MoveToPos.X);
if (StartPos.Y>=1) and (EndPos.Y>=1) and (MoveToPos.Y>=1) then
MoveTxt(StartPos, EndPos, MoveToPos,
SrcLogEntry.Position<SrcLogEntry.MoveTo);
end;
end;
FEditor.EndUndoBlock;
FEditor.EndUpdate;
end else begin
if Sender.IsEqual(FEditor.Lines) then exit;
Sender.AssignTo(FEditor.Lines);
end;
end;
procedure TSourceEditor.IncreaseIgnoreCodeBufferLock;
begin
inc(FIgnoreCodeBufferLock);
end;
procedure TSourceEditor.DecreaseIgnoreCodeBufferLock;
begin
if FIgnoreCodeBufferLock<=0 then exit;
dec(FIgnoreCodeBufferLock);
end;
procedure TSourceEditor.UpdateCodeBuffer;
// copy the source from EditorComponent
begin
if not FEditor.Modified then exit;
{$IFDEF IDE_DEBUG}
if FCodeBuffer=nil then begin
writeln('');
writeln('*********** Oh, no: UpdateCodeBuffer ************');
writeln('');
end;
{$ENDIF}
if FCodeBuffer=nil then exit;
IncreaseIgnoreCodeBufferLock;
FModified:=FModified or FEditor.Modified;
FCodeBuffer.Assign(FEditor.Lines);
FEditor.Modified:=false;
DecreaseIgnoreCodeBufferLock;
end;
Function TSourceEditor.GetSource : TStrings;
Begin
//return synedit's source.
Result := FEditor.Lines;
end;
procedure TSourceEditor.SetPageName(const AValue: string);
begin
if FPageName=AValue then exit;
FPageName:=AValue;
UpdatePageName;
end;
procedure TSourceEditor.UpdatePageName;
var
p: Integer;
NewPageName: String;
begin
p:=SourceNotebook.FindPageWithEditor(Self);
NewPageName:=FPageName;
if Modified then NewPageName:='*'+NewPageName;
if SourceNotebook.NoteBook.Pages[p]<>NewPageName then
SourceNotebook.NoteBook.Pages[p]:=NewPageName;
end;
Procedure TSourceEditor.SetSource(value : TStrings);
Begin
FEditor.Lines.Assign(Value);
end;
Function TSourceEditor.GetCurrentCursorXLine : Integer;
Begin
Result := FEditor.CaretX
end;
Procedure TSourceEditor.SetCurrentCursorXLine(num : Integer);
Begin
FEditor.CaretX := Num;
end;
Function TSourceEditor.GetCurrentCursorYLine : Integer;
Begin
Result := FEditor.CaretY;
end;
Procedure TSourceEditor.SetCurrentCursorYLine(num : Integer);
Begin
FEditor.CaretY := Num;
end;
Procedure TSourceEditor.SelectText(LineNum,CharStart,LineNum2,CharEnd : Integer);
var
P : TPoint;
Begin
P.X := CharStart;
P.Y := LineNum;
FEditor.BlockBegin := P;
P.X := CharEnd;
P.Y := LineNum2;
FEditor.BlockEnd := P;
end;
procedure TSourceEditor.ReplaceLines(StartLine, EndLine: integer;
const NewText: string);
begin
FEditor.BeginUndoBlock;
FEditor.BlockBegin:=Point(1,StartLine);
FEditor.BlockEnd:=Point(length(FEditor.Lines[Endline-1])+1,EndLine);
FEditor.SelText:=NewText;
FEditor.EndUndoBlock;
end;
procedure TSourceEditor.EncloseSelection;
var
EncloseType: TEncloseSelectionType;
EncloseTemplate: string;
NewSelection: string;
NewCaretXY: TPoint;
begin
if not FEditor.SelAvail then begin
FEditor.BlockBegin:=FEditor.CaretXY;
FEditor.BlockEnd:=FEditor.CaretXY;
end;
if ShowEncloseSelectionDialog(EncloseType)<>mrOk then exit;
GetEncloseSelectionParams(EncloseType,EncloseTemplate);
EncloseTextSelection(EncloseTemplate,FEditor.Lines,
FEditor.BlockBegin,FEditor.BlockEnd,
FEditor.BlockIndent,
NewSelection,NewCaretXY);
//writeln('TSourceEditor.EncloseSelection A NewCaretXY=',NewCaretXY.X,',',NewCaretXY.Y,
// ' "',NewSelection,'"');
FEditor.SelText:=NewSelection;
FEditor.CaretXY:=NewCaretXY;
end;
Function TSourceEditor.GetModified : Boolean;
Begin
Result := FEditor.Modified or FModified;
end;
procedure TSourceEditor.SetModified(NewValue:boolean);
var
OldModified: Boolean;
begin
OldModified:=Modified;
FModified:=NewValue;
if not FModified then FEditor.Modified:=false;
if OldModified<>Modified then
UpdatePageName;
end;
Function TSourceEditor.GetInsertMode : Boolean;
Begin
Result := FEditor.Insertmode;
end;
Function TSourceEditor.Close : Boolean;
Begin
Result := True;
If Assigned(FOnBeforeClose) then
FOnBeforeClose(Self);
Visible := False;
aCompletion.RemoveEditor(FEditor);
SourceEditorMarks.DeleteAllForEditor(FEditor);
FEditor.Parent:=nil;
CodeBuffer := nil;
If Assigned(FOnAfterClose) then FOnAfterClose(Self);
end;
Procedure TSourceEditor.ReParent(AParent : TWInControl);
Begin
CreateEditor(FAOwner,AParent);
End;
procedure TSourceEditor.SetCodeTemplates(
NewCodeTemplates: TSynEditAutoComplete);
begin
if NewCodeTemplates<>FCodeTemplates then begin
if FCodeTemplates<>nil then
FCodeTemplates.RemoveEditor(FEditor);
if NewCodeTemplates<>nil then
NewCodeTemplates.AddEditor(FEditor);
end;
end;
procedure TSourceEditor.SetPopupMenu(NewPopupMenu: TPopupMenu);
begin
if NewPopupMenu<>FPopupMenu then begin
FPopupMenu:=NewPopupMenu;
if FEditor<>nil then FEditor.PopupMenu:=NewPopupMenu;
end;
end;
function TSourceEditor.GetFilename: string;
begin
if FCodeBuffer<>nil then
Result:=FCodeBuffer.Filename
else
Result:='';
end;
Procedure TSourceEditor.EditorMouseMoved(Sender : TObject;
Shift : TShiftState; X,Y : Integer);
begin
// Writeln('MouseMove in Editor',X,',',Y);
if Assigned(OnMouseMove) then
OnMouseMove(Self,Shift,X,Y);
end;
Function TSourceEditor.GetWordAtPosition(Position : TPoint) : String;
var
CaretPos : TPoint;
begin
Result := '';
Caretpos := GetCaretPosfromCursorPos(Position);
Result := GetWordFromCaret(CaretPos);
end;
Procedure TSourceEditor.EditorMouseDown(Sender : TObject; Button : TMouseButton;
Shift : TShiftState; X, Y : Integer);
begin
if Assigned(OnMouseDown) then
OnMouseDown(Sender, Button, Shift, X,Y);
end;
procedure TSourceEditor.EditorMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Assigned(OnMouseUp) then
OnMouseUp(Sender, Button, Shift, X,Y);
end;
Procedure TSourceEditor.EditorKeyDown(Sender : TObject; var Key : Word; Shift :
TShiftState);
begin
if Assigned(OnKeyDown) then
OnKeyDown(Sender, Key, Shift);
end;
Function TSourceEditor.GetCaretPosFromCursorPos(CursorPos : TPoint) : TPoint;
var
TopLine : Integer;
LineHeight : Integer;
LineNum : Integer;
XLine : Integer;
begin
//Figure out the line number
TopLine := FEditor.TopLine;
LineHeight := FEditor.LineHeight;
if CursorPos.Y > 1 then
LineNum := CursorPos.Y div LineHeight
else
LineNum := 1;
LineNum := LineNUm + (TopLine);
XLine := CursorPos.X div FEditor.CharWidth;
if XLine = 0 then inc(XLine);
Result.X := XLine;
Result.Y := LineNum;
end;
{-------------------------------------------------------------------------------
method TSourceEditor.CenterCursor
Params: none
Result: none
Center the current cursor line in editor.
-------------------------------------------------------------------------------}
procedure TSourceEditor.CenterCursor;
var NewTopLine: integer;
begin
NewTopLine:=EditorComponent.CaretY-((EditorComponent.LinesInWindow-1) div 2);
if NewTopLine<1 then NewTopLine:=1;
EditorComponent.TopLine:=NewTopLine;
end;
procedure TSourceEditor.Activate;
begin
if (FSourceNoteBook=nil) then exit;
FSourceNoteBook.SetActiveSE(Self);
end;
function TSourceEditor.PageIndex: integer;
begin
if FSourceNoteBook<>nil then
Result:=FSourceNoteBook.FindPageWithEditor(Self)
else
Result:=-1;
end;
function TSourceEditor.CaretInSelection(const ACaretPos: TPoint): Boolean;
begin
Result := (CompareCaret(EditorComponent.BlockBegin, ACaretpos) >= 0)
and (CompareCaret(ACaretPos, EditorComponent.BlockEnd) >= 0);
end;
function TSourceEditor.PositionInSelection(const APosition: TPoint): Boolean;
begin
Result := CaretInSelection(GetCaretPosfromCursorPos(APosition));
end;
function TSourceEditor.IsActiveOnNoteBook: boolean;
begin
if FSourceNoteBook<>nil then
Result:=(FSourceNoteBook.GetActiveSE=Self)
else
Result:=false;
end;
Function TSourceEditor.GetWordAtCurrentCaret: String;
var
CaretPos : TPoint;
begin
Result := '';
CaretPos.Y := CurrentCursorYLine;
CaretPos.X := CurrentCursorXLine;
Result := GetWordFromCaret(CaretPos);
end;
function TSourceEditor.GetWordFromCaret(const ACaretPos : TPoint) : String;
begin
Result := GetWordFromCaretEx(ACaretPos, ['A'..'Z', 'a'..'z', '0'..'9'], ['A'..'Z', 'a'..'z', '0'..'9']);
end;
function TSourceEditor.GetWordFromCaretEx(const ACaretPos: TPoint; const ALeftLimit, ARightLimit: TCharSet): String;
var
XLine,YLine : Integer;
EditorLine: String;
begin
Result := '';
YLine := ACaretPos.Y;
XLine := ACaretPos.X;
EditorLine := FEditor.Lines[YLine-1];
if Length(trim(EditorLine)) = 0 then Exit;
if XLine > Length(EditorLine) then Exit;
if not (EditorLine[XLine] in ALeftLimit) then Exit;
//walk backwards to a space or non-standard character.
while (XLine > 1) and (EditorLine[XLine - 1] in ALeftLimit) do Dec(XLine);
//chop off the beginning
Result := Copy(EditorLine, XLine, Length(EditorLine));
//start forward search
XLine := ACaretPos.X - XLine + 1;
while (XLine <= Length(Result)) and (Result[XLine] in ARightLimit) do Inc(Xline);
// Strip remainder
SetLength(Result, XLine - 1);
end;
procedure TSourceEditor.LinesDeleted(sender : TObject; FirstLine,
Count : Integer);
begin
//notify the notebook that lines were deleted.
//marks will use this to update themselves
end;
procedure TSourceEditor.LinesInserted(sender : TObject; FirstLine,
Count : Integer);
begin
//notify the notebook that lines were Inserted.
//marks will use this to update themselves
end;
procedure TSourceEditor.SetVisible(Value: boolean);
begin
if FVisible=Value then exit;
if FEditor<>nil then FEditor.Visible:=Value;
FVisible:=Value;
end;
procedure TSourceEditor.DoEditorExecuteCommand(EditorCommand: integer);
begin
EditorComponent.CommandProcessor(EditorCommand,' ',nil);
end;
{------------------------------------------------------------------------}
{ TSourceNotebook }
constructor TSourceNotebook.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Visible:=false;
Name:=NonModalIDEWindowNames[nmiwSourceNoteBookName];
Caption := locWndSrcEditor;
FProcessingCommand := false;
FMainIDE := AOwner;
EnvironmentOptions.IDEWindowLayoutList.Apply(Self,Name);
FSourceEditorList := TList.Create;
FUnUsedEditorComponents := TList.Create;
// code templates
FCodeTemplateModul:=TSynEditAutoComplete.Create(Self);
with FCodeTemplateModul do begin
if FileExists(EditorOpts.CodeTemplateFilename) then
AutoCompleteList.LoadFromFile(EditorOpts.CodeTemplateFilename)
else
if FileExists('lazarus.dci') then
AutoCompleteList.LoadFromFile('lazarus.dci');
IndentToTokenStart:=EditorOpts.CodeTemplateIndentToTokenStart;
OnTokenNotFound:=@OnCodeTemplateTokenNotFound;
EndOfTokenChr:=' ()[]{},.;:"+-*^@$\<>=''';
end;
// word completion
if aWordCompletion=nil then begin
aWordCompletion:=TWordCompletion.Create;
with AWordCompletion do begin
WordBufferCapacity:=100;
OnGetSource:=@OnWordCompletionGetSource;
end;
end;
// identifier completion
IdentCompletionTimer := TTimer.Create(self);
IdentCompletionTimer.Enabled := False;
IdentCompletionTimer.Interval := 500;
// marks
SourceEditorMarks:=TSourceMarks.Create(Self);
SourceEditorMarks.OnGetSourceEditor:=@OnSourceMarksGetSourceEditor;
SourceEditorMarks.OnGetFilename:=@OnSourceMarksGetFilename;
// key mapping
FKeyStrokes:=TSynEditKeyStrokes.Create(Self);
EditorOpts.KeyMap.AssignTo(FKeyStrokes,[caSourceEditor]);
// popup menu
BuildPopupMenu;
// completion form
aCompletion := TSynCompletion.Create(AOwner);
with aCompletion do
Begin
EndOfTokenChr:='()[]';
Width:=400;
OnExecute := @ccExecute;
OnCancel := @ccCancel;
OnCodeCompletion := @ccComplete;
OnPaintItem:=@OnSynCompletionPaintItem;
OnSearchPosition:=@OnSynCompletionSearchPosition;
ShortCut:=Menus.ShortCut(VK_UNKNOWN,[]);
end;
// statusbar
StatusBar := TStatusBar.Create(self);
with Statusbar do
begin
Parent := Self;
Name := 'StatusBar';
Visible := True;
SimpleText := 'This is a test';
Panels.Add; //x,y coord
Panels.Add; //Readonly/Modified
Panels.Add; //OVR/INS
Panels.Add; //Unitname
Panels[0].Text := '';
Panels[0].Width := 100;
Panels[0].Bevel := pbLowered;
Panels[1].Text := '';
Panels[1].Bevel := pbLowered;
Panels[1].Width := 150;
Panels[2].Text := '';
Panels[2].Bevel := pbLowered;
Panels[2].Width := 50;
Panels[3].Text := 'INS';
Panels[3].Bevel := pbLowered;
Panels[3].Width := 50;
SimplePanel := False;
end;
// goto dialog
GotoDialog := TfrmGoto.Create(self);
// HintTimer
FHintTimer := TTimer.Create(nil);
with FHintTimer do begin
Interval := 500;
Enabled := False;
OnTimer := @HintTimer;
end;
// HintWindow
FHintWindow := THintWindow.Create(nil);
with FHintWindow do begin
Visible := False;
Caption := '';
HideInterval := 4000;
AutoHide := False;
end;
Application.AddOnUserInputHandler(@OnApplicationUserInput);
end;
destructor TSourceNotebook.Destroy;
var i: integer;
begin
FProcessingCommand:=false;
for i:=FSourceEditorList.Count-1 downto 0 do
Editors[i].Free;
ClearUnUsedEditorComponents(true);
FUnUsedEditorComponents.Free;
if Notebook<>nil then begin
FreeThenNil(Notebook);
end;
FKeyStrokes.Free;
FCodeTemplateModul.Free;
FSourceEditorList.Free;
Gotodialog.free;
FreeThenNil(FHintTimer);
FreeThenNil(FHintWindow);
FreeThenNil(fCustomPopupMenuItems);
inherited Destroy;
end;
function TSourceNotebook.OnSynCompletionPaintItem(const AKey: string;
ACanvas: TCanvas; X, Y: integer; ItemSelected: boolean;
Index: integer): boolean;
var
MaxX: Integer;
begin
with ACanvas do begin
if (aCompletion<>nil) and (aCompletion.Editor<>nil) then
Font:=aCompletion.Editor.Font
else begin
Font.Name:=EditorOpts.EditorFont;
Font.Size:=EditorOpts.EditorFontHeight;
end;
Font.Style:=[];
if not ItemSelected then
Font.Color:=FActiveEditDefaultFGColor
else
Font.Color:=FActiveEditSelectedFGColor;
end;
MaxX:=aCompletion.TheForm.ClientWidth;
PaintCompletionItem(AKey,ACanvas,X,Y,MaxX,ItemSelected,Index,aCompletion,
CurrentCompletionType);
Result:=true;
end;
procedure TSourceNotebook.OnWordCompletionGetSource(var Source:TStrings;
SourceIndex:integer);
var TempEditor: TSourceEditor;
i:integer;
begin
TempEditor:=GetActiveSE;
if SourceIndex=0 then begin
Source:=TempEditor.EditorComponent.Lines;
end else begin
i:=0;
while (i<FSourceEditorList.Count) do begin
if Editors[i]<>TempEditor then dec(SourceIndex);
if SourceIndex=0 then begin
Source:=Editors[i].EditorComponent.Lines;
exit;
end;
inc(i);
end;
Source:=nil;
end;
end;
procedure TSourceNotebook.OnCodeTemplateTokenNotFound(Sender: TObject;
AToken: string; AnEditor: TCustomSynEdit; var Index:integer);
var P:TPoint;
begin
//writeln('RRRRRRRRRRR ',AToken,',',AnEditor.ReadOnly,',',CurrentCompletionType=ctNone);
if (AnEditor.ReadOnly=false) and (CurrentCompletionType=ctNone) then begin
CurrentCompletionType:=ctTemplateCompletion;
with AnEditor do
P := ClientToScreen(Point(CaretXPix,CaretYPix+LineHeight));
aCompletion.Editor:=AnEditor;
aCompletion.Execute(AToken,P.X,P.Y);
end;
end;
procedure TSourceNotebook.OnSynCompletionSearchPosition(var APosition:integer);
// word changed
var
i,x:integer;
CurStr,s:Ansistring;
SL:TStringList;
ItemCnt: Integer;
begin
if CurCompletionControl=nil then exit;
case CurrentCompletionType of
ctIdentCompletion:
begin
// rebuild completion list
APosition:=0;
CurStr:=CurCompletionControl.CurrentString;
CodeToolBoss.IdentifierList.Prefix:=CurStr;
ItemCnt:=CodeToolBoss.IdentifierList.GetFilteredCount;
SL:=TStringList.Create;
try
for i:=0 to ItemCnt-1 do
SL.Add('Dummy');
CurCompletionControl.ItemList:=SL;
finally
SL.Free;
end;
end;
ctTemplateCompletion:
begin
// search CurrentString in bold words (words after #3'B')
CurStr:=CurCompletionControl.CurrentString;
i:=0;
while i<CurCompletionControl.ItemList.Count do begin
s:=CurCompletionControl.ItemList[i];
x:=1;
while (x<=length(s)) and (s[x]<>#3) do inc(x);
if x<length(s) then begin
inc(x,2);
if AnsiCompareText(CurStr,copy(s,x,length(CurStr)))=0 then begin
APosition:=i;
break;
end;
end;
inc(i);
end;
end;
ctWordCompletion:
begin
// rebuild completion list
APosition:=0;
CurStr:=CurCompletionControl.CurrentString;
SL:=TStringList.Create;
try
aWordCompletion.GetWordList(SL, CurStr, false, 30);
CurCompletionControl.ItemList:=SL;
finally
SL.Free;
end;
end;
end;
end;
procedure TSourceNotebook.DeactivateCompletionForm;
begin
CurCompletionControl.Deactivate;
CurCompletionControl:=nil;
CurrentCompletionType:=ctNone;
end;
procedure TSourceNotebook.InitIdentCompletion(S: TStrings);
type
TMethodRec = record
Flags : TParamFlags;
ParamName : ShortString;
TypeName : ShortString;
end;
var
CompInt : TComponentInterface;
propKind : TTypeKind;
TypeInfo : PTypeInfo;
TypeData : PTypeData;
MethodRec: TMethodRec;
CompName: String;
CurLine: String;
I, X1, X2: Integer;
ParamStr: String;
PropName: String;
Count,Offset,Len: Integer;
ActiveEditor: TSynEdit;
Prefix: string;
NewStr: string;
Handled: boolean;
Abort: boolean;
ItemCnt: Integer;
begin
Prefix := CurCompletionControl.CurrentString;
if Assigned(OnInitIdentCompletion) then begin
OnInitIdentCompletion(Self,Handled,Abort);
if Handled then begin
if Abort then exit;
// add one entry per item
CodeToolBoss.IdentifierList.Prefix:=Prefix;
ItemCnt:=CodeToolBoss.IdentifierList.GetFilteredCount;
writeln('InitIdentCompletion B Prefix=',Prefix,' ItemCnt=',ItemCnt);
CurCompletionControl.Position:=0;
for i:=0 to ItemCnt-1 do
s.Add('Dummy');
exit;
end;
end;
CompInt := nil;
ccSelection := Prefix;
ActiveEditor:=GetActiveSE.EditorComponent;
with ActiveEditor do begin
CurLine:=LineText;
X1:=CaretX-1;
end;
if X1>length(CurLine) then X1:=length(CurLine);
while (X1>0) and (CurLine[X1]<>'.') do dec(X1);
X2:=X1-1;
while (X2>0) and (CurLine[X2] in ['A'..'Z','a'..'z','0'..'9','_']) do dec(X2);
CompName:=copy(CurLine,X2+1,X1-X2-1);
CompInt := TComponentInterface(FormEditor1.FindComponentByName(CompName));
if CompInt = nil then begin
ccSelection:='';
end else begin
//get all methods
NewStr := '';
for I := 0 to CompInt.GetPropCount-1 do
Begin
PropName:=#3'B'+CompInt.GetPropName(I)+#3'b';
PropKind := CompInt.GetPropType(i);
case PropKind of
tkMethod :
Begin
TypeInfo := CompInt.GetPropTypeInfo(I);
TypeData := GetTypeData(TypeInfo);
//check for parameters
if TypeData^.ParamCount > 0 then
Begin
{Writeln('----');
for Count := 0 to 60 do
if TypeData^.ParamList[Count] in ['a'..'z','A'..'Z','0'..'9'] then
Write(TypeData^.ParamList[Count])
else
Begin
Write('$',HexStr(ord(TypeData^.ParamList[Count]),3),' ');
end;
}
ParamStr := '';
Offset:=0;
for Count := 0 to TypeData^.ParamCount-1 do
begin
Len:=1; // strange: SizeOf(TParamFlags) is 4, but the data is only 1 byte
Move(TypeData^.ParamList[Offset],MethodRec.Flags,Len);
inc(Offset,Len);
Len:=ord(TypeData^.ParamList[Offset]);
inc(Offset);
SetLength(MethodRec.ParamName,Len);
Move(TypeData^.ParamList[Offset],MethodRec.ParamName[1],Len);
inc(Offset,Len);
Len:=ord(TypeData^.ParamList[Offset]);
inc(Offset);
SetLength(MethodRec.TypeName,Len);
Move(TypeData^.ParamList[Offset],MethodRec.TypeName[1],Len);
inc(Offset,Len);
if ParamStr<>'' then ParamStr:=';'+ParamStr;
if MethodRec.ParamName='' then
ParamStr:=MethodRec.TypeName+ParamStr
else
ParamStr:=MethodRec.ParamName+':'+MethodRec.TypeName+ParamStr;
if (pfVar in MethodRec.Flags) then ParamStr := 'var '+ParamStr;
if (pfConst in MethodRec.Flags) then ParamStr := 'const '+ParamStr;
if (pfOut in MethodRec.Flags) then ParamStr := 'out '+ParamStr;
end;
NewStr:='('+ParamStr+')';
end else NewStr:='';
case TypeData^.MethodKind of
mkProcedure :
NewStr := 'procedure '+PropName+' :'+CompInt.GetPropTypeName(I);
mkFunction :
NewStr := 'function '+PropName+' :'+CompInt.GetPropTypeName(I);
mkClassFunction :
NewStr := 'function '+PropName+' :'+'Function '+NewStr;
mkClassProcedure :
NewStr := 'procedure '+PropName+' :'+'Procedure '+NewStr;
mkConstructor :
NewStr := 'constructor '+PropName+' '+'procedure ';
mkDestructor :
NewStr := 'destructor '+PropName+' '+'procedure ';
end;
end;
tkObject :
NewStr := 'object '+PropName+' :'+CompInt.GetPropTypeName(I);
tkInteger,tkChar,tkEnumeration,tkWChar :
NewStr := 'var '+PropName+' :'+CompInt.GetPropTypeName(I);
tkBool :
NewStr := 'var '+PropName+' :'+CompInt.GetPropTypeName(I);
tkClass :
NewStr := 'class '+PropName+' :'+CompInt.GetPropTypeName(I);
tkFloat :
NewStr := 'var '+PropName+' :'+CompInt.GetPropTypeName(I);
tkSString :
NewStr := 'var '+PropName+' :'+CompInt.GetPropTypeName(I);
tkUnKnown,tkLString,tkWString,tkAString,tkVariant :
NewStr := 'var '+PropName+' :'+CompInt.GetPropTypeName(I);
end;
if NewStr <> '' then S.Add(NewStr);
NewStr := '';
end; // end for
end;
end;
procedure TSourceNotebook.ccComplete(var Value: ansistring; Shift: TShiftState);
// completion selected -> deactivate completion form
// Called when user has selected a completion item
function CharBehindIdent(const Line: string; StartPos: integer): char;
begin
while (StartPos<=length(Line))
and (Line[StartPos] in ['_','A'..'Z','a'..'z']) do
inc(StartPos);
while (StartPos<=length(Line)) and (Line[StartPos] in [' ',#9]) do
inc(StartPos);
if StartPos<=length(Line) then
Result:=Line[StartPos]
else
Result:=#0;
end;
function CharInFrontOfIdent(const Line: string; StartPos: integer): char;
begin
while (StartPos>=1)
and (Line[StartPos] in ['_','A'..'Z','a'..'z']) do
dec(StartPos);
while (StartPos>=1) and (Line[StartPos] in [' ',#9]) do
dec(StartPos);
if StartPos>=1 then
Result:=Line[StartPos]
else
Result:=#0;
end;
var
p1, p2: integer;
ValueType: TIdentComplValue;
SrcEdit: TSourceEditor;
CaretXY: TPoint;
CursorToLeft: integer;
NewValue: String;
Begin
if CurCompletionControl=nil then exit;
case CurrentCompletionType of
ctIdentCompletion:
begin
// add to history
CodeToolBoss.IdentifierHistory.Add(
CodeToolBoss.IdentifierList.FilteredItems[aCompletion.Position]);
// get value
NewValue:=GetIdentCompletionValue(aCompletion,ValueType,CursorToLeft);
// insert value plus special chars like brackets, semicolons, ...
SrcEdit:=GetActiveSE;
SrcEdit.EditorComponent.SelText:=NewValue;
if CursorToLeft>0 then
begin
CaretXY:=SrcEdit.EditorComponent.BlockEnd;
dec(CaretXY.X,CursorToLeft);
SrcEdit.EditorComponent.CaretXY:=CaretXY;
end;
ccSelection := '';
Value:='';
end;
ctTemplateCompletion:
begin
// the completion is the bold text between #3'B' and #3'b'
p1:=Pos(#3,Value);
if p1>=0 then begin
p2:=p1+2;
while (p2<=length(Value)) and (Value[p2]<>#3) do inc(p2);
Value:=copy(Value,p1+2,p2-p1-2);
// keep parent identifier (in front of '.')
p1:=length(ccSelection);
while (p1>=1) and (ccSelection[p1]<>'.') do dec(p1);
if p1>=1 then
Value:=copy(ccSelection,1,p1)+Value;
end;
ccSelection := '';
if Value<>'' then
FCodeTemplateModul.ExecuteCompletion(Value,
GetActiveSE.EditorComponent);
Value:='';
end;
ctWordCompletion:
// the completion is already in Value
begin
ccSelection := '';
if Value<>'' then AWordCompletion.AddWord(Value);
end;
end;
DeactivateCompletionForm;
End;
Procedure TSourceNotebook.ccCancel(Sender : TObject);
// user cancels completion form
var ActSE: TSourceEditor;
begin
if CurCompletionControl=nil then exit;
DeactivateCompletionForm;
ActSE:=GetActiveSE;
if ActSE<>nil then LCLIntf.ShowCaret(ActSE.EditorComponent.Handle);
end;
Procedure TSourceNotebook.ccExecute(Sender : TObject);
// init completion form
var
S : TStrings;
Prefix: String;
I: Integer;
NewStr: String;
ActiveEditor: TSynEdit;
Begin
CurCompletionControl := TSynBaseCompletion(Sender);
S := TStringList.Create;
Prefix := CurCompletionControl.CurrentString;
ActiveEditor:=GetActiveSE.EditorComponent;
case CurrentCompletionType of
ctIdentCompletion:
InitIdentCompletion(S);
ctWordCompletion:
begin
ccSelection:='';
end;
ctTemplateCompletion:
begin
ccSelection:='';
for I:=0 to FCodeTemplateModul.Completions.Count-1 do begin
NewStr:=FCodeTemplateModul.Completions[I];
if NewStr<>'' then begin
NewStr:=#3'B'+NewStr+#3'b';
while length(NewStr)<10+4 do NewStr:=NewStr+' ';
NewStr:=NewStr+' '+FCodeTemplateModul.CompletionComments[I];
S.Add(NewStr);
end;
end;
end;
end;
CurCompletionControl.ItemList := S;
S.Free;
CurCompletionControl.CurrentString:=Prefix;
// set colors
if (ActiveEditor<>nil) and (CurCompletionControl.TheForm<>nil) then begin
with CurCompletionControl.TheForm do begin
Color:=FActiveEditDefaultBGColor;
clSelect:=FActiveEditSelectedBGColor;
TextColor:=FActiveEditDefaultFGColor;
TextSelectedColor:=FActiveEditSelectedFGColor;
end;
end;
End;
Function TSourceNotebook.CreateNotebook : Boolean;
Begin
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] START');
{$ENDIF}
{$IFDEF IDE_MEM_CHECK}
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] A ');
{$ENDIF}
ClearUnUsedEditorComponents(false);
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] A');
{$ENDIF}
{$IFDEF IDE_MEM_CHECK}
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] B ');
{$ENDIF}
Result := False;
if not assigned(Notebook) then
Begin
Result := True;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] B');
{$ENDIF}
Notebook := TNotebook.Create(self);
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] C');
{$ENDIF}
{$IFDEF IDE_MEM_CHECK}
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] C ');
{$ENDIF}
with Notebook do
Begin
Name:='SrcEditNotebook';
Parent := Self;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] D');
{$ENDIF}
Align := alClient;
if PageCount>0 then
Pages.Strings[0] := 'unit1'
else
Pages.Add('unit1');
PageIndex := 0; // Set it to the first page
if EditorOpts.ShowTabCloseButtons then
Options:=Options+[nboShowCloseButtons]
else
Options:=Options-[nboShowCloseButtons];
OnPageChanged := @NotebookPageChanged;
OnCloseTabClicked:=@CloseClicked;
ShowHint:=true;
OnShowHint:=@NotebookShowTabHint;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] E');
{$ENDIF}
Visible := true;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] F');
{$ENDIF}
{$IFDEF IDE_MEM_CHECK}
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] F ');
{$ENDIF}
end; //with
Show; //used to display the code form
end;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.CreateNotebook] END');
{$ENDIF}
{$IFDEF IDE_MEM_CHECK}
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] END ');
{$ENDIF}
End;
Procedure TSourceNotebook.ClearUnUsedEditorComponents(Force: boolean);
var i:integer;
begin
if (not Force) and FProcessingCommand then exit;
for i:=FUnUsedEditorComponents.Count-1 downto 0 do
TSynEdit(FUnUsedEditorComponents[i]).Free;
FUnUsedEditorComponents.Clear;
end;
procedure TSourceNotebook.EditorPropertiesClicked(Sender: TObject);
begin
if Assigned(FOnEditorPropertiesClicked) then
FOnEditorPropertiesClicked(Sender);
end;
procedure TSourceNotebook.SrcPopUpMenuPopup(Sender: TObject);
var
ASrcEdit: TSourceEditor;
BookMarkID, BookMarkX, BookMarkY: integer;
MarkSrcEdit: TSourceEditor;
MarkDesc: String;
MarkEditorIndex: Integer;
MarkMenuItem: TMenuItem;
EditorComp: TSynEdit;
Marks: PSourceMark;
MarkCount: integer;
i: Integer;
CurMark: TSourceMark;
EditorPopupPoint: TPoint;
begin
if not (Sender is TPopupMenu) then exit;
RemoveUserDefinedMenuItems;
ASrcEdit:=
FindSourceEditorWithEditorComponent(TPopupMenu(Sender).PopupComponent);
if ASrcEdit=nil then exit;
EditorComp:=ASrcEdit.EditorComponent;
// readonly
ReadOnlyMenuItem.Checked:=ASrcEdit.ReadOnly;
ShowLineNumbersMenuItem.Checked:=EditorComp.Gutter.ShowLineNumbers;
// bookmarks
for BookMarkID:=0 to 9 do begin
MarkDesc:=' '+IntToStr(BookMarkID);
MarkSrcEdit:=FindBookmark(BookMarkID);
if (MarkSrcEdit<>nil)
and MarkSrcEdit.EditorComponent.GetBookMark(BookMarkID,BookMarkX,BookMarkY)
then begin
MarkEditorIndex:=FindPageWithEditor(MarkSrcEdit);
MarkDesc:=MarkDesc+': '+Notebook.Pages[MarkEditorIndex]
+' ('+IntToStr(BookMarkY)+','+IntToStr(BookMarkX)+')';
end;
// set book mark item
MarkMenuItem:=SetBookmarkMenuItem[BookMarkID];
MarkMenuItem.Checked:=(MarkSrcEdit<>nil);
MarkMenuItem.Caption:=uemSetBookmark+MarkDesc;
// goto book mark item
MarkMenuItem:=GotoBookmarkMenuItem[BookMarkID];
MarkMenuItem.Checked:=(MarkSrcEdit<>nil);
MarkMenuItem.Caption:=uemBookmarkN+MarkDesc;
end;
// editor layout
MoveEditorLeftMenuItem.Enabled:=(NoteBook<>nil) and (NoteBook.PageCount>1);
MoveEditorRightMenuItem.Enabled:=(NoteBook<>nil) and (NoteBook.PageCount>1);
EditorPopupPoint:=EditorComp.ScreenToClient(SrcPopUpMenu.PopupPoint);
if EditorPopupPoint.X>EditorComp.Gutter.Width then begin
// user clicked on text
end else begin
// user clicked on gutter
SourceEditorMarks.GetMarksForLine(EditorComp,EditorComp.CaretY,
Marks,MarkCount);
if Marks<>nil then begin
for i:=0 to MarkCount-1 do begin
CurMark:=Marks[i];
CurMark.CreatePopupMenuItems(@AddUserDefinedPopupMenuItem);
end;
FreeMem(Marks);
end;
end;
end;
procedure TSourceNotebook.NotebookShowTabHint(Sender: TObject;
HintInfo: Pointer);
var
Tabindex: integer;
ASrcEdit: TSourceEditor;
begin
if (NoteBook=nil) or (HintInfo=nil) then exit;
TabIndex:=NoteBook.TabIndexAtClientPos(
Notebook.ScreenToClient(Mouse.CursorPos));
if TabIndex<0 then exit;
ASrcEdit:=FindSourceEditorWithPageIndex(TabIndex);
if ASrcEdit=nil then exit;
if ASrcEdit.CodeBuffer<>nil then begin
PHintInfo(HintInfo)^.HintStr:=ASrcEdit.CodeBuffer.Filename;
end;
end;
function TSourceNotebook.OnSourceMarksGetFilename(ASourceEditor: TObject
): string;
begin
if (ASourceEditor=nil) or (not (ASourceEditor is TSourceEditor)) then
RaiseException('TSourceNotebook.OnSourceMarksGetFilename');
Result:=TSourceEditor(ASourceEditor).Filename;
end;
function TSourceNotebook.OnSourceMarksGetSourceEditor(ASynEdit: TCustomSynEdit
): TObject;
begin
Result:=FindSourceEditorWithEditorComponent(ASynEdit);
end;
Procedure TSourceNotebook.BuildPopupMenu;
Function Seperator : TMenuItem;
Begin
Result := TMenuItem.Create(Self);
Result.Caption := '-';
end;
var
SubMenuItem : TMenuItem;
I : Integer;
Begin
SrcPopupMenu := TPopupMenu.Create(Self);
with SrcPopupMenu do begin
AutoPopup := True;
OnPopup :=@SrcPopUpMenuPopup;
end;
FindDeclarationMenuItem := TMenuItem.Create(Self);
with FindDeclarationMenuItem do begin
Name:='FindDeclarationMenuItem';
Caption := uemFindDeclaration;
OnClick := @FindDeclarationClicked;
end;
SrcPopupMenu.Items.Add(FindDeclarationMenuItem);
OpenFileAtCursorMenuItem := TMenuItem.Create(Self);
with OpenFileAtCursorMenuItem do begin
Name:='OpenFileAtCursorMenuItem';
Caption := uemOpenFileAtCursor;
OnClick := @OpenAtCursorClicked;
end;
SrcPopupMenu.Items.Add(OpenFileAtCursorMenuItem);
ClosePageMenuItem := TMenuItem.Create(Self);
with ClosePageMenuItem do begin
Name:='ClosePageMenuItem';
Caption := uemClosePage;
OnClick := @CloseClicked;
end;
SrcPopupMenu.Items.Add(ClosePageMenuItem);
SrcPopupMenu.Items.Add(Seperator);
GotoBookmarkMenuItem := TMenuItem.Create(Self);
with GotoBookmarkMenuItem do begin
Name:='GotoBookmarkMenuItem';
Caption := uemGotoBookmark;
end;
SrcPopupMenu.Items.Add(GotoBookmarkMenuItem);
for I := 0 to 9 do
Begin
SubMenuItem := TMenuItem.Create(Self);
with SubmenuItem do begin
Name:='GotoBookmark'+IntToStr(I)+'MenuItem';
Caption := uemBookmarkN+IntToStr(i);
OnClick := @BookmarkGotoClicked;
end;
GotoBookmarkMenuItem.Add(SubMenuItem);
end;
SetBookmarkMenuItem := TMenuItem.Create(Self);
with SetBookmarkMenuItem do begin
Name:='SetBookmarkMenuItem';
Caption := uemSetBookmark;
end;
SrcPopupMenu.Items.Add(SetBookmarkMenuItem);
for I := 0 to 9 do
Begin
SubMenuItem := TMenuItem.Create(Self);
with SubMenuItem do begin
Name:='SubSetBookmarkMenuItem'+IntToStr(I);
Caption := uemBookmarkN+IntToStr(i);
OnClick := @BookmarkSetClicked;
end;
SetBookmarkMenuItem.Add(SubMenuItem);
end;
SrcPopupMenu.Items.Add(Seperator);
ReadOnlyMenuItem := TMenuItem.Create(Self);
with ReadOnlyMenuItem do begin
Name:='ReadOnlyMenuItem';
Caption := uemReadOnly;
OnClick := @ReadOnlyClicked;
ShowAlwaysCheckable:=true;
end;
SrcPopupMenu.Items.Add(ReadOnlyMenuItem);
ShowLineNumbersMenuItem := TMenuItem.Create(Self);
with ShowLineNumbersMenuItem do begin
Name := 'ShowLineNumbersMenuItem';
Caption := dlgShowLineNumbers;
OnClick := @ToggleLineNumbersClicked;
ShowAlwaysCheckable:=true;
end;
SrcPopupMenu.Items.Add(ShowLineNumbersMenuItem);
SrcPopupMenu.Items.Add(Seperator);
ShowUnitInfoMenuItem := TMenuItem.Create(Self);
with ShowUnitInfoMenuItem do begin
Name:='ShowUnitInfoMenuItem';
Caption := uemUnitInfo;
OnClick:=@ShowUnitInfo;
end;
SrcPopupMenu.Items.Add(ShowUnitInfoMenuItem);
SrcPopupMenu.Items.Add(Seperator);
DebugMenuItem := TMenuItem.Create(Self);
with DebugMenuItem do begin
Name:='DebugMenuItem';
Caption := uemDebugWord;
end;
SrcPopupMenu.Items.Add(DebugMenuItem);
AddBreakpointMenuItem := TMenuItem.Create(Self);
with AddBreakpointMenuItem do begin
Name := 'AddBreakpointMenuItem';
Caption := uemAddBreakpoint;
OnClick := @AddBreakpointClicked;
end;
DebugMenuItem.Add(AddBreakpointMenuItem);
AddWatchAtCursorMenuItem := TMenuItem.Create(Self);
with AddWatchAtCursorMenuItem do begin
Name := 'AddWatchAtCursorMenuItem';
Caption := uemAddWatchAtCursor;
OnClick := @AddWatchAtCursor;
end;
DebugMenuItem.Add(AddWatchAtCursorMenuItem);
RunToCursorMenuItem := TMenuItem.Create(Self);
with RunToCursorMenuItem do begin
Name := 'RunToCursorMenuItem';
Caption := uemRunToCursor;
OnClick := @RunToClicked;
end;
DebugMenuItem.Add(RunToCursorMenuItem);
ViewCallStackMenuItem := TMenuItem.Create(Self);
with ViewCallStackMenuItem do begin
Name := 'ViewCallStackMenuItem';
Caption := uemViewCallStackCursor;
OnClick := @ViewCallStackClick;
end;
DebugMenuItem.Add(ViewCallStackMenuItem);
SrcPopupMenu.Items.Add(Seperator);
MoveEditorLeftMenuItem := TMenuItem.Create(Self);
with MoveEditorLeftMenuItem do begin
Name := 'MoveEditorLeftMenuItem';
Caption := uemMoveEditorLeft;
OnClick :=@MoveEditorLeftClicked;
end;
SrcPopupMenu.Items.Add(MoveEditorLeftMenuItem);
MoveEditorRightMenuItem := TMenuItem.Create(Self);
with MoveEditorRightMenuItem do begin
Name := 'MoveEditorRightMenuItem';
Caption := uemMoveEditorRight;
OnClick :=@MoveEditorRightClicked;
end;
SrcPopupMenu.Items.Add(MoveEditorRightMenuItem);
SrcPopupMenu.Items.Add(Seperator);
EditorPropertiesMenuItem := TMenuItem.Create(Self);
with EditorPropertiesMenuItem do begin
Name := 'EditorPropertiesMenuItem';
Caption := uemEditorproperties;
OnClick :=@EditorPropertiesClicked;
end;
SrcPopupMenu.Items.Add(EditorPropertiesMenuItem);
end;
procedure TSourceNotebook.RemoveUserDefinedMenuItems;
var
AMenuItem: TMenuItem;
begin
if fCustomPopupMenuItems=nil then exit;
while fCustomPopupMenuItems.Count>0 do begin
AMenuItem:=TMenuItem(fCustomPopupMenuItems[fCustomPopupMenuItems.Count-1]);
AMenuItem.Free;
fCustomPopupMenuItems.Delete(fCustomPopupMenuItems.Count-1);
end;
end;
function TSourceNotebook.AddUserDefinedPopupMenuItem(const NewCaption: string;
const NewEnabled: boolean; const NewOnClick: TNotifyEvent): TMenuItem;
var
NewIndex: Integer;
begin
if fCustomPopupMenuItems=nil then fCustomPopupMenuItems:=TList.Create;
NewIndex:=fCustomPopupMenuItems.Count;
Result:=TMenuItem.Create(Self);
fCustomPopupMenuItems.Add(Result);
Result.Caption:=NewCaption;
Result.Enabled:=NewEnabled;
Result.OnClick:=NewOnClick;
SrcPopUpMenu.Items.Insert(NewIndex,Result);
end;
{-------------------------------------------------------------------------------
Procedure TSourceNotebook.EditorChanged
Params: Sender : TObject
Result: none
Called whenever an editor status changes. Sender is normally a TSynEdit.
-------------------------------------------------------------------------------}
Procedure TSourceNotebook.EditorChanged(Sender : TObject);
var SenderDeleted: boolean;
Begin
SenderDeleted:=FUnUsedEditorComponents.IndexOf(Sender)>=0;
ClearUnUsedEditorComponents(false);
UpdateStatusBar;
if (not SenderDeleted) and Assigned(OnEditorChanged) then
OnEditorChanged(Sender);
End;
Function TSourceNotebook.NewSE(PageNum : Integer) : TSourceEditor;
Begin
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.NewSE A ');
{$ENDIF}
if CreateNotebook then Pagenum := 0;
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.NewSE A2 ');
{$ENDIF}
if Pagenum < 0 then begin
// add a new page right to the current
Pagenum := Notebook.PageIndex+1;
Notebook.Pages.Insert(PageNum,FindUniquePageName('',-1));
end;
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.NewSE B ',Notebook.PageIndex,',',NoteBook.Pages.Count);
{$ENDIF}
Result := TSourceEditor.Create(Self,Notebook.Page[PageNum]);
Result.EditorComponent.BeginUpdate;
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.NewSE C ');
{$ENDIF}
FSourceEditorList.Add(Result);
Result.CodeTemplates:=CodeTemplateModul;
Notebook.PageIndex := Pagenum;
Result.FPageName:=NoteBook.Pages[Pagenum];
Result.EditorComponent.BookMarkOptions.BookmarkImages :=
SourceEditorMarks.ImgList;
Result.PopupMenu:=SrcPopupMenu;
Result.OnEditorChange := @EditorChanged;
Result.OnMouseMove := @EditorMouseMove;
Result.OnMouseDown := @EditorMouseDown;
Result.OnMouseUp := @EditorMouseUp;
Result.EditorComponent.EndUpdate;
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.NewSE end ');
{$ENDIF}
end;
function TSourceNotebook.FindSourceEditorWithPageIndex(
PageIndex:integer):TSourceEditor;
var I:integer;
TempEditor : TControl;
begin
ClearUnUsedEditorComponents(false);
Result := nil;
if (FSourceEditorList=nil)
or (Notebook=nil)
or (PageIndex<0) or (PageIndex>=Notebook.PageCount) then exit;
TempEditor:=nil;
with Notebook.Page[PageIndex] do
for I := 0 to ControlCount-1 do
if Controls[I] is TSynEdit then
Begin
TempEditor := Controls[I];
Break;
end;
if TempEditor=nil then exit;
I := FSourceEditorList.Count-1;
while (I>=0)
and (TSourceEditor(FSourceEditorList[I]).EditorComponent <> TempEditor) do
dec(i);
if i<0 then exit;
Result := TSourceEditor(FSourceEditorList[i]);
end;
Function TSourceNotebook.GetActiveSE : TSourceEditor;
Begin
Result := nil;
if (FSourceEditorList=nil) or (FSourceEditorList.Count=0)
or (Notebook=nil) or (Notebook.PageIndex<0) then exit;
Result:=FindSourceEditorWithPageIndex(Notebook.PageIndex);
end;
procedure TSourceNotebook.SetActiveSE(SrcEdit: TSourceEditor);
var
i: integer;
begin
i:=FindPageWithEditor(SrcEdit);
if i>=0 then
NoteBook.PageIndex:=i;
end;
procedure TSourceNotebook.LockAllEditorsInSourceChangeCache;
// lock all sourceeditors that are to be modified by the CodeToolBoss
var i: integer;
begin
for i:=0 to EditorCount-1 do begin
if CodeToolBoss.SourceChangeCache.BufferIsModified(Editors[i].CodeBuffer)
then begin
with Editors[i].EditorComponent do begin
BeginUpdate;
BeginUndoBlock;
end;
end;
end;
end;
procedure TSourceNotebook.UnlockAllEditorsInSourceChangeCache;
// unlock all sourceeditors that were modified by the CodeToolBoss
var i: integer;
begin
for i:=0 to EditorCount-1 do begin
if CodeToolBoss.SourceChangeCache.BufferIsModified(Editors[i].CodeBuffer)
then begin
with Editors[i].EditorComponent do begin
EndUndoBlock;
EndUpdate;
end;
end;
end;
end;
function TSourceNotebook.GetDiffFiles: TDiffFiles;
var
i: Integer;
SrcEdit: TSourceEditor;
begin
Result:=TDiffFiles.Create;
if Notebook=nil then exit;
for i:=0 to NoteBook.PageCount-1 do begin
SrcEdit:=FindSourceEditorWithPageIndex(i);
Result.Add(TDiffFile.Create(NoteBook.Pages[i],i,SrcEdit.SelectionAvailable));
end;
end;
procedure TSourceNotebook.GetSourceText(PageIndex: integer;
OnlySelection: boolean; var Source: string);
var
SrcEdit: TSourceEditor;
begin
SrcEdit:=FindSourceEditorWithPageIndex(PageIndex);
if SrcEdit=nil then
Source:=''
else
Source:=SrcEdit.GetText(OnlySelection);
end;
Function TSourceNotebook.Empty : Boolean;
Begin
Result := (not assigned(Notebook)) or (Notebook.PageCount = 0);
end;
procedure TSourceNotebook.FindReplaceDlgKey(Sender: TObject; var Key: Word;
Shift: TShiftState; FindDlgComponent: TFindDlgComponent);
var
HistoryList: TStringList;
CurText: string;
CurIndex: integer;
procedure SetHistoryText;
var s: string;
begin
if FindReplaceDlgHistoryIndex[FindDlgComponent]>=0 then
s:=HistoryList[FindReplaceDlgHistoryIndex[FindDlgComponent]]
else
s:=FindReplaceDlgUserText[FindDlgComponent];
//writeln(' SetHistoryText "',s,'"');
FindReplaceDlg.ComponentText[FindDlgComponent]:=s
end;
procedure FetchFocus;
begin
if Sender is TWinControl then
TWinControl(Sender).SetFocus;
end;
begin
if FindDlgComponent=fdcText then
HistoryList:=InputHistories.FindHistory
else
HistoryList:=InputHistories.ReplaceHistory;
CurIndex:=FindReplaceDlgHistoryIndex[FindDlgComponent];
CurText:=FindReplaceDlg.ComponentText[FindDlgComponent];
//writeln('TSourceNotebook.FindReplaceDlgKey CurIndex=',CurIndex,' CurText="',CurText,'"');
if Key=VK_Down then begin
// go forward in history
if CurIndex>=0 then begin
if (HistoryList[CurIndex]<>CurText) then begin
// save user text
FindReplaceDlgUserText[FindDlgComponent]:=CurText;
end;
dec(FindReplaceDlgHistoryIndex[FindDlgComponent]);
SetHistoryText;
end;
FetchFocus;
Key:=VK_UNKNOWN;
end else if Key=VK_UP then begin
if (CurIndex<0)
or (HistoryList[CurIndex]<>CurText) then
begin
// save user text
FindReplaceDlgUserText[FindDlgComponent]:=CurText;
end;
// go back in history
if CurIndex<HistoryList.Count-1 then
begin
inc(FindReplaceDlgHistoryIndex[FindDlgComponent]);
SetHistoryText;
end;
FetchFocus;
Key:=VK_UNKNOWN;
end;
end;
procedure TSourceNotebook.EndIncrementalFind;
begin
if not (snIncrementalFind in States) then exit;
Exclude(States,snIncrementalFind);
UpdateStatusBar;
end;
function TSourceNotebook.SomethingModified: boolean;
var i: integer;
begin
Result:=false;
for i:=0 to EditorCount-1 do Result:=Result or Editors[i].Modified;
end;
Procedure TSourceNotebook.NextEditor;
Begin
if NoteBook=nil then exit;
if Notebook.PageIndex < Notebook.PageCount-1 then
Notebook.PageIndex := Notebook.PageIndex+1
else
NoteBook.PageIndex := 0;
End;
Procedure TSourceNotebook.PrevEditor;
Begin
if NoteBook=nil then exit;
if Notebook.PageIndex > 0 then
Notebook.PageIndex := Notebook.PageIndex-1
else
NoteBook.PageIndex := NoteBook.PageCount-1;
End;
procedure TSourceNotebook.MoveEditor(OldPageIndex, NewPageIndex: integer);
begin
if (NoteBook=nil) or (NoteBook.PageCount<=1)
or (OldPageIndex=NewPageIndex)
or (OldPageIndex<0) or (OldPageIndex>=Notebook.PageCount)
or (NewPageIndex<0) or (NewPageIndex>=Notebook.PageCount) then exit;
if Assigned(OnMovingPage) then
OnMovingPage(Self,OldPageIndex,NewPageIndex);
NoteBook.Pages.Move(OldPageIndex,NewPageIndex);
end;
procedure TSourceNotebook.MoveEditorLeft(PageIndex: integer);
begin
if (NoteBook=nil) or (NoteBook.PageCount<=1) then exit;
if PageIndex>0 then
MoveEditor(PageIndex,PageIndex-1)
else
MoveEditor(PageIndex,NoteBook.PageCount-1);
end;
procedure TSourceNotebook.MoveEditorRight(PageIndex: integer);
begin
if (NoteBook=nil) or (NoteBook.PageCount<=1) then exit;
if PageIndex<Notebook.PageCount-1 then
MoveEditor(PageIndex,PageIndex+1)
else
MoveEditor(PageIndex,0);
end;
procedure TSourceNotebook.MoveActivePageLeft;
begin
if (NoteBook=nil) then exit;
MoveEditorLeft(NoteBook.PageIndex);
end;
procedure TSourceNotebook.MoveActivePageRight;
begin
if (NoteBook=nil) then exit;
MoveEditorRight(NoteBook.PageIndex);
end;
Procedure TSourceNotebook.FindClicked(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSE;
if TempEditor <> nil then TempEditor.StartFindAndReplace(false);
End;
Procedure TSourceNotebook.ReplaceClicked(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSE;
if TempEditor <> nil then TempEditor.StartFindAndReplace(true);
End;
procedure TSourceNotebook.IncrementalFindClicked(Sender: TObject);
var
TempEditor: TSourceEditor;
begin
TempEditor:=GetActiveSE;
if TempEditor = nil then exit;
Include(States,snIncrementalFind);
fIncrementalSearchStartPos:=TempEditor.EditorComponent.CaretXY;
IncrementalSearchStr:='';
UpdateStatusBar;
end;
Procedure TSourceNotebook.FindNextClicked(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSe;
if TempEditor <> nil then TempEditor.FindNext;
End;
Procedure TSourceNotebook.FindPreviousClicked(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSe;
if TempEditor <> nil then TempEditor.FindPrevious;
End;
Procedure TSourceNotebook.FindInFiles(AProject: TProject);
var
TheFileList: TStringList; //List of Files to be searched.
TheMatchedFiles: TStringList; //List of files that contain a match
i: integer; //loop counter
AnUnitInfo: TUnitInfo;
LocalFindText: String; //Text to search for
AText: string; //Formated message string
Begin
if FindInFilesDialog=nil then
FindInFilesDialog:=TLazFindInFilesDialog.Create(Application);
with FindInFilesDialog do
begin
TextToFindComboBox.Items.Assign(InputHistories.FindHistory);
DirectoryComboBox.Items.Assign(InputHistories.FindInFilesPathHistory);
FileMaskComboBox.Items.Assign(InputHistories.FindInFilesMaskHistory);
end;//With
if FindInFilesDialog.ShowModal=mrOk then
begin
LocalFindText:=FindInFilesDialog.FindText;
with FindInFilesDialog do
begin
InputHistories.AddToFindHistory(FindText);
InputHistories.AddToFindInFilesPathHistory(DirectoryComboBox.Text);
InputHistories.AddToFindInFilesMaskHistory(FileMaskComboBox.Text);
end;//with
InputHistories.Save;
if LocalFindText<>'' then
begin
try
TheFileList:= TStringList.Create;
// find in project files
if FindInFilesDialog.WhereRadioGroup.ItemIndex = 0 then
begin
AnUnitInfo:=AProject.FirstPartOfProject;
while AnUnitInfo<>nil do begin
//Only if file exists on disk.
if FilenameIsAbsolute(AnUnitInfo.FileName)
and FileExists(AnUnitInfo.FileName) then
TheFileList.Add(AnUnitInfo.FileName);
AnUnitInfo:=AnUnitInfo.NextPartOfProject;
end;
end;//if
// find in open files
if FindInFilesDialog.WhereRadioGroup.ItemIndex = 1 then
begin
for i:= 0 to self.EditorCount -1 do
//only if file exists on disk
if FilenameIsAbsolute(Editors[i].FileName)
and FileExists(Editors[i].FileName) then
TheFileList.Add(Editors[i].FileName);
end;//if
//Find in Directories
if FindInFilesDialog.WhereRadioGroup.ItemIndex = 2 then
begin
FindMatchingTextFiles(TheFileList,
FindInFilesDialog.DirectoryComboBox.Text,
FindInFilesDialog.FileMaskComboBox.Text,
FindInFilesDialog.IncludeSubDirsCheckBox.Checked);
end;//if
//if the file search returned any files then look for the search
//text in each file.
if TheFileList.Count > 0 then
begin
MessagesView.Clear;
MessagesView.ShowOnTop;
try
try
TheMatchedFiles:= IDEProcs.FindInFiles(TheFileList,
LocalFindText,
FindInFilesDialog.WholeWordsOnlyCheckBox.Checked,
FindInFilesDialog.CaseSensitiveCheckBox.Checked,
FindInFilesDialog.RegularExpressionsCheckBox.Checked);
except
on E: ERegExpr do begin
MessageDlg(lisUEErrorInRegularExpression,
E.Message,mtError,[mbCancel],0);
exit;
end;//on except
end;//try-except
//if we matched any files add them to the message window
if (TheMatchedFiles<>nil) and (TheMatchedFiles.Count>0) then
begin
MessagesView.AddSeparator;
for i:= 0 to TheMatchedFiles.Count -1 do
begin
MessagesView.Add(TheMatchedFiles.Strings[i],'',false);
end;//for
//Hand off the search to the FindAndReplace Function in the
//unit editor.
with FindReplaceDlg do
begin
FindText:=LocalFindText;
Options:= FindInFilesDialog.SynSearchOptions;
//Multiline RegExpr?
Options:= Options-[ssoRegExprMultiLine];
end;//with
end//if
else
begin
MessagesView.Clear;
MessagesView.ShowOnTop;
MessagesView.AddSeparator;
AText:=Format(lisUESearchStringNotFound,[LocalFindText]);
MessagesView.Add(AText,'',false);
end;//else
finally
TheMatchedFiles.Free;
end;//try-finally
end//if
else
begin
MessagesView.Clear;
MessagesView.ShowOnTop;
MessagesView.AddSeparator;
MessagesView.Add(lisFileNotFound,'',false);
end;//else
finally
TheFileList.Free;
end;//try-finally
end//if
else
begin
MessagesView.Clear;
MessagesView.ShowOnTop;
MessagesView.AddSeparator;
AText:=Format(lisUESearchStringNotFound,[LocalFindText]);
MessagesView.Add(AText,'',false);
end;//else
end;//if
End;//FindInFilesClicked
procedure TSourceNotebook.GotoLineClicked(Sender: TObject);
var SrcEdit: TSourceEditor;
begin
SrcEdit:=GetActiveSE;
if SrcEdit<>nil then SrcEdit.ShowGotoLineDialog;
end;
procedure TSourceNotebook.HistoryJump(Sender: TObject;
Action: TJumpHistoryAction);
var NewCaretXY: TPoint;
NewTopLine: integer;
NewPageIndex: integer;
SrcEdit: TSourceEditor;
begin
if (NoteBook<>nil) and Assigned(OnJumpToHistoryPoint) then begin
NewCaretXY.X:=-1;
NewPageIndex:=-1;
OnJumpToHistoryPoint(NewCaretXY,NewTopLine,NewPageIndex,Action);
SrcEdit:=FindSourceEditorWithPageIndex(NewPageIndex);
if SrcEdit<>nil then begin
NoteBook.PageIndex:=NewPageIndex;
with SrcEdit.EditorComponent do begin
TopLine:=NewTopLine;
CaretXY:=NewCaretXY;
BlockBegin:=CaretXY;
BlockEnd:=CaretXY;
end;
end;
end;
end;
procedure TSourceNotebook.JumpBackClicked(Sender: TObject);
begin
HistoryJump(Sender,jhaBack);
end;
procedure TSourceNotebook.JumpForwardClicked(Sender: TObject);
begin
HistoryJump(Sender,jhaForward);
end;
procedure TSourceNotebook.AddJumpPointClicked(Sender: TObject);
var SrcEdit: TSourceEditor;
begin
if Assigned(OnAddJumpPoint) then begin
SrcEdit:=GetActiveSE;
if SrcEdit<>nil then begin
OnAddJumpPoint(SrcEdit.EditorComponent.CaretXY,
SrcEdit.EditorComponent.TopLine, Notebook.PageIndex, true);
end;
end;
end;
procedure TSourceNotebook.DeleteLastJumpPointClicked(Sender: TObject);
begin
if Assigned(OnDeleteLastJumpPoint) then
OnDeleteLastJumpPoint(Sender);
end;
procedure TSourceNotebook.ViewJumpHistoryClicked(Sender: TObject);
begin
if Assigned(OnViewJumpHistory) then
OnViewJumpHistory(Sender);
end;
procedure TSourceNotebook.ActivateHint(const ScreenPos: TPoint;
const TheHint: string);
var
HintWinRect: TRect;
begin
if FHintWindow<>nil then
FHintWindow.Visible:=false;
if FHintWindow=nil then
FHintWindow:=THintWindow.Create(Self);
HintWinRect := FHintWindow.CalcHintRect(Screen.Width, TheHint, nil);
OffsetRect(HintWinRect, ScreenPos.X, ScreenPos.Y+30);
FHintWindow.ActivateHint(HintWinRect,TheHint);
end;
procedure TSourceNotebook.HideHint;
begin
if FHintTimer<>nil then
FHintTimer.Enabled:=false;
if IdentCompletionTimer<>nil then
IdentCompletionTimer.Enabled:=false;
if FHintWindow<>nil then
FHintWindow.Visible:=false;
end;
Procedure TSourceNotebook.BookMarkSetClicked(Sender : TObject);
// popup menu: set bookmark clicked
var
MenuItem : TMenuItem;
Begin
MenuItem := TMenuItem(sender);
BookMarkSet(MenuItem.MenuIndex);
end;
Procedure TSourceNotebook.BookMarkGotoClicked(Sender : TObject);
// popup menu goto bookmark clicked
var
MenuItem : TMenuItem;
Begin
MenuItem := TMenuItem(sender);
GotoBookMark(MenuItem.MenuIndex);
end;
Procedure TSourceNotebook.ReadOnlyClicked(Sender : TObject);
var ActEdit:TSourceEditor;
begin
ActEdit:=GetActiveSE;
if ActEdit.ReadOnly and (ActEdit.CodeBuffer<>nil)
and (not ActEdit.CodeBuffer.IsVirtual)
and (not FileIsWritable(ActEdit.CodeBuffer.Filename)) then begin
MessageDlg(ueFileROCap,
ueFileROText1+ActEdit.CodeBuffer.Filename+ueFileROText2,
mtError,[mbCancel],0);
exit;
end;
ActEdit.EditorComponent.ReadOnly := not(ActEdit.EditorComponent.ReadOnly);
if Assigned(OnReadOnlyChanged) then
OnReadOnlyChanged(Self);
UpdateStatusBar;
end;
Procedure TSourceNotebook.ShowUnitInfo(Sender : TObject);
begin
if Assigned(FOnShowUnitInfo) then FOnShowUnitInfo(Sender);
end;
Procedure TSourceNotebook.ToggleLineNumbersClicked(Sender : TObject);
var
MenuITem : TMenuItem;
ActEdit:TSourceEditor;
i: integer;
ShowLineNumbers: boolean;
begin
MenuItem := TMenuITem(Sender);
ActEdit:=GetActiveSE;
MenuItem.Checked := not(ActEdit.EditorComponent.Gutter.ShowLineNumbers);
ShowLineNumbers:=MenuItem.Checked;
for i:=0 to EditorCount-1 do
Editors[i].EditorComponent.Gutter.ShowLineNumbers := ShowLineNumbers;
EditorOpts.ShowLineNumbers := ShowLineNumbers;
EditorOpts.Save;
end;
Procedure TSourceNotebook.OpenAtCursorClicked(Sender : TObject);
begin
if Assigned(FOnOpenFileAtCursorClicked) then
FOnOpenFileAtCursorClicked(Sender);
end;
Procedure TSourceNotebook.FindDeclarationClicked(Sender : TObject);
begin
if Assigned(FOnFindDeclarationClicked) then
FOnFindDeclarationClicked(Sender);
end;
Procedure TSourceNotebook.BookMarkToggle(Value : Integer);
var
MenuItem : TMenuItem;
ActEdit,AnEdit:TSourceEditor;
Begin
MenuItem := TMenuItem(SetBookmarkMenuItem.Items[Value]);
MenuItem.Checked := not MenuItem.Checked;
ActEdit:=GetActiveSE;
AnEdit:=FindBookmark(Value);
if AnEdit<>nil then AnEdit.EditorComponent.ClearBookMark(Value);
if MenuItem.Checked then
Begin
ActEdit.EditorComponent.SetBookMark(Value,
ActEdit.EditorComponent.CaretX,ActEdit.EditorComponent.CaretY);
MenuItem.Caption := MenuItem.Caption + '*';
end
else
begin
MenuItem.Caption := copy(MenuItem.Caption,1,Length(MenuItem.Caption)-1);
end;
end;
procedure TSourceNotebook.MoveEditorLeftClicked(Sender: TObject);
begin
MoveActivePageLeft;
end;
procedure TSourceNotebook.MoveEditorRightClicked(Sender: TObject);
begin
MoveActivePageRight;
end;
{This is called from outside to toggle a bookmark}
Procedure TSourceNotebook.ToggleBookmark(Value : Integer);
Begin
BookMarkToggle(Value);
End;
procedure TSourceNotebook.AddBreakpointClicked(Sender: TObject );
var
ASrcEdit: TSourceEditor;
begin
ASrcEdit:=GetActiveSE;
if ASrcEdit=nil then exit;
DebugBoss.DoCreateBreakPoint(ASrcEdit.Filename,
ASrcEdit.EditorComponent.CaretY);
end;
procedure TSourceNotebook.RunToClicked(Sender: TObject);
var
ASrcEdit: TSourceEditor;
begin
ASrcEdit:=GetActiveSE;
if ASrcEdit=nil then exit;
DebugBoss.DoRunToCursor;
end;
procedure TSourceNotebook.ViewCallStackClick(Sender: TObject);
var
Command: TSynEditorCommand;
AChar: char;
Data: pointer;
Handled: boolean;
begin
Command:=ecToggleCallStack;
AChar:=#0;
Data:=nil;
Handled:=false;
ProcessParentCommand(Self,Command,AChar,Data,Handled);
end;
Procedure TSourceNotebook.BookMarkSet(Value : Integer);
var
MenuItem : TMenuItem;
ActEdit,AnEdit:TSourceEditor;
Begin
MenuItem := TMenuItem(SetBookmarkMenuItem.Items[Value]);
ActEdit:=GetActiveSE;
AnEdit:=FindBookmark(Value);
if AnEdit<>nil then begin
AnEdit.EditorComponent.ClearBookMark(Value);
end;
ActEdit.EditorComponent.SetBookMark(Value,
ActEdit.EditorComponent.CaretX,ActEdit.EditorComponent.CaretY);
MenuItem.Checked := true;
GotoBookmarkMenuItem[Value].Checked:=true;
end;
{This is called from outside to set a bookmark}
Procedure TSourceNotebook.SetBookmark(Value : Integer);
Begin
BookMarkSet(Value);
End;
Procedure TSourceNotebook.BookMarkGoto(Index : Integer);
var
AnEditor:TSourceEditor;
begin
if Notebook=nil then exit;
AnEditor:=FindBookmark(Index);
if AnEditor<>nil then begin
AnEditor.EditorComponent.GotoBookMark(Index);
AnEditor.CenterCursor;
Notebook.PageIndex:=FindPageWithEditor(AnEditor);
end;
end;
{This is called from outside to Go to a bookmark}
Procedure TSourceNotebook.GoToBookmark(Value: Integer);
begin
BookMarkGoTo(Value);
End;
Procedure TSourceNotebook.NewFile(const NewShortName: String;
ASource : TCodeBuffer; FocusIt: boolean);
Var
TempEditor : TSourceEditor;
Begin
//create a new page
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.NewFile] A ');
{$ENDIF}
Visible:=true;
TempEditor := NewSE(-1);
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.NewFile] B ');
{$ENDIF}
TempEditor.CodeBuffer:=ASource;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.NewFile] D ');
{$ENDIF}
TempEditor.PageName:=FindUniquePageName(NewShortName,Notebook.PageIndex);
if FocusIt then FocusEditor;
{$IFDEF IDE_DEBUG}
writeln('[TSourceNotebook.NewFile] end');
{$ENDIF}
end;
Procedure TSourceNotebook.CloseFile(PageIndex:integer);
var
TempEditor: TSourceEditor;
Begin
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.CloseFile A PageIndex=',PageIndex);
{$ENDIF}
TempEditor:=FindSourceEditorWithPageIndex(PageIndex);
if TempEditor=nil then exit;
Visible:=true;
TempEditor.Close;
TempEditor.Free;
if Notebook.PageCount>1 then begin
//writeln('TSourceNotebook.CloseFile B PageIndex=',PageIndex);
// if this is the current page, switch to left PageIndex
if (Notebook.PageIndex=PageIndex) and (PageIndex>0) then
Notebook.PageIndex:=PageIndex-1;
// delete the page
Notebook.Pages.Delete(PageIndex);
//writeln('TSourceNotebook.CloseFile C PageIndex=',PageIndex,' Notebook.PageCount=',Notebook.PageCount);
UpdateStatusBar;
end else begin
//writeln('TSourceNotebook.CloseFile D PageIndex=',PageIndex);
Notebook.Free;
//writeln('TSourceNotebook.CloseFile E PageIndex=',PageIndex);
Notebook:=nil;
Hide;
end;
{$IFDEF IDE_DEBUG}
writeln('TSourceNotebook.CloseFile END');
{$ENDIF}
end;
procedure TSourceNotebook.FocusEditor;
var
SrcEdit: TSourceEditor;
begin
if (NoteBook=nil) or (fAutoFocusLock>0) then exit;
SrcEdit:=GetActiveSE;
if SrcEdit=nil then exit;
Show;
SrcEdit.FocusEditor;
end;
Procedure TSourceNotebook.NewClicked(Sender: TObject);
Begin
if Assigned(FOnNewClicked) then FOnNewClicked(Sender);
End;
Procedure TSourceNotebook.OpenClicked(Sender: TObject);
Begin
if Assigned(FOnOpenClicked) then FOnOpenClicked(Sender);
end;
Procedure TSourceNotebook.SaveClicked(Sender: TObject);
Begin
if Assigned(FOnSaveClicked) then FOnSaveClicked(Sender);
end;
Function TSourceNotebook.ActiveFileName : AnsiString;
Begin
Result := GetActiveSE.FileName;
end;
function TSourceNotebook.GetEditors(Index:integer):TSourceEditor;
begin
Result:=TSourceEditor(FSourceEditorList[Index]);
end;
function TSourceNotebook.EditorCount:integer;
begin
Result:=FSourceEditorList.Count;
end;
Procedure TSourceNotebook.CloseClicked(Sender : TObject);
Begin
if Assigned(FOnCloseClicked) then FOnCloseClicked(Sender);
end;
Function TSourceNotebook.FindUniquePageName(FileName:string;
IgnorePageIndex:integer):string;
var I:integer;
ShortName:string;
function PageNameExists(const AName:string):boolean;
var a:integer;
begin
Result:=false;
if Notebook=nil then exit;
for a:=0 to Notebook.PageCount-1 do begin
if (a<>IgnorePageIndex)
and (AnsiCompareText(AName,FindSourceEditorWithPageIndex(a).PageName)=0)
then begin
Result:=true;
exit;
end;
end;
end;
begin
if FileName='' then begin
FileName:='unit1';
if not PageNameExists(FileName) then begin
Result:=Filename;
exit;
end;
end;
if FilenameIsPascalUnit(FileName) then
ShortName:=ExtractFileNameOnly(Filename)
else
ShortName:=ExtractFileName(FileName);
Result:=ShortName;
if PageNameExists(Result) then begin
i:=1;
repeat
inc(i);
Result:=ShortName+'('+IntToStr(i)+')';
until PageNameExists(Result)=false;
end;
end;
Procedure TSourceNotebook.SaveAsClicked(Sender : TObject);
Begin
if Assigned(FOnSaveAsClicked) then FOnSaveAsClicked(Sender);
end;
Procedure TSourceNotebook.SaveAllClicked(Sender : TObject);
Begin
if Assigned(FOnSaveAllClicked) then FOnSaveAllClicked(Sender);
end;
procedure TSourceNotebook.ToggleFormUnitClicked(Sender: TObject);
begin
if Assigned(FOnToggleFormUnitClicked) then FOnToggleFormUnitClicked(Sender);
end;
procedure TSourceNotebook.ToggleObjectInspClicked(Sender: TObject);
begin
if Assigned(FOnToggleObjectInspClicked) then FOnToggleObjectInspClicked(Sender);
end;
procedure TSourceNotebook.InitFindDialog;
var c: TFindDlgComponent;
begin
FindReplaceDlg.OnKey:=@FindReplaceDlgKey;
for c:=Low(TFindDlgComponent) to High(TFindDlgComponent) do
FindReplaceDlgHistoryIndex[c]:=-1;
end;
Procedure TSourceNotebook.UpdateStatusBar;
var
tempEditor : TSourceEditor;
begin
if not Visible then exit;
TempEditor := GetActiveSE;
if TempEditor = nil then Exit;
if (TempEditor.EditorComponent.CaretY<>TempEditor.ErrorLine)
or (TempEditor.EditorComponent.CaretX<>TempEditor.fErrorColumn) then
TempEditor.ErrorLine:=-1;
if snIncrementalFind in States then begin
Statusbar.SimplePanel:=true;
Statusbar.SimpleText:=Format(lisUESearching, [IncrementalSearchStr]);
end else begin
Statusbar.SimplePanel:=false;
Statusbar.Panels[3].Text := TempEditor.Filename;
If TempEditor.Modified then
StatusBar.Panels[1].Text := ueModified
else
StatusBar.Panels[1].Text := '';
If TempEditor.ReadOnly then
if StatusBar.Panels[1].Text <> '' then
StatusBar.Panels[1].Text := Format(lisUEReadOnly, [StatusBar.Panels[1
].Text])
else
StatusBar.Panels[1].Text := uepReadonly;
Statusbar.Panels[0].Text :=
Format(' %6d:%4d',[TempEditor.CurrentCursorYLine,TempEditor.CurrentCursorXLine]);
if GetActiveSE.InsertMode then
Statusbar.Panels[2].Text := uepIns
else
Statusbar.Panels[2].Text := uepOvr;
end;
End;
function TSourceNotebook.FindBookmark(BookmarkID: integer): TSourceEditor;
var i,x,y:integer;
begin
for i:=0 to EditorCount-1 do begin
if Editors[i].EditorComponent.GetBookmark(BookMarkID,x,y) then begin
Result:=Editors[i];
exit;
end;
end;
Result:=nil;
end;
function TSourceNotebook.FindPageWithEditor(
ASourceEditor: TSourceEditor):integer;
var i:integer;
begin
if Notebook=nil then begin
Result:=-1;
end else begin
Result:=Notebook.PageCount-1;
while (Result>=0) do begin
with Notebook.Page[Result] do
for I := 0 to ControlCount-1 do
if Controls[I]=ASourceEditor.EditorComponent then exit;
dec(Result);
end;
end;
end;
function TSourceNotebook.FindSourceEditorWithEditorComponent(
EditorComp: TComponent): TSourceEditor;
var i: integer;
begin
for i:=0 to EditorCount-1 do begin
Result:=Editors[i];
if Result.EditorComponent=EditorComp then exit;
end;
Result:=nil;
end;
function TSourceNotebook.FindSourceEditorWithFilename(const Filename: string
): TSourceEditor;
var i: integer;
begin
for i:=0 to EditorCount-1 do begin
Result:=Editors[i];
if CompareFilenames(Result.Filename,Filename)=0 then exit;
end;
Result:=nil;
end;
Procedure TSourceNotebook.NotebookPageChanged(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSE;
if TempEditor <> nil then
begin
if fAutoFocusLock=0 then begin
{$IFDEF VerboseFocus}
writeln('TSourceNotebook.NotebookPageChanged BEFORE SetFocus ',
TempEditor.EditorComponent.Name,' ',
NoteBook.Pages[FindPageWithEditor(TempEditor)]);
{$ENDIF}
TempEditor.FocusEditor;
{$IFDEF VerboseFocus}
writeln('TSourceNotebook.NotebookPageChanged AFTER SetFocus ',
TempEditor.EditorComponent.Name,' ',
NoteBook.Pages[FindPageWithEditor(TempEditor)]);
{$ENDIF}
end;
UpdateStatusBar;
UpdateActiveEditColors;
if Assigned(FOnEditorVisibleChanged) then
FOnEditorVisibleChanged(sender);
end;
end;
Procedure TSourceNotebook.ProcessParentCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer;
var Handled: boolean);
begin
FProcessingCommand:=true;
if Assigned(FOnProcessUserCommand) then begin
Handled:=false;
FOnProcessUserCommand(Self,Command,Handled);
if Handled or (Command=ecNone) then begin
FProcessingCommand:=false;
exit;
end;
end;
Handled:=true;
case Command of
ecNextEditor:
NextEditor;
ecPrevEditor :
PrevEditor;
ecMoveEditorLeft:
MoveActivePageLeft;
ecMoveEditorRight:
MoveActivePageRight;
ecOpenFileAtCursor:
OpenAtCursorClicked(self);
ecJumpToEditor:
Begin
// This is NOT implemented yet
end;
ecGotoEditor1..ecGotoEditor9,ecGotoEditor0:
if Notebook.PageCount>Command-ecGotoEditor1 then
Notebook.PageIndex:=Command-ecGotoEditor1;
ecToggleFormUnit:
ToggleFormUnitClicked(Self);
ecToggleObjectInsp:
ToggleObjectInspClicked(Self);
ecGotoMarker0..ecGotoMarker9:
BookMarkGoto(Command - ecGotoMarker0);
ecSetMarker0..ecSetMarker9:
BookMarkSet(Command - ecSetMarker0);
ecJumpBack:
HistoryJump(Self,jhaBack);
ecJumpForward:
HistoryJump(Self,jhaForward);
ecAddJumpPoint:
AddJumpPointClicked(Self);
ecViewJumpHistory:
ViewJumpHistoryClicked(Self);
else
Handled:=false;
end; //case
if Handled then Command:=ecNone;
FProcessingCommand:=false;
end;
Procedure TSourceNotebook.ParentCommandProcessed(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer;
var Handled: boolean);
begin
if Assigned(FOnUserCommandProcessed) then begin
Handled:=false;
FOnUserCommandProcessed(Self,Command,Handled);
if Handled then exit;
end;
Handled:=(Command=ecClose);
if Handled then Command:=ecNone;
end;
Procedure TSourceNotebook.ReloadEditorOptions;
var
I : integer;
h: TLazSyntaxHighlighter;
Begin
// this reloads the colors for the highlighter and other editor settings.
for h:=Low(TLazSyntaxHighlighter) to High(TLazSyntaxHighlighter) do
if Highlighters[h]<>nil then
EditorOpts.GetHighlighterSettings(Highlighters[h]);
for I := 0 to FSourceEditorList.Count-1 do
TSourceEditor(FSourceEditorList.Items[i]).RefreshEditorSettings;
// reload code templates
with CodeTemplateModul do begin
if FileExists(EditorOpts.CodeTemplateFilename) then
AutoCompleteList.LoadFromFile(EditorOpts.CodeTemplateFilename)
else
if FileExists('lazarus.dci') then
AutoCompleteList.LoadFromFile('lazarus.dci');
IndentToTokenStart:=EditorOpts.CodeTemplateIndentToTokenStart;
end;
EditorOpts.KeyMap.AssignTo(FKeyStrokes,[caSourceEditor]);
if NoteBook<>nil then begin
if EditorOpts.ShowTabCloseButtons then
NoteBook.Options:=NoteBook.Options+[nboShowCloseButtons]
else
NoteBook.Options:=NoteBook.Options-[nboShowCloseButtons];
end;
end;
procedure TSourceNotebook.KeyDown(var Key : Word; Shift : TShiftState);
var i, Command: integer;
Begin
inherited KeyDown(Key,Shift);
i := FKeyStrokes.FindKeycode(Key, Shift);
if i>=0 then begin
Command:=FKeyStrokes[i].Command;
case Command of
ecClose:
begin
CloseClicked(Self);
Key:=0;
end;
end;
end;
end;
procedure TSourceNotebook.BeginAutoFocusLock;
begin
inc(fAutoFocusLock);
end;
procedure TSourceNotebook.EndAutoFocusLock;
begin
dec(fAutoFocusLock);
end;
Procedure TSourceNotebook.EditorMouseMove(Sender : TObject; Shift: TShiftstate;
X,Y : Integer);
begin
// restart hint timer
FHintTimer.Enabled := False;
FHintTimer.Enabled := EditorOpts.AutoToolTipSymbTools and Visible;
end;
procedure TSourceNotebook.EditorMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftstate; X, Y: Integer);
begin
end;
Procedure TSourceNotebook.HintTimer(sender : TObject);
var
MousePos : TPoint;
AControl: TControl;
begin
FHintTimer.Enabled := False;
MousePos := Mouse.CursorPos;
AControl:=FindLCLControl(MousePos);
if (AControl=nil) or (GetParentForm(AControl)<>Self) then exit;
if AControl is TSynEdit then
ShowSynEditHint(MousePos);
end;
{------------------------------------------------------------------------------
procedure TSourceNotebook.OnApplicationUserInput(Sender: TObject;
Msg: Cardinal);
------------------------------------------------------------------------------}
procedure TSourceNotebook.OnApplicationUserInput(Sender: TObject; Msg: Cardinal
);
begin
HideHint;
end;
procedure TSourceNotebook.EditorMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftstate; X, Y: Integer);
begin
if GetKeyShiftState=[ssCtrl] then begin
// Control+MouseUp = Find Declaration
if Assigned(FOnCtrlMouseUp) then begin
FOnCtrlMouseUp(Sender,Button,Shift,X,Y);
end;
end;
end;
procedure TSourceNotebook.ShowSynEditHint(const MousePos: TPoint);
var
EditPos: TPoint;
ASrcEdit: TSourceEditor;
ASynEdit: TSynEdit;
EditCaret: TPoint;
LineMarks: TSynEditMarks;
AMark: TSourceMark;
i: integer;
HintStr: String;
CurHint: String;
begin
// hide other hints
Application.HideHint;
//
ASrcEdit:=GetActiveSE;
if ASrcEdit=nil then exit;
ASynEdit:=ASrcEdit.EditorComponent;
EditPos:=ASynEdit.ScreenToClient(MousePos);
if not PtInRect(ASynEdit.ClientRect,EditPos) then exit;
EditCaret:=ASynEdit.PixelsToRowColumn(EditPos);
if (EditCaret.Y<1) then exit;
if EditPos.X<ASynEdit.Gutter.Width then begin
// hint for a gutter item
if EditorOpts.ShowGutterHints then begin
ASynEdit.Marks.GetMarksForLine(EditCaret.Y,LineMarks);
HintStr:='';
for i:=Low(TSynEditMarks) to High(TSynEditMarks) do begin
AMark:=TSourceMark(LineMarks[i]);
if not (AMark is TSourceMark) then continue;
CurHint:=AMark.GetHint;
if CurHint='' then continue;
if HintStr<>'' then HintStr:=HintStr+EndOfLine;
HintStr:=HintStr+CurHint;
end;
if HintStr<>'' then
ActivateHint(MousePos,HintStr);
end;
end else begin
// hint for source
if Assigned(OnShowHintForSource) then
OnShowHintForSource(ASrcEdit,EditPos,EditCaret);
end;
end;
Procedure TSourceNotebook.AddWatchAtCursor(Sender : TObject);
begin
if Assigned(OnAddWatchAtCursor) then
OnAddWatchAtCursor(Self);
end;
procedure TSourceNotebook.SetIncrementalSearchStr(const AValue: string);
var
CurEdit: TSynEdit;
begin
if FIncrementalSearchStr=AValue then exit;
FIncrementalSearchStr:=AValue;
if snIncrementalFind in States then begin
// search string
CurEdit:=GetActiveSE.EditorComponent;
CurEdit.BeginUpdate;
CurEdit.CaretXY:=fIncrementalSearchStartPos;
if fIncrementalSearchStr<>'' then begin
CurEdit.SearchReplace(fIncrementalSearchStr,'',[]);
CurEdit.CaretXY:=CurEdit.BlockEnd;
FIncrementalSearchStr:=CurEdit.SelText;
end else begin
CurEdit.BlockBegin:=CurEdit.CaretXY;
CurEdit.BlockEnd:=CurEdit.CaretXY;
end;
CurEdit.EndUpdate;
end;
UpdateStatusBar;
end;
procedure TSourceNotebook.UpdateActiveEditColors;
var ASynEdit: TSynEdit;
SrcEDit: TSourceEditor;
begin
SrcEdit:=GetActiveSe;
if SrcEdit=nil then exit;
ASynEdit:=SrcEdit.EditorComponent;
if ASynEdit=nil then exit;
FActiveEditDefaultFGColor:=ASynEdit.Font.Color;
FActiveEditDefaultBGColor:=ASynEdit.Color;
FActiveEditSelectedFGColor:=ASynEdit.SelectedColor.ForeGround;
FActiveEditSelectedBGColor:=ASynEdit.SelectedColor.Background;
FActiveEditKeyFGColor:=FActiveEditDefaultFGColor;
FActiveEditKeyBGColor:=FActiveEditDefaultBGColor;
FActiveEditSymbolFGColor:=FActiveEditDefaultFGColor;
FActiveEditSymbolBGColor:=FActiveEditDefaultBGColor;
if ASynEdit.Highlighter<>nil then begin
with ASynEdit.Highlighter do begin
if IdentifierAttribute<>nil then begin
if IdentifierAttribute.ForeGround<>clNone then
FActiveEditDefaultFGColor:=IdentifierAttribute.ForeGround;
if IdentifierAttribute.BackGround<>clNone then
FActiveEditDefaultBGColor:=IdentifierAttribute.BackGround;
end;
if KeywordAttribute<>nil then begin
if KeywordAttribute.ForeGround<>clNone then
FActiveEditKeyFGColor:=KeywordAttribute.ForeGround;
if KeywordAttribute.BackGround<>clNone then
FActiveEditKeyBGColor:=KeywordAttribute.BackGround;
end;
if SymbolAttribute<>nil then begin
if SymbolAttribute.ForeGround<>clNone then
FActiveEditSymbolFGColor:=SymbolAttribute.ForeGround;
if SymbolAttribute.BackGround<>clNone then
FActiveEditSymbolBGColor:=SymbolAttribute.BackGround;
end;
end;
end;
end;
Procedure TSourceNotebook.GetSynEditPreviewSettings(APreviewEditor: TObject);
var ASynEdit: TSynEdit;
begin
if not (APreviewEditor is TSynEdit) then exit;
ASynEdit:=TSynEdit(APreviewEditor);
EditorOpts.GetSynEditPreviewSettings(ASynEdit);
ASynEdit.Highlighter:=Highlighters[lshFreePascal];
end;
procedure TSourceNotebook.ClearErrorLines;
var i: integer;
begin
for i:=0 to EditorCount-1 do
Editors[i].ErrorLine:=-1;
end;
procedure TSourceNotebook.ClearExecutionLines;
var i: integer;
begin
for i:=0 to EditorCount-1 do
Editors[i].ExecutionLine:=-1;
end;
{ GOTO DIALOG }
Constructor TfrmGoto.Create(AOWner : TComponent);
begin
inherited Create(AOwner);
if LazarusResources.Find(ClassName)=nil then begin
Position := poScreenCenter;
Width := 250;
Height := 100;
Caption := lisMenuGotoLine;
BorderStyle:= bsDialog;
Label1 := TLabel.Create(self);
with Label1 do
Begin
Parent := self;
Top := 10;
Left := 5;
Caption := lisUEGotoLine;
Visible := True;
end;
Edit1 := TEdit.Create(self);
with Edit1 do
Begin
Parent := self;
Top := 30;
Width := self.width-40;
Left := 5;
Caption := '';
OnKeyDown:=@Edit1KeyDown;
Visible := True;
end;
btnOK := TBitbtn.Create(self);
with btnOK do
Begin
Name:='btnOK';
Parent := self;
Top := 70;
Left := 40;
kind := bkOK;
Default:=false;
Visible := True;
end;
btnCancel := TBitbtn.Create(self);
with btnCancel do
Begin
Name:='btnCancel';
Parent := self;
Top := 70;
Left := 120;
kind := bkCancel;
Default:=false;
Visible := True;
end;
end;
ActiveControl:=Edit1;
end;
procedure TfrmGoto.Edit1KeyDown(Sender: TObject; var Key:Word;
Shift:TShiftState);
begin
if (Key=VK_RETURN) then ModalResult:=mrOk;
if (Key=VK_ESCAPE) then ModalResult:=mrCancel;
end;
{ TSynEditPlugin1 }
constructor TSynEditPlugin1.Create(AOwner: TCustomSynEdit);
Begin
inherited;
end;
procedure TSynEditPlugin1.AfterPaint(ACanvas: TCanvas; AClip: TRect; FirstLine,
LastLine: integer);
begin
//don't do anything
end;
procedure TSynEditPlugin1.LinesDeleted(FirstLine, Count: integer);
begin
if Assigned(OnLinesDeleted) then
OnLinesDeleted(self,Firstline,Count);
end;
procedure TSynEditPlugin1.LinesInserted(FirstLine, Count: integer);
begin
if Assigned(OnLinesInserted) then
OnLinesInserted(self,Firstline,Count);
end;
//-----------------------------------------------------------------------------
procedure InternalInit;
var h: TLazSyntaxHighlighter;
begin
for h:=Low(TLazSyntaxHighlighter) to High(TLazSyntaxHighlighter) do
Highlighters[h]:=nil;
aCompletion:=nil;
CurCompletionControl:=nil;
GotoDialog:=nil;
IdentCompletionTimer:=nil;
AWordCompletion:=nil;
end;
procedure InternalFinal;
var h: TLazSyntaxHighlighter;
begin
for h:=Low(TLazSyntaxHighlighter) to High(TLazSyntaxHighlighter) do
FreeThenNil(Highlighters[h]);
FreeThenNil(aWordCompletion);
end;
initialization
InternalInit;
{$I images/bookmark.lrs}
finalization
InternalFinal;
end.