unit TextEditor;
interface
uses
Windows, SysUtils, Classes, Types, Controls, Graphics, Messages, Menus,
ExtCtrls, RichEdit, CommCtrl, Forms, BitmapEffects, TextEncodings,
UnicodeData, ActiveX, System.Win.ComObj, ShlObj, Generics.Defaults,
Generics.Collections, UITypes, Math;
resourcestring
SNumOnlyErrorTitle = 'Character not allowed';
SNumOnlyErrorText = 'You can only type a number here.';
SControlLineInputTitle = 'Text input not allowed';
SControlLineInputText = 'You cannot enter text on a control line.';
SPicture = 'Picture';
SImageFilter = 'All images|*.bmp; *.jpg; *.jpeg; *.jpe; *.png; *.gif; *.ico|Bitmap images|*.bmp|JPEG images|*.jpg; *.jpeg; *.jpe|PNG images|*.png|GIF images|*.gif|Icons|*.ico';
SOpenImageDialogCaption = 'Select image';
SControl = 'Control';
SRemovedControl = 'Removed control';
SCliHistoryDialogCaption = 'Command History';
SMultiSelectCaption = 'Character Selection';
SMultiCharDlgLvColumnTitleDescription = 'Description';
SMultiCharDlgLvColumnTitleCodepoint = 'Codepoint';
SMultiCharDlgLvColumnTitleBlock = 'Block';
SNewFileName = 'New file %d';
SMenuOpenURL = 'Open URL';
SMenuOpenURLHint = 'Opens %s.';
SMenuUndo = 'Undo';
SMenuUndoHint = 'Undoes the previous operation in the undo list.';
SMenuRedo = 'Redo';
SMenuRedoHint = 'Redoes the next operation in the undo list.';
SMenuCut = 'Cut';
SMenuCutHint = 'Moves the selected text to the clipboard.';
SMenuCopy = 'Copy';
SMenuCopyHint = 'Copies the selected text to the clipboard.';
SMenuPaste = 'Paste';
SMenuPasteHint = 'Pastes the contents of the clipboard at the caret, replacing any selection.';
SMenuClear = 'Clear';
SMenuClearHint = 'Removes the selected text.';
SMenuSelectAll = 'Select all';
SMenuSelectAllHint = 'Selects all text.';
SMenuSetBookmark = 'Set bookmark';
SMenuSetBookmarkItemHint = 'Sets this bookmark to the current caret position.';
SMenuGotoBookmark = 'Goto bookmark';
SMenuGotoBookmarkItemHint = 'Moves the caret to this bookmark.';
SMenuClearBookmark = 'Clear bookmark';
SMenuClearBookmarkItemHint = 'Clears (removes) this bookmark.';
SMenuClasses = 'Classes';
SMenuClassesItemHint = 'Assigns this class to the current line.';
SMenuActivateControl = 'Activate control';
SMenuActivateControlHint = 'Activates this control.';
SMenuTransform = 'Transform';
SMenuTransformUpperCase = 'To upper case';
SMenuTransformUpperCaseHint = 'Converts the selected text to upper case.';
SMenuTransformLowerCase = 'To lower case';
SMenuTransformLowerCaseHint = 'Converts the selected text to lower case.';
SMenuTransformInvertCase = 'Invert case';
SMenuTransformInvertCaseHint = 'Inverts the case of the characters in the selection.';
SMenuTransformCamelCase = 'To camel case';
SMenuTransformCamelCaseHint = 'Enforces camel case (Camel Case) in the selection.';
SMenuTransformSentenceCase = 'To sentence case';
SMenuTransformSentenceCaseHint = 'Enforces sentence case in the selection.';
SMenuTransformReverse = 'Reverse text';
SMenuTransformReverseHint = 'Reverses the selected text.';
SMenuTransformROT13 = 'Perform ROT-13';
SMenuTransformROT13Hint = 'Performs ROT-13 on the selected text.';
SMenuTransformCaesar = 'Apply Caesar cipher...';
SMenuTransformCaesarHint = 'Performs the Caesar cipher on the selected text.';
SMenuTransformVigenere = 'Apply Vigenère cipher...';
SMenuTransformVigenereHint = 'Performs the Vigenère cipher on the selected text.';
SMenuTransformVigenereInverse = 'Apply inverse Vigenère cipher...';
SMenuTransformVigenereInverseHint = 'Performs the inverse Vigenère cipher on the selected text.';
SCaesarNTitle = 'Caesar Cipher';
SCaesarNText = 'Please enter the parameter of the Caesar cipher:';
SVigenereTitle = 'Vigenère Cipher';
SVigenereText = 'Please enter the parameter of the Vigenère cipher:';
SMenuNoBookmarksSetParen = '(No bookmarks set.)';
SMenuClearAllBookmarks = 'Clear all';
SMenuClearAllBookmarksHint = 'Clears all bookmarks.';
SMenuUseNoClass = 'No class';
SMenuUseNoClassHint = 'Assigns no class to the current line.';
SBookmarkDescriptionInvalid = 'Invalid bookmark';
SBookmarkDescription = 'Bookmark %d (%d, %d)';
SBookmarkDescriptionEmpty = 'Bookmark %d (empty)';
SMenuCopyImage = 'Copy image';
SMenuCopyImageHint = 'Copies the image to the clipboard.';
SMenuDeleteImage = 'Remove image';
SMenuDeleteImageHint = 'Removes the image.';
SMenuChangeImage = 'Change image...';
SMenuChangeImageHint = 'Replaces the image with a different one.';
SMenuRulerProperties = 'Properties';
SMenuRulerPropertiesHint = 'Displays or modifies the ruler properties.';
SMoveHere = 'Move here';
SCopyHere = 'Copy here';
SCancel = 'Cancel';
SFPSlowTitle = 'Text Editor Control';
SFPSlowText = 'The formatting processor used for interactive formatting (syntax highlighting) appears to be slow. Do you want to disable interactive formatting?';
SRestoreWrapAtText = 'Do you want to restore the default wrap at characters?';
SRestoreWrapAtCaption = 'TTextEditor control';
SNotifyDragMove = 'Drag to move the selection to the new position. (Press Esc to abort.)';
SNotifyDragCopy = 'Drag to copy the selection to the new position. (Press Esc to abort.)';
SNotifyReadOnlyError = 'You cannot edit a read-only line.';
SNotifyInputError = 'Invalid operation.';
SNotifyPrinting = 'Printing...';
SNotifyScrollMode = 'Scroll mode';
SNotifyScript = 'Script running... (Press Esc to abort.)';
SNotifyMultiCharSelect = 'Press F9 to show a list of related characters.';
SNotifyReadOnlyMode = 'Read-only mode';
SNotifyMultiCaretMode = 'Multi-caret mode. (Press Esc to abort.)';
SReadOnlyErrorText = 'You cannot edit a read-only line.';
SReadOnlyErrorTitle = 'Read only';
SUndoSelectionTransformed = 'Selection transformed (%s)';
SUndoTextTransformed = 'Text transformed (%s)';
SUndoLineCleared = 'Line cleared';
SUndoSelectionCleared = 'Selection cleared';
SUndoFirstPost = 'First version since undo history was removed';
SUndoTyped = 'Typed';
SUndoInitialText = 'Initial text';
SUndoCutToClipboard = 'Cut to clipboard';
SUndoTrimRight = 'Lines trimmed to the right';
SUndoTextCleared = 'Document cleared';
SUndoBookmarksCleared = 'Bookmarks cleared';
SUndoWordWrap = 'Word wrap performed';
SUndoTextInserted = 'Text inserted';
SUndoTextSurrounded = 'Selection surrounded by "%s" and "%s"';
SUndoReplacedAll = 'Replaced %d instance(s) of "%s" by "%s"';
SUndoUnicodeReplacedCodepoint = 'Unicode codepoint replaced by character';
SUndoLinesSwapped = 'Lines swapped';
SUndoMouseMove = 'Selection moved using mouse';
SUndoMouseCopy = 'Selection copied using mouse';
SUndoMouseMoveExtSrc = 'External text moved here using mouse';
SUndoMouseCopyExtSrc = 'External text copied here using mouse';
SUndoMouseMoveExtDst = 'Selection moved to external document';
SUndoNewFile = 'Document created';
SUndoBookmarkCleared = 'Bookmark cleared';
SUndoBookmarkAdded = 'Bookmark added';
SUndoIndentIncreased = 'Indent increased';
SUndoDocumentLoaded = 'Document loaded';
SUndoPastedFromClipboard = 'Pasted from clipboard';
SUndoIndentRemoved = 'Indent removed';
SUndoIndentDecreased = 'Indent decreased';
SUndoReverted = 'Reverted to version #%d from %s';
SUndoSorted = 'Sorted lines';
SUndoMadeLinesUnique = 'Removed duplicates, made lines unique';
SUndoScript = 'Script executed';
SUndoScriptAbort = 'Script partially executed before being aborted';
SUndoCliHistory = 'Command-line history item recalled';
SUndoFillWithChar = 'Filled selection with character %s';
SUndoLinesTruncated = 'Lines truncated';
SUndoLinesFiltered = 'Lines filtered';
SUndoAutoReplaced = 'Auto-replaced code';
SDefaultPrintJobTitle = 'Text file';
SDefaultFileName = 'Untitled file';
STransformNameUpperCase = 'upper case';
STransformNameLowerCase = 'lower case';
STransformNameInvertCase = 'invert case';
STransformNameCamelCase = 'camel case';
STransformNameSentenceCase = 'sentence case';
STransformNameReverse = 'reverse text';
STransformNameRot13 = 'ROT-13';
STransformNameCaesarN = 'Caesar %d';
STransformNameVigenere = 'Vigenère';
SNoInteractiveFormattingParen = '(No interactive formatting)';
SHTMLExportFileName = 'File name';
SHTMLExportDate = 'Date exported';
SHTMLExportTime = 'Time exported';
SHTMLExportFP = 'Formatting processor';
SInvalidOpMsgSingleLineModeInsertLine = 'Cannot insert line in single-line mode.';
SInvalidOpMsgInvalidChrIndex = 'TTextFile: Invalid character index %d.';
SNoLineComparer = 'Cannot sort because no line comparison function has been assigned.';
SIllegalLineComparer = 'Illegal line-comparing function assigned.';
const
FORMATETC_UNICODETEXT: TFormatEtc =
(
cfFormat: CF_UNICODETEXT;
ptd: nil;
dwAspect: DVASPECT_CONTENT;
lindex: -1;
tymed: TYMED_HGLOBAL
);
type
TChangeType = (ctNone, ctFile, ctLineRange, ctBlock, ctLine, ctLineFrom,
ctChar, ctTwoChars, ctPostFile);
TChangeRecord = record
ChangeType: TChangeType;
Data1, Data2, Data3, Data4: integer;
end;
TChangeRecords = array of TChangeRecord;
function MakeChangeRecord(ChangeType: TChangeType; Data1, Data2, Data3, Data4: integer): TChangeRecord;
const
NO_CHANGE_RECORD: TChangeRecord = (ChangeType: ctNone; Data1: 0; Data2: 0; Data3: 0; Data4: 0);
FILE_CHANGE_RECORD: TChangeRecord = (ChangeType: ctFile; Data1: 0; Data2: 0; Data3: 0; Data4: 0);
type
TChangeEvent = procedure(Sender: TObject; ChangeType: TChangeType; Data1,
Data2, Data3, Data4: integer) of object;
function ChangeUnion(const ChangeRecord1, ChangeRecord2: TChangeRecord): TChangeRecord;
type
TSelectionType = (stLineBased, stBlock);
TCaretPos = class
private
FCaretPos: TPoint;
FSelStartPos: TPoint;
FSelectionType: TSelectionType;
FOnChange: TNotifyEvent;
FOnSelChange: TChangeEvent;
FSavedSelExtent: TChangeRecord;
procedure SetCaretPos(const Value: TPoint);
procedure Changed;
procedure SelChanged(ChangeType: TChangeType; Data1, Data2, Data3, Data4: integer);
procedure SelRemoved;
procedure SetSelEndPos(const Value: TPoint);
procedure SetSelectionType(const Value: TSelectionType);
function GetSelExtent(ACaretPos, ASelEndPos: TPoint; ASelectionType: TSelectionType): TChangeRecord;
procedure SaveSelExtent; inline;
function GetFirstPoint: TPoint;
function GetLastPoint: TPoint;
public
constructor Create;
procedure Reset;
property Data: TPoint read FCaretPos;
property SelEnd: TPoint read FSelStartPos;
property FirstPoint: TPoint read GetFirstPoint;
property LastPoint: TPoint read GetLastPoint;
property X: Integer read FCaretPos.X;
property Y: Integer read FCaretPos.Y;
procedure SetPoint(X, Y: integer; SelEnd: boolean = false); overload;
procedure SetPoint(Point: TPoint; SelEnd: boolean = false); overload; inline;
procedure SetX(X: integer; SelEnd: boolean = false);
procedure SetY(Y: integer; SelEnd: boolean = false);
procedure CreateSelection(const ASelStart, ASelEnd: TPoint;
const ASelectionType: TSelectionType = stLineBased);
procedure RemoveSelection;
property SelectionType: TSelectionType read FSelectionType write SetSelectionType default stLineBased;
procedure GetSelBdry(const PointA, PointB: TPoint; out FirstPoint, SecondPoint: TPoint); overload;
procedure GetSelBdry(out FirstPoint, SecondPoint: TPoint); overload;
procedure InternalPush(Size: integer; LastLine: boolean = true);
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnSelChange: TChangeEvent read FOnSelChange write FOnSelChange;
end;
TEditMode = (emText, emConsole, emReadOnly);
EReadOnlyViolation = class(Exception);
TAutoReplaceItem = record
Token,
ReplacedValue: string;
end;
TAutoReplaceItems = array of TAutoReplaceItem;
const
NUM_BOOKMARKS = 17;
INTERNAL_BOOKMARK = -1;
type
TBookmarkList = array[-1..NUM_BOOKMARKS - 1] of TPoint;
const
EMPTY_BOOKMARK: TPoint = (X: -1; Y: -1);
type
TUndoDataItem = record
Text: string;
Classes: string;
CaretPos: TPoint;
SelStartPos: TPoint;
SelType: TSelectionType;
Time: TDateTime;
Comment: string;
UID: integer;
Bookmarks: TBookmarkList;
end;
TUndoData = array of TUndoDataItem;
THistoryManager = class
public const
UNDO_SIGNATURE = $4F444E55;
UNDO_SIGNATURE_ITEM = $4D455449;
strict private const
DEFAULT_MAX_UNDO_SIZE = 536870912;
HISTORY_ALLOC_BY = 1024;
strict private
FUndoData: TUndoData;
FMaxSize: integer;
FActualLength: integer;
FSize: integer;
FFirstItem: integer;
FHistoryIndex: integer;
function GetLength: integer;
function SizeOfItem(ItemIndex: integer): integer;
procedure SetMaxSize(Value: integer);
procedure ClearItem(ItemIndex: integer);
function RemoveFirstItem: boolean;
procedure TrimLeft;
function GetUndoData(Index: integer): TUndoDataItem;
function GetLastItem: integer;
procedure Revert;
public
constructor Create;
destructor Destroy; override;
procedure Add(AUndoDataItem: TUndoDataItem); overload;
procedure Add(const AText: string; const AClasses: string;
const ACaretPos, ASelStartPos: TPoint; ASelType: TSelectionType;
const ATime: TDateTime; const AComment: string;
const ABookmarks: TBookmarkList; AUID: integer = 0); overload;
procedure Clear;
function Undo(out UndoData: TUndoDataItem): boolean;
function CanUndo: boolean;
function Redo(out UndoData: TUndoDataItem): boolean;
function CanRedo: boolean;
function GotoVersion(Index: integer; out UndoData: TUndoDataItem): boolean;
procedure CreateDataStream(out Data: pointer; out Len: UInt64);
procedure SaveToStream(AStream: TStream);
procedure LoadFromStream(AStream: TStream);
procedure LoadFromBuffer(const Data: pointer; const Len: UInt64);
property UndoData[Index: integer]: TUndoDataItem read GetUndoData;
property Sizes[Index: integer]: integer read SizeOfItem;
property Count: integer read GetLength;
property Size: integer read FSize;
property FirstItem: integer read FFirstItem;
property LastItem: integer read GetLastItem;
property HistoryIndex: integer read FHistoryIndex;
property MaxSize: integer read FMaxSize write SetMaxSize default DEFAULT_MAX_UNDO_SIZE;
end;
TFindQuery = record
SearchString: string;
MatchCase: boolean;
MatchWord: boolean;
Linebreak: boolean;
UCBlock: integer;
end;
const
FQ_NULL = 0;
FQ_NONASCII = -1;
FQ_CONTROL = -2;
FQ_NONCHAR = -3;
FQ_MIN = -3;
function MakeFindQuery(const ASearchString: string; AMatchCase, AMatchWord, ALinebreak: boolean): TFindQuery; overload;
function MakeFindQuery(UCBlock: integer): TFindQuery; overload;
type
TTextSpan = record
A, B: TPoint;
end;
TFindData = array of TTextSpan;
TFileStatisticsFlags = set of (fsfCharTypes, fsfLines, fsfWords, fsSourceCode,
fsCaseSensitive);
const
FILE_STAT_ALL = [fsfCharTypes, fsfLines, fsfWords];
FILE_STAT_CHARS = [fsfCharTypes];
FILE_STAT_LINES = [fsfLines];
FILE_STAT_WORDS = [fsfWords];
const
LINE_CONTROL_CLASS = #$FFFF ;
LINE_CONTROL_PREFIX = #$FFFC#$FFFF ;
LINE_CLASS_INDICATOR = #$FFFE ;
type
TFileStatistics = record
Flags: TFileStatisticsFlags;
NumLines: integer;
NumChars: integer;
NumLetters: integer;
NumDigits: integer;
NumWhitespace: integer;
NumPunctuation: integer;
MaxLineLength: integer;
AvgLineLength: real;
LineLengthDistr: array of integer;
NumWords: integer;
MaxWordLength: integer;
AvgWordLength: real;
WordLengthDistr: array of integer;
procedure Clear;
end;
TCharTestFunction = function(C: char): boolean;
TLineChangeType = (lctAll, lctAppend, lctChangeFrom);
TLineChangeEvent = procedure(Sender: TObject; ChangeType: TLineChangeType; From: integer) of object;
TControlEvent = procedure(Sender: TObject; ControlID: integer) of object;
TLineEvent = procedure(Sender: TObject; LineIndex: integer) of object;
TGetControlTextEvent = procedure(Sender: TObject; LineIndex: integer; var ControlText: string) of object;
TChrTransformFunc = reference to function(C: char): char;
TTextTransformFunc = reference to function(const AText: string): string;
function ChrUpperCase(C: char): char;
function ChrLowerCase(C: char): char;
function ChrInvertCase(C: char): char;
function ChrROT13(C: char): char;
function ChrCaesar(N: integer): TChrTransformFunc;
function TxtVigenère(const Key: string; decode: boolean = false): TTextTransformFunc;
function TxtCamelCase(const AText: string): string;
function TxtSentenceCase(const AText: string): string;
function ReverseText(const AText: string): string;
const
UNICODE_RETURN_SYMBOL = #$23CE;
UNICODE_RETURN_SYMBOL_ALTERNATIVE = #$21B5;
const
DEFAULT_WRAP_AT = #$9#$20#$1680#$2000#$2001#$2002#$2003#$2004#$2005#$2006 +
#$2008#$2009#$200A#$205F#$3000#$180E#$200B#$200C#$200D#$002D#$00AD#$2010 +
#$2013#$2014';:@?=>)]}';
type
TEditorState = class
private var
FValid: boolean;
FFormattingProcessorClassName: string;
FScrollPos: TPoint;
FMultiSize: boolean;
FOverwrite: boolean;
FHiddenChrs: boolean;
FRulerVisible: boolean;
FZoomLevel: integer;
FFPCache: PByte;
FFPCacheLen: integer;
public
constructor Create;
destructor Destroy; override;
property Valid: boolean read FValid write FValid;
property FormattingProcessor: string read FFormattingProcessorClassName
write FFormattingProcessorClassName;
property ScrollPos: TPoint read FScrollPos write FScrollPos;
property MultiSize: boolean read FMultiSize write FMultiSize;
property Overwrite: boolean read FOverwrite write FOverwrite;
property HiddenChrs: boolean read FHiddenChrs write FHiddenChrs;
property RulerVisible: boolean read FRulerVisible write FRulerVisible;
property ZoomLevel: integer read FZoomLevel write FZoomLevel;
property FPCache: PByte read FFPCache write FFPCache;
property FPCacheLen: integer read FFPCacheLen write FFPCacheLen;
end;
TLineComparer = function(const LineA, LineB: string): integer;
PFilterOptions = ^TFilterOptions;
TFilterOptions = record
RemoveMatchingLines: boolean;
Contains,
StartsWith,
EndsWith: string;
MatchCase: boolean;
end;
TPointArray = array of TPoint;
TWordFreqItem = class
Count: Int64;
InNaturalCase: string;
IsLower: boolean;
constructor Create(AInNaturalCase: string; AIsLower: Boolean = False;
ACount: Int64 = 1);
end;
TWordFreqDict = TObjectDictionary<string, TWordFreqItem>;
TTextFile = class
private var
FFindData: TFindData;
strict private const
TEXTFILE_SIGNATURE: cardinal = $53455452;
TEXTFILE_SIGNATURE_FPCACHE: cardinal = $41435046;
TEXTFILE_SIGNATURE_UNDO: cardinal = $4F444E55;
strict private type
TFixedString = record
strict private const
MAXLEN = 1024;
public
Data: array[0..MAXLEN] of char;
class operator Implicit(const S: string): TFixedString;
class operator Implicit(const S: TFixedString): string;
end;
TStreamHeader = record
Signature: cardinal;
CaretPos,
SelEndPos: TPoint;
SelectionType: TSelectionType;
EditMode: TEditMode;
Modified: boolean;
FileName: TFixedString;
LineCount: integer;
Bookmarks: TBookmarkList;
ScrollPos: TPoint;
MultiSize,
Overwrite,
HiddenChars,
RulerVisible: boolean;
ZoomLevel: integer;
Encoding: TTextFileFormatInfo;
RecentlyOpened: boolean;
StrictReadOnly: boolean;
UseLineClasses: boolean;
FPClassName: TFixedString;
end;
strict private var
FLines: array of string;
FClasses: array of string;
FCaretPos: TCaretPos;
FOnCaretPosChange: TNotifyEvent;
FOnCaretPosSelChange: TChangeEvent;
FOnChange: TChangeEvent;
FCaretAfterEOL: boolean;
FOnInputError: TNotifyEvent;
FOnReadOnlyError: TNotifyEvent;
FAutoIndent: boolean;
FIndentSize: integer;
FEditMode: TEditMode;
FModified: boolean;
FFileName: TFileName;
FOnModified: TNotifyEvent;
FAutoReplaceItems: TAutoReplaceItems;
FHistoryManager: THistoryManager;
FFindDataActualLength: integer;
FOnFindDataClear: TNotifyEvent;
FFindResultValid: boolean;
FFindQuery: TFindQuery;
FSingleLine: boolean;
FOnLineChange: TLineChangeEvent;
FOnControlRemoved: TControlEvent;
FOnLineClassChange: TLineEvent;
FControlAware: boolean;
FOnGetControlText: TGetControlTextEvent;
FBookmarks: TBookmarkList;
FOnBookmarksMoved: TNotifyEvent;
FWrapAt: string;
FEditorState: TEditorState;
FLineComparer: TLineComparer;
FSortReverseOrder: boolean;
FDesiredCol: integer;
FPreserveDesiredCol: boolean;
FMultiAddLineMode: boolean;
FEncoding: TTextFileFormatInfo;
FRecentlyOpened: boolean;
FOnLockVisualUpdates,
FOnUnlockVisualUpdates: TNotifyEvent;
FStrictReadOnly: boolean;
FUseLineClasses: boolean;
function GetLine(Index: Integer): string;
procedure SetLine(Index: Integer; const Value: string);
function GetClass(Index: Integer): string;
procedure SetClass(Index: Integer; const Value: string);
function GetLineCount: integer; inline;
function GetPhysicalLineWidth(Index: Integer): integer; inline;
function GetVirtualLineWidth(Index: Integer): integer; inline;
function GetMaxLineWidth: integer;
function GetChar(Y, X: Integer): char; overload;
function GetChar(APoint: TPoint): char; overload; inline;
procedure CaretPosChange(Sender: TObject);
procedure CaretPosSelChange(Sender: TObject; ChangeType: TChangeType; Data1,
Data2, Data3, Data4: integer);
procedure Changed(ChangeType: TChangeType; Data1: integer = 0; Data2: integer = 0;
Data3: integer = 0; Data4: integer = 0);
procedure PostFileChanged(const NumLines: integer);
procedure InternalAddLine(const ALine: string; const AClassName: string);
procedure InternalAddLines(const NumLines: integer);
procedure InternalInsertLine(const LineIndex: integer; const ALine: string; const AClassName: string);
procedure InternalInsertLines(const LineIndex: integer; const NumLines: integer);
procedure InternalDeleteLine(const LineIndex: integer); inline;
procedure InternalDeleteLines(const LineIndex: integer; const NumLines: integer);
procedure IssueInputError;
function GetIndentOnReturn(out Len: integer): string; overload;
function TextIsMultiline(const AText: string): boolean;
function GetFirstLine(const AText: string): string;
function GetVirtualSpace: string; overload;
function GetVirtualSpace(LineIndex, Col: integer): string; overload;
function GetText: string;
function GetClassesAsText: string;
procedure SetText(const Value: string); overload;
procedure SetText(const Value, Classes: string); overload;
function GetNumCharacters: integer;
function GetVirtualTextLength: integer;
function GetPhysicalTextLength: integer;
function GetClassLength: integer;
function GetSelText: string;
procedure InternalZero;
function GetSelLength: integer;
procedure SetSelLength(const Value: integer);
procedure IssueReadOnlyError;
procedure Modified;
function PrevChar(const APoint: TPoint): TPoint;
function NextChar(const APoint: TPoint): TPoint;
procedure LoadAutoReplaceItems;
function GetSelStart: integer;
procedure SetSelStart(const Value: integer);
procedure InternalClearFindData;
procedure ClearFindData;
procedure AddFindData(const A, B: TPoint); overload; inline;
procedure AddFindData(const A: TPoint); overload; inline;
procedure EndAddFindData;
function GetFindData(Index: integer): TTextSpan;
function GetFindCount: integer;
procedure ReplaceInLineDiffWidth(const ReplaceText: string);
procedure ReplaceInLineSameWidth(const ReplaceText: string);
procedure ReplaceMultilineDiffWidth(const ReplaceText: string);
procedure ReplaceMultilineSameWidth(const ReplaceText: string);
function CompareFindQuery(const AFindQuery: TFindQuery): boolean;
function HasQueryResult(const AFindQuery: TFindQuery): boolean;
function GetSingleLineText: string;
procedure SetSingleLine(const Value: boolean);
procedure SetCaretAfterEOL(const Value: boolean);
procedure LineArrayChanged;
function IsControlLine: boolean; overload; inline;
function IsControlLine(LineIndex: integer): boolean; overload; inline;
procedure LineClassChanged(LineIndex: integer);
function GetCurrentClass: string;
function GetControlText(LineIndex: integer): string;
function GetDecoratedControlText(LineIndex: integer): string; inline;
function GetEmptyBookmarkIndex: integer;
function GetBookmark(Index: Integer): TPoint;
function GetBookmarkCount: integer;
function GetUsedBookmarkCount: integer;
function GetHasBookmarks: boolean;
function PushBookmarks(LineIndex, ColIndex: integer; NumChars: integer = 1): boolean;
function PushMultiCarets(var ACarets: TPointArray; LineIndex, ColIndex: integer; NumChars: integer = 1): boolean;
function PushBookmarksInternal(LineIndex: integer; NumChars: integer = 1): boolean;
function PushBookmarksEx(FirstLine, LastLine: integer; NumChars: integer = 1): boolean;
function QushBookmarks(LineIndex, ColIndex: integer): boolean;
function QushBookmarksEx(SelectionType: TSelectionType;
const FirstPoint, SecondPoint: TPoint): boolean;
function RushBookmarks(const FirstPoint: TPoint): boolean;
function RushBookmarksInternal(const FirstPoint: TPoint): boolean;
function RushBookmarksEx(const FirstPoint, SecondPoint: TPoint): boolean;
function SushBookmarks(FirstLine, SecondLine: integer; Silent: boolean = false): boolean;
function TushBookmarks(Line: integer; NumLines: integer = 1): boolean;
function TushBookmarksInternal(Line: integer; NumLines: integer = 1): boolean;
function DeleteBookmarksOnLine(Line: integer): boolean;
procedure BookmarksMoved;
procedure InternalSwapLines(FirstLine, SecondLine: integer;
BookmarkAware: boolean = true);
procedure SortRecursive(AFirstLine, ALastLine: integer; BookmarkAware: boolean = true);
procedure SetChar(Y, X: Integer; const Value: char);
procedure IntersectFindDataWithSelection;
procedure ApplyUndoRecord(const UndoData: TUndoDataItem);
procedure LockVisualUpdates;
procedure UnlockVisualUpdates;
function LineMatches(LineIndex: integer;
const ACriteria: TFilterOptions): boolean;
function GetAutoReplaceItem(Index: integer): TAutoReplaceItem;
function GetAutoReplaceItemCount: integer;
procedure SanitizeSelection;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
function GetIndexOfPoint(const APoint: TPoint): integer;
function GetPhysicalIndexOfPoint(const APoint: TPoint): integer;
function GetPhysicalPhysicalIndexOfPoint(const APoint: TPoint): integer;
function GetPointOfIndex(const Index: integer): TPoint;
function CharacterExists(Y, X: integer): boolean; overload; inline;
function CharacterExists(APoint: TPoint): boolean; overload; inline;
function CharacterExistsEx(Y, X: integer): boolean; overload; inline;
function CharacterExistsEx(APoint: TPoint): boolean; overload; inline;
function ValidCaretPos(APoint: TPoint): boolean; inline;
function AtEOL: boolean; inline;
function AtOrBeyondEOL: boolean; inline;
function BeyondEOL: boolean; inline;
function AtEOF: boolean; inline;
function AtOrBeyondEOF: boolean; inline;
function AtLastLine: boolean; inline;
function AtSOF: boolean; inline;
function CurrentLine: string;
function LineToRight: string;
function LineToLeft: string;
procedure GotoSOF(Selection: boolean = false);
procedure GotoEOF(Selection: boolean = false);
procedure GotoBottomRight(Selection: boolean = false);
procedure AddLine(const ALine: string; const AClassName: string); overload;
procedure AddLine(const ALine: string); overload;
procedure BeginAddLine;
procedure EndAddLine;
procedure InsertLine(const ALine: string; const AClassName: string; LineIndex: integer); overload;
procedure InsertLine(const ALine: string; LineIndex: integer); overload;
procedure InsertChar(const AChar: char; const Overwrite: boolean = false);
procedure MultiInsertChar(var ACarets: TPointArray; const AChar: char; const Overwrite: boolean = false);
procedure Backspace(Word: boolean = false);
procedure MultiBackspace(var ACarets: TPointArray);
procedure Delete(Word: boolean = false);
procedure Left(Word: boolean = false; Selection: boolean = false; Block: boolean = false);
procedure Right(Word: boolean = false; Selection: boolean = false; Block: boolean = false);
procedure Up(Selection: boolean = false; Block: boolean = false);
procedure Down(Selection: boolean = false; Block: boolean = false);
procedure Return;
procedure Home(AFile: boolean = false; Selection: boolean = false);
procedure KEnd(AFile: boolean = false; Selection: boolean = false);
function HasSelection: boolean; inline;
function SelectionIsMultiline: boolean; inline;
procedure ClearSelection;
function PrevWordBoundary(Point: TPoint): integer; overload; inline;
function NextWordBoundary(Point: TPoint): integer; overload; inline;
function PrevWordBoundary(Y, X: integer): integer; overload;
function NextWordBoundary(Y, X: integer): integer; overload;
function PrevWordBoundary: integer; overload;
function NextWordBoundary: integer; overload;
function GetIndent(LineIndex: integer): integer; overload;
function GetIndent: integer; overload;
function LineIsEmpty(const LineIndex: integer): boolean;
procedure InsertText(const AText: string);
procedure MultiInsertText(var ACarets: TPointArray; const AText: string);
procedure InsertTextAsBlock(const AText: string);
procedure SurroundText(const APrefix, APostfix: string);
procedure CutToClipboard;
procedure CopyToClipboard;
function PasteFromClipboard: boolean;
function PasteFromClipboardAsBlock: boolean;
procedure ClearLine(LineIndex: integer); overload;
procedure ClearLine; overload;
function SwapLines(FirstLine, SecondLine: integer): boolean;
function SwapLinesAbove: boolean;
function SwapLinesBelow: boolean;
function ReplaceCodepoint: boolean;
function IsCharInRgn(X, Y: integer; SelectionType: TSelectionType; const FirstPoint, SecondPoint: TPoint): boolean; overload;
function IsCharInRgn(const Point: TPoint; SelectionType: TSelectionType; const FirstPoint, SecondPoint: TPoint): boolean; overload; inline;
function IsCharSel(const X, Y: integer): boolean; overload;
function IsCharSel(const Point: TPoint): boolean; overload; inline;
function IsCharFound(const X, Y: integer): boolean;
procedure SelectAll;
procedure SelectNone;
procedure SelectAllNone;
function AllSelected: boolean;
function GetWordBoundary(const Point: TPoint; out StartPos, EndPos: integer; PascalIdent: boolean = false): boolean; overload;
function GetWordBoundary(out StartPos, EndPos: integer; PascalIdent: boolean = false): boolean; overload;
function GetWord(const Point: TPoint; PascalIdent: boolean = false): string; overload;
function GetWord(PascalIdent: boolean = false): string; overload;
function GetURLAtCaret(out AURL: string): boolean;
function SelectWord: boolean;
procedure SelectLines(const ALineA, ALineB: integer);
procedure SelectLine(const ALineIndex: integer); overload;
procedure SelectLine; overload;
procedure NewFile;
procedure NewFileAndInitUndo;
procedure SaveToFile(const FileName: TFileName; TrimRight: boolean = false;
AExport: boolean = false);
procedure LoadFromFile(const FileName: TFileName; Encoding: TEncoding;
ClassAware: boolean = false);
procedure LoadFromFileAndInitUndo(const FileName: TFileName; Encoding: TEncoding);
procedure AddIndent;
procedure RemoveIndent;
procedure RemoveAllIndent;
function CanAutoReplace(out StartPos, Index: integer): boolean;
procedure DoAutoReplace(const StartPos, Index: integer);
function AutoReplace: boolean;
function MatchBracket(const BracketPoint: TPoint): TPoint;
procedure AddUndoRecord(const AComment: string; UID: UNDONAMEID); overload;
procedure AddUndoRecord; overload;
procedure ClearUndoHistory;
function CanUndo: boolean;
function Undo: boolean;
function CanRedo: boolean;
function Redo: boolean;
function GotoHistoryVersion(Index: integer): boolean;
function Find(AFindData: TFindQuery; AInternal: boolean = false): integer;
function ReplaceAll(const ReplaceText: string; SelOnly: boolean = false): integer;
function NumCharsOfType(CharTestFunction: TCharTestFunction): integer;
function GetFileStatistics(AFileStatisticsFlags: TFileStatisticsFlags = FILE_STAT_ALL;
AWordFreqs: TWordFreqDict = nil): TFileStatistics;
function GetUnicodeBlockStatistics: TIntegerArray;
function GetControlCharCount: integer;
function GetNoncharacterCount: integer;
function LineExists(LineIndex: integer): boolean; inline;
function DeleteControlAtLine(const LineIndex: integer): boolean;
procedure TrimRight;
procedure ClearBookmarks;
procedure AddBookmark(AIndex: integer; const APoint: TPoint); overload;
procedure AddBookmark(AIndex: integer); overload;
function AddBookmark(const APoint: TPoint): integer; overload;
function AddBookmark: integer; overload;
function GotoBookmark(AIndex: integer): boolean;
function RemoveGhostBookmarks: boolean;
function ChrTransform(Transformation: TChrTransformFunc): boolean;
procedure ChrTransformText(Transformation: TChrTransformFunc);
function FillWithChar(const AChar: char): boolean;
property CaretPos: TCaretPos read FCaretPos;
property Lines[Index: Integer]: string read GetLine write SetLine;
property Classes[Index: Integer]: string read GetClass write SetClass;
property PhysicalLineWidths[Index: Integer]: integer read GetPhysicalLineWidth;
property VirtualLineWidths[Index: Integer]: integer read GetVirtualLineWidth;
property Character[Y, X: Integer]: char read GetChar write SetChar;
function UnsafeGetChar(Y, X: integer): char; inline;
function IsWrappable(const AChar: char): boolean; inline;
procedure FindWhereToWrap(ALineIndex: integer; MaxLength: integer;
var AWrapList: TIntegerDynArray);
procedure WordWrap(ALineLength: integer = 80; ANice: boolean = true;
AChr: char = #0);
function Sort(AFirstLine, ALastLine: integer; BookmarkAware: boolean): boolean; overload;
function Sort(BookmarkAware: boolean): boolean; overload;
function SortSelection(BookmarkAware: boolean): boolean;
property LineComparer: TLineComparer read FLineComparer write FLineComparer;
property SortReverseOrder: boolean read FSortReverseOrder write FSortReverseOrder default false;
function MakeLinesUnique: boolean;
procedure TruncateAt(AFirstLine, ALastLine, AIndex: integer;
AChar: char = #0; PreserveChar: boolean = false; AReverse: boolean = false);
procedure Filter(const AFilterOptions: TFilterOptions);
procedure SaveToStream(AStream: TStream);
procedure CreateDataStream(out Data: pointer; out Len: UInt64);
procedure LoadFromStream(AStream: TStream);
procedure LoadFromBuffer(const Data: pointer; const Len: UInt64);
property MaxLineWidth: integer read GetMaxLineWidth;
property LineCount: integer read GetLineCount;
property CaretAfterEOL: boolean read FCaretAfterEOL write SetCaretAfterEOL default true;
property AutoIndent: boolean read FAutoIndent write FAutoIndent;
property NumCharacters: integer read GetNumCharacters;
property VirtualTextLength: integer read GetVirtualTextLength;
property PhysicalTextLength: integer read GetPhysicalTextLength;
property PlainText: string read GetText write SetText;
property SelText: string read GetSelText write InsertText;
property SelStart: integer read GetSelStart write SetSelStart;
property SelLength: integer read GetSelLength write SetSelLength;
property IndentSize: integer read FIndentSize write FIndentSize;
property EditMode: TEditMode read FEditMode write FEditMode default emText;
property FileModified: boolean read FModified write FModified default false;
property FileName: TFileName read FFileName write FFileName;
property HistoryManager: THistoryManager read FHistoryManager;
property FindData[Index: integer]: TTextSpan read GetFindData;
property FindCount: integer read GetFindCount;
property SingleLine: boolean read FSingleLine write SetSingleLine default false;
property ControlAware: boolean read FControlAware write FControlAware default false;
function Empty: boolean;
property Bookmarks[Index: Integer]: TPoint read GetBookmark write AddBookmark;
property BookmarkCount: integer read GetBookmarkCount;
property UsedBookmarkCount: integer read GetUsedBookmarkCount;
property HasBookmarks: boolean read GetHasBookmarks;
property WrapAt: string read FWrapAt write FWrapAt;
property EditorState: TEditorState read FEditorState write FEditorState;
property Encoding: TTextFileFormatInfo read FEncoding write FEncoding;
property RecentlyOpened: boolean read FRecentlyOpened;
property StrictReadOnly: boolean read FStrictReadOnly write FStrictReadOnly default false;
property UseLineClasses: boolean read FUseLineClasses write FUseLineClasses default false;
property AutoReplaceItems[Index: integer]: TAutoReplaceItem read GetAutoReplaceItem;
property AutoReplaceItemCount: integer read GetAutoReplaceItemCount;
property OnChange: TChangeEvent read FOnChange write FOnChange;
property OnCaretPosChange: TNotifyEvent read FOnCaretPosChange write FOnCaretPosChange;
property OnCaretPosSelChange: TChangeEvent read FOnCaretPosSelChange write FOnCaretPosSelChange;
property OnFileModified: TNotifyEvent read FOnModified write FOnModified;
property OnInputError: TNotifyEvent read FOnInputError write FOnInputError;
property OnReadOnlyError: TNotifyEvent read FOnReadOnlyError write FOnReadOnlyError;
property OnFindDataClear: TNotifyEvent read FOnFindDataClear write FOnFindDataClear;
property OnLineChange: TLineChangeEvent read FOnLineChange write FOnLineChange;
property OnControlRemoved: TControlEvent read FOnControlRemoved write FOnControlRemoved;
property OnLineClassChange: TLineEvent read FOnLineClassChange write FOnLineClassChange;
property OnGetControlText: TGetControlTextEvent read FOnGetControlText write FOnGetControlText;
property OnBookmarksMoved: TNotifyEvent read FOnBookmarksMoved write FOnBookmarksMoved;
property OnLockVisualUpdates: TNotifyEvent read FOnLockVisualUpdates write FOnLockVisualUpdates;
property OnUnlockVisualUpdates: TNotifyEvent read FOnUnlockVisualUpdates write FOnUnlockVisualUpdates;
end;
const
EDITOR_COMMAND_RIGHT = 1;
EDITOR_COMMAND_LEFT = 2;
EDITOR_COMMAND_DOWN = 3;
EDITOR_COMMAND_UP = 4;
EDITOR_COMMAND_HOME = 5;
EDITOR_COMMAND_END = 6;
EDITOR_COMMAND_PAGE_UP = 7;
EDITOR_COMMAND_PAGE_DOWN = 8;
EDITOR_COMMAND_BACKSPACE = 9;
EDITOR_COMMAND_DELETE = 10;
EDITOR_COMMAND_CLEAR_SELECTION = 11;
EDITOR_COMMAND_SELECT_ALL = 12;
EDITOR_COMMAND_SELECT_NONE = 13;
EDITOR_COMMAND_SELECT_ALL_NONE = 14;
EDITOR_COMMAND_SELECT_WORD = 15;
EDITOR_COMMAND_SELECT_LINE = 16;
EDITOR_COMMAND_CLEAR_LINE = 17;
EDITOR_COMMAND_CUT = 18;
EDITOR_COMMAND_COPY = 19;
EDITOR_COMMAND_PASTE = 20;
EDITOR_COMMAND_UNDO = 21;
EDITOR_COMMAND_REDO = 22;
EDITOR_COMMAND_CLEAR_UNDO_BUFFER = 23;
EDITOR_COMMAND_GOTO_SOF = 24;
EDITOR_COMMAND_GOTO_EOF = 25;
EDITOR_COMMAND_RETURN = 26;
EDITOR_COMMAND_CHAR = 27;
EDITOR_COMMAND_GET_AT_SOF = 28;
EDITOR_COMMAND_GET_AT_EOL = 29;
EDITOR_COMMAND_GET_BEYOND_EOL = 30;
EDITOR_COMMAND_GET_AT_EOF = 31;
EDITOR_COMMAND_GET_AT_LAST_LINE = 32;
EDITOR_COMMAND_GET_HAS_SELECTION = 33;
EDITOR_COMMAND_GET_LINE_NUMBER_0 = 34;
EDITOR_COMMAND_GET_COL_NUMBER_0 = 35;
EDITOR_COMMAND_GET_CHR_INDEX = 36;
EDITOR_COMMAND_GOTO_POINT = 37;
EDITOR_COMMAND_GOTO_INDEX = 38;
EDITOR_COMMAND_GET_SEL_LENGTH = 39;
EDITOR_COMMAND_SET_SEL_LENGTH = 40;
EDITOR_COMMAND_GET_EDIT_MODE = 41;
EDITOR_COMMAND_SET_EDIT_MODE = 42;
EDITOR_COMMAND_GET_SELECTION_MODE = 43;
EDITOR_COMMAND_SET_SELECTION_MODE = 44;
EDITOR_COMMAND_GET_OVERWRITE = 45;
EDITOR_COMMAND_SET_OVERWRITE = 46;
EDITOR_COMMAND_GET_AUTO_REPLACE = 47;
EDITOR_COMMAND_SET_AUTO_REPLACE = 48;
EDITOR_COMMAND_GET_CHAR = 49;
EDITOR_COMMAND_ADD_INDENT = 50;
EDITOR_COMMAND_REMOVE_INDENT = 51;
EDITOR_COMMAND_TRIM_INDENT = 52;
EDITOR_COMMAND_SWAP_UP = 53;
EDITOR_COMMAND_SWAP_DOWN = 54;
EDITOR_COMMAND_GET_AUTO_INDENT = 55;
EDITOR_COMMAND_SET_AUTO_INDENT = 56;
EDITOR_COMMAND_GET_CARET_BEYOND_EOL = 57;
EDITOR_COMMAND_SET_CARET_BEYOND_EOL = 58;
EDITOR_COMMAND_GET_NUM_CHARACTERS = 59;
EDITOR_COMMAND_GET_TEXT_SIZE = 60;
EDITOR_COMMAND_GET_NUM_LINES = 61;
EDITOR_COMMAND_GET_MAX_WIDTH = 62;
EDITOR_COMMAND_SCROLL_TO_CARET = 63;
EDITOR_COMMAND_REPLACE_TOKEN = 64;
EDITOR_COMMAND_REPLACE_CODEPOINT = 65;
EDITOR_COMMAND_UPDATE_SCROLLBARS = 66;
EDITOR_COMMAND_UPDATE_CARET = 67;
EDITOR_COMMAND_UPDATE_CURSOR = 68;
EDITOR_COMMAND_REDRAW = 69;
EDITOR_COMMAND_REDRAW_LINE = 70;
EDITOR_COMMAND_REDRAW_LINE_RANGE = 71;
EDITOR_COMMAND_REDRAW_BLOCK = 72;
EDITOR_COMMAND_GET_MODIFIED = 73;
EDITOR_COMMAND_SET_MODIFIED = 74;
EDITOR_COMMAND_NEW = 75;
EDITOR_COMMAND_CLEAR = 76;
EDITOR_COMMAND_OPEN = 77;
EDITOR_COMMAND_SAVE = 78;
EDITOR_COMMAND_GET_HIDDEN = 79;
EDITOR_COMMAND_SET_HIDDEN = 80;
EDITOR_COMMAND_SET_SELECTION = 81;
EDITOR_COMMAND_GET_MATCH_BRACKETS = 82;
EDITOR_COMMAND_SET_MATCH_BRACKETS = 83;
EDITOR_COMMAND_GET_BRACKET_HIGHLIGHT = 84;
EDITOR_COMMAND_GET_SCROLL_POS_X = 85;
EDITOR_COMMAND_GET_SCROLL_POS_Y = 86;
EDITOR_COMMAND_SET_SCROLL_POS = 87;
EDITOR_COMMAND_REDRAW_CHAR = 88;
EDITOR_COMMAND_REDRAW_CHARS = 89;
EDITOR_COMMAND_GET_INDENT = 90;
EDITOR_COMMAND_SET_INDENT = 91;
EDITOR_COMMAND_GET_TAB_LENGTH = 92;
EDITOR_COMMAND_SET_TAB_LENGTH = 93;
EDITOR_COMMAND_GET_SINGLE_LINE = 94;
EDITOR_COMMAND_SET_SINGLE_LINE = 95;
EDITOR_COMMAND_GET_LABEL_MODE = 96;
EDITOR_COMMAND_SET_LABEL_MODE = 97;
EDITOR_COMMAND_GET_ELLIPSIS_MODE = 98;
EDITOR_COMMAND_SET_ELLIPSIS_MODE = 99;
EDITOR_COMMAND_GET_INPUT_TRANSFORM = 100;
EDITOR_COMMAND_SET_INPUT_TRANSFORM = 101;
EDITOR_COMMAND_GET_NUMBERS_ONLY = 102;
EDITOR_COMMAND_SET_NUMBERS_ONLY = 103;
EDITOR_COMMAND_GET_PASSWORD_CHAR = 104;
EDITOR_COMMAND_SET_PASSWORD_CHAR = 105;
EDITOR_COMMAND_GET_UNICODE_FALLBACK = 106;
EDITOR_COMMAND_SET_UNICODE_FALLBACK = 107;
EDITOR_COMMAND_ESCAPE = 108;
EDITOR_COMMAND_USE_DEFAULT_FALLBACK_FONTS = 109;
EDITOR_COMMAND_SHOW_BALLOON = 110;
EDITOR_COMMAND_HIDE_BALLOON = 111;
EDITOR_COMMAND_SHOW_BALLOON_POS = 112;
EDITOR_COMMAND_IS_BALLOON_VISIBLE = 113;
EDITOR_COMMAND_ADJUST_HEIGHT = 114;
EDITOR_COMMAND_GET_UNDO_LENGTH = 115;
EDITOR_COMMAND_GET_UNDO_SIZE = 116;
EDITOR_COMMAND_GET_UNDO_MAX_SIZE = 117;
EDITOR_COMMAND_SET_UNDO_MAX_SIZE = 118;
EDITOR_COMMAND_GET_UNDO_FIRST_INDEX = 119;
EDITOR_COMMAND_GET_UNDO_LAST_INDEX = 120;
EDITOR_COMMAND_GET_UNDO_POSITION = 121;
EDITOR_COMMAND_WINDOWS_MESSAGE = 122;
EDITOR_COMMAND_COPY_ALL = 123;
EDITOR_COMMAND_FIND = 124;
EDITOR_COMMAND_GET_FIND_COUNT = 125;
EDITOR_COMMAND_FIND_NEXT = 126;
EDITOR_COMMAND_FIND_PREV = 127;
EDITOR_COMMAND_FIND_FROM_TOP = 128;
EDITOR_COMMAND_GET_START_OVER = 129;
EDITOR_COMMAND_SET_START_OVER = 130;
EDITOR_COMMAND_REPLACE_ALL = 131;
EDITOR_COMMAND_ADD_UNDO_RECORD = 132;
EDITOR_COMMAND_POSTTYPE = 133;
EDITOR_COMMAND_TYPE_TIMER_EMD = 134;
EDITOR_COMMAND_TYPE_TIMER_DISABLE = 135;
EDITOR_COMMAND_TYPE_TIMER_DISCONNECT = 136;
EDITOR_COMMAND_TYPE_TIMER_CONNECT = 137;
EDITOR_COMMAND_GET_ENABLED = 138;
EDITOR_COMMAND_SET_ENABLED = 139;
EDITOR_COMMAND_IS_FOCUSED = 140;
EDITOR_COMMAND_TRY_FOCUS = 141;
EDITOR_COMMAND_GET_FIRST_VISIBLE_LINE = 142;
EDITOR_COMMAND_GET_LAST_VISIBLE_LINE = 143;
EDITOR_COMMAND_RECOMPUTE_HOR_EXTENT = 144;
EDITOR_COMMAND_ACTIVATE_CONTROL = 145;
EDITOR_COMMAND_REMOVE_LINE_CONTROL = 146;
EDITOR_COMMAND_ADD_LINE_CONTROL = 147;
EDITOR_COMMAND_ADD_GRAPHICS = 148;
EDITOR_COMMAND_INSERT_LINE_CONTROL = 149;
EDITOR_COMMAND_INSERT_GRAPHICS = 150;
EDITOR_COMMAND_TRIM_RIGHT = 151;
EDITOR_COMMAND_BOOKMARK_SET_MENU = 152;
EDITOR_COMMAND_BOOKMARK_GO_MENU = 153;
EDITOR_COMMAND_BOOKMARK_CLEAR_MENU = 154;
EDITOR_COMMAND_BOOKMARK_SET = 155;
EDITOR_COMMAND_BOOKMARK_GO = 156;
EDITOR_COMMAND_BOOKMARK_CLEAR = 157;
EDITOR_COMMAND_BOOKMARK_CLEAR_ALL = 158;
EDITOR_COMMAND_CLASS_MENU = 159;
EDITOR_COMMAND_CLASS_USE = 160;
EDITOR_COMMAND_CLASS_REMOVE = 161;
EDITOR_COMMAND_SET_FP = 162;
EDITOR_COMMAND_EXPORT_HTML = 163;
EDITOR_COMMAND_OPEN_URL_AT_CARET = 164;
EDITOR_COMMAND_SELECT_LINE_INDEX = 165;
EDITOR_COMMAND_SELECT_LINE_RANGE = 166;
EDITOR_COMMAND_DISABLE_SCROLL_TO_CARET = 167;
EDITOR_COMMAND_ENABLE_SCROLL_TO_CARET = 168;
EDITOR_COMMAND_CREATE_SELECTION = 169;
EDITOR_COMMAND_CREATE_BLOCK_SELECTION = 170;
EDITOR_COMMAND_GET_LINE_HIGHLIGHT = 171;
EDITOR_COMMAND_SET_LINE_HIGHLIGHT = 172;
EDITOR_COMMAND_REDRAW_RULER = 173;
EDITOR_COMMAND_REDRAW_RULER_LINE = 174;
EDITOR_COMMAND_PRINT = 175;
EDITOR_COMMAND_PRINT_SELECTION = 176;
EDITOR_COMMAND_SET_PRINT_MARGINS = 177;
EDITOR_COMMAND_SET_PRINT_WW_OPTIONS = 178;
EDITOR_COMMAND_PRINT_DIALOG = 179;
EDITOR_COMMAND_GET_PRINT_VMARGIN = 180;
EDITOR_COMMAND_GET_PRINT_HMARGIN = 181;
EDITOR_COMMAND_GET_PRINT_WW_OPTIONS = 182;
EDITOR_COMMAND_GET_PRINT_WW_CHAR = 183;
EDITOR_COMMAND_GET_PRINT_WW_COLOR = 184;
EDITOR_COMMAND_WORDWRAP = 185;
EDITOR_COMMAND_UPPER_CASE = 186;
EDITOR_COMMAND_LOWER_CASE = 187;
EDITOR_COMMAND_INVERT_CASE = 188;
EDITOR_COMMAND_SEL_UPPER_CASE = 189;
EDITOR_COMMAND_SEL_LOWER_CASE = 190;
EDITOR_COMMAND_SEL_INVERT_CASE = 191;
EDITOR_COMMAND_CAMEL_CASE = 192;
EDITOR_COMMAND_SENTENCE_CASE = 193;
EDITOR_COMMAND_SEL_CAMEL_CASE = 194;
EDITOR_COMMAND_SEL_SENTENCE_CASE = 195;
EDITOR_COMMAND_SEL_TRANSFORM_MENU = 196;
EDITOR_COMMAND_ROT13 = 197;
EDITOR_COMMAND_CAESAR = 198;
EDITOR_COMMAND_VIGENERE = 199;
EDITOR_COMMAND_SEL_ROT13 = 200;
EDITOR_COMMAND_SEL_CAESAR = 201;
EDITOR_COMMAND_SEL_VIGENERE = 202;
EDITOR_COMMAND_UPDATE_SCROLL_MODE = 203;
EDITOR_COMMAND_GET_SCROLL_MODE = 204;
EDITOR_COMMAND_SORT = 205;
EDITOR_COMMAND_SORT_ALL = 206;
EDITOR_COMMAND_SORT_SEL = 207;
EDITOR_COMMAND_SET_LINE_COMPARER = 208;
EDITOR_COMMAND_GET_LINE_COMPARER = 209;
EDITOR_COMMAND_SET_SORT_REVERSE = 210;
EDITOR_COMMAND_GET_SORT_REVERSE = 211;
EDITOR_COMMAND_MAKE_LINES_UNIQUE = 212;
EDITOR_COMMAND_CLI_NEW_PROMPT = 213;
EDITOR_COMMAND_CLI_WRITELN = 214;
EDITOR_COMMAND_ABORT_SCRIPT = 215;
EDITOR_COMMAND_WRITE_INT = 216;
EDITOR_COMMAND_ABORT_SCRIPT_IF_EOL = 217;
EDITOR_COMMAND_ABORT_SCRIPT_IF_LL = 218;
EDITOR_COMMAND_ABORT_SCRIPT_IF_EOF = 219;
EDITOR_COMMAND_ABORT_SCRIPT_IF_SOF = 220;
EDITOR_COMMAND_SET_SCRIPT_COUNTER = 221;
EDITOR_COMMAND_GET_SCRIPT_COUNTER = 222;
EDITOR_COMMAND_GET_LINE_NUMBER_1 = 223;
EDITOR_COMMAND_GET_COL_NUMBER_1 = 224;
EDITOR_COMMAND_WRITE_DATE = 225;
EDITOR_COMMAND_WRITE_TIME = 226;
EDITOR_COMMAND_WRITE_DATETIME = 227;
EDITOR_COMMAND_GET_TICKCOUNT = 228;
EDITOR_COMMAND_GET_RANDOM_INTEGER = 229;
EDITOR_COMMAND_FIX_REMOVED_LINE_CONTROLS = 230;
EDITOR_COMMAND_CLI_HISTORY_UP = 231;
EDITOR_COMMAND_CLI_HISTORY_DOWN = 232;
EDITOR_COMMAND_CLI_HISTORY_CLEAR = 233;
EDITOR_COMMAND_CLI_HISTORY_ADD = 234;
EDITOR_COMMAND_CLI_GET_HISTORY_LENGTH = 235;
EDITOR_COMMAND_CLI_GET_HISTORY_INDEX = 236;
EDITOR_COMMAND_CLI_HISTORY_RECALL = 237;
EDITOR_COMMAND_BEGIN_ADD_LINES = 238;
EDITOR_COMMAND_END_ADD_LINES = 239;
EDITOR_COMMAND_GET_LISTBOX_MODE = 240;
EDITOR_COMMAND_SET_LISTBOX_MODE = 241;
EDITOR_COMMAND_WRITE_STRING = 242;
EDITOR_COMMAND_WRITE_INPUT_DIALOG = 243;
EDITOR_COMMAND_SET_AS_HYPHEN_ASTERISK_TOGGLE = 244;
EDITOR_COMMAND_SET_MULTI_CHAR_SELECT = 245;
EDITOR_COMMAND_GET_MULTI_CHAR_SELECT = 246;
EDITOR_COMMAND_SET_MULTI_CHAR_REPORT_VIEW = 247;
EDITOR_COMMAND_GET_MULTI_CHAR_REPORT_VIEW = 248;
EDITOR_COMMAND_SET_NO_VERIFY_FONT = 249;
EDITOR_COMMAND_SET_DOUBLE_BUFFERING = 250;
EDITOR_COMMAND_REPLACE_ALL_IN_SELECTION = 251;
EDITOR_COMMAND_SET_BITMAP_EFFECT = 252;
EDITOR_COMMAND_GET_BITMAP_EFFECT = 253;
EDITOR_COMMAND_SET_DISABLED_EFFECT = 254;
EDITOR_COMMAND_GET_DISABLED_EFFECT = 255;
EDITOR_COMMAND_REPEAT = 256;
EDITOR_COMMAND_REPEAT_EX_SET_NUM = 257;
EDITOR_COMMAND_REPEAT_EX_SET_COMMAND = 258;
EDITOR_COMMAND_REPEAT_EX = 259;
EDITOR_COMMAND_RESTORE_MARGINS = 260;
EDITOR_COMMAND_FILL_WITH_CHAR = 261;
EDITOR_COMMAND_PASTE_AS_BLOCK = 262;
EDITOR_COMMAND_TRUNCATE_AT = 263;
EDITOR_COMMAND_TRUNCATE_AT_IN_FILE = 264;
EDITOR_COMMAND_TRUNCATE_AT_IN_SELECTION = 265;
EDITOR_COMMAND_GET_JUST_OPENED = 266;
EDITOR_COMMAND_LOAD_DEFAULT_CLASSES = 267;
EDITOR_COMMAND_BEGIN_VISUAL_UPDATE = 268;
EDITOR_COMMAND_END_VISUAL_UPDATE = 269;
EDITOR_COMMAND_SURROUND_SEL = 270;
EDITOR_COMMAND_FILTER_LINES = 271;
EDITOR_COMMAND_UPDATE_SPI = 272;
EDITOR_COMMAND_SET_STRICT_READONLY = 273;
EDITOR_COMMAND_REMOVE_GHOST_BOOKMARKS = 274;
EDITOR_COMMAND_CHARACTER_FIND = 275;
EDITOR_COMMAND_SEL_REVERSE = 276;
EDITOR_COMMAND_CENTER_ON_SELECTION = 277;
IMAGE_COMMAND_COPY = 1;
IMAGE_COMMAND_REMOVE = 2;
IMAGE_COMMAND_CHANGE = 3;
RULER_COMMAND_PROPERTIES = 1;
type
TFontRecord = record
Size: integer;
Style: TFontStyles;
Color: TColor;
BoxSize: TSize;
end;
TClassRecord = record
Name: string;
Format: TFontRecord;
end;
TClassArray = array of TClassRecord;
function FontRecord(ASize: integer; AStyle: TFontStyles; AColor: TColor): TFontRecord;
function MakeClass(const AName: string; ASize: integer; AStyle: TFontStyles; AColor: TColor): TClassRecord;
type
TInputTransform = (itNone, itUpperCase, itLowerCase, itSuperscript,
itSubscript, itCircled, itParenthesized, itFullStop, itDoublyCircled);
TBalloonPersistence = (bpTime, bpScroll, bpCaretPos, bpModify, bpRemain);
TBalloonIconKind = (bikNone = TTI_NONE, bikInfo = TTI_INFO,
bikWarning = TTI_WARNING, bikError = TTI_ERROR, bikInfoLarge = TTI_INFO_LARGE,
bikWarningLarge = TTI_WARNING_LARGE, bikErrorLarge = TTI_ERROR_LARGE);
TLineControlRecord = record
ID: integer;
Control: TControl;
end;
TCSSDeclaration = record
CSSProperty: string;
Value: string;
end;
TCSSDeclarationBlock = array of TCSSDeclaration;
TCSSRule = record
Selector: string;
Declarations: TCSSDeclarationBlock;
end;
TCSSRules = array of TCSSRule;
function MakeCSSDeclaration(const AProperty, AValue: string): TCSSDeclaration;
function MakeCSSOptionalDeclaration(const AUse: boolean; const AProperty, AValue: string): TCSSDeclaration;
function MakeCSSRule(const ASelector: string; const ADeclarations: array of TCSSDeclaration): TCSSRule;
function CSSColor(const AColor: TColor): string;
const
SC_BLACK = $00000000;
SC_BLUE = $00FF0000;
SC_RED = $00000099;
SC_GREEN = $00008000;
SC_GRAY = $00999999;
SC_INTENSE_RED = $000000FF;
type
TColorScheme = record
Default,
Accent1,
Accent2,
Accent3,
Soft,
Intense: TColor;
end;
const
DEFAULT_COLORS: TColorScheme = (Default: SC_BLACK; Accent1: SC_BLUE; Accent2:
SC_GREEN; Accent3: SC_RED; Soft: SC_GRAY; Intense: SC_INTENSE_RED);
type
TGetLineWidthEvent = function(ALineIndex: integer): integer of object;
TGetCharEvent = function(ALineIndex, ACol: integer): char of object;
TGetLineCountEvent = function: integer of object;
TGetWordEvent = function(const APoint: TPoint; APascalIdent: boolean = false): string of object;
TGetWordBoundaryEvent = function(const APoint: TPoint; out SP, EP: integer): boolean of object;
TFormattingProcessor = class(TComponent)
strict private
FUpdateLevel: integer;
FOnChange: TNotifyEvent;
FOnGetLineWidth: TGetLineWidthEvent;
FOnGetChar: TGetCharEvent;
FOnGetLineCount: TGetLineCountEvent;
FOnGetWord: TGetWordEvent;
FOnGetWordBoundary: TGetWordBoundaryEvent;
strict protected
procedure Changed;
function TextLineWidth(ALineIndex: integer): integer; inline;
function TextChar(ALineIndex, ACol: integer): char; inline;
function TextLineCount: integer; inline;
function TextGetWord(const APoint: TPoint; APascalIdent: boolean = false): string; inline;
function TextGetWordBoundary(const APoint: TPoint; out SP, EP: integer): boolean; inline;
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: integer; ACol: integer; AChar: char;
var AFontRecord: TFontRecord); virtual; abstract;
function FileChangeNotification(ChangeType: TChangeType;
Data1, Data2, Data3, Data4: Integer): TChangeRecord; virtual;
function GetCSSRules: TCSSRules; virtual; abstract;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): integer; virtual; abstract;
procedure BeginUpdate;
procedure EndUpdate;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); virtual; abstract;
function GetCache(out ACache: PByte): integer; virtual;
function RestoreCache(ACache: PByte; ASize: integer): boolean; virtual;
procedure ClearCache; virtual;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnGetLineWidth: TGetLineWidthEvent read FOnGetLineWidth write FOnGetLineWidth;
property OnGetChar: TGetCharEvent read FOnGetChar write FOnGetChar;
property OnGetLineCount: TGetLineCountEvent read FOnGetLineCount write FOnGetLineCount;
property OnGetWord: TGetWordEvent read FOnGetWord write FOnGetWord;
property OnGetWordBoundary: TGetWordBoundaryEvent read FOnGetWordBoundary write FOnGetWordBoundary;
end;
TVowelsAndConsonantsFormattingProcessor = class(TFormattingProcessor)
private const
DEFAULT_VOWEL_COLOR = SC_RED;
DEFAULT_CONSONANT_COLOR = SC_GREEN;
DEFAULT_VOWELS_BOLD = true;
DEFAULT_CONSONANTS_BOLD = false;
private const
CSS_CLASS_VOWEL = 0;
CSS_CLASS_CONSONANT = 1;
CSS_CLASS_HIGH = CSS_CLASS_CONSONANT;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FVowelColor,
FConsonantColor: TColor;
FVowelsBold: boolean;
FConsonantsBold: boolean;
procedure SetConsonantColor(const Value: TColor);
procedure SetVowelColor(const Value: TColor);
procedure SetConsonantsBold(const Value: boolean);
procedure SetVowelsBold(const Value: boolean);
function IsVowel(const AChar: Char): boolean;
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer; AChar: Char): integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property VowelColor: TColor read FVowelColor write SetVowelColor default DEFAULT_VOWEL_COLOR;
property ConsonantColor: TColor read FConsonantColor write SetConsonantColor default DEFAULT_CONSONANT_COLOR;
property VowelsBold: boolean read FVowelsBold write SetVowelsBold default DEFAULT_VOWELS_BOLD;
property ConsonantBold: boolean read FConsonantsBold write SetConsonantsBold default DEFAULT_CONSONANTS_BOLD;
end;
TXMLFormattingProcessor = class(TFormattingProcessor)
private type
TXMLChrKind = (ckXmlUndefined = -1, ckXmlText, ckXmlTag, ckXmlTagName,
ckXmlParam, ckXmlValue, ckXmlComment, ckCDATAMarker, ckCDATA,
ckXmlSignatureOnly);
TFmtBreak = record
x: integer;
kind: TXMLChrKind;
signature: cardinal;
end;
private const
DEFAULT_TAG_COLOR = SC_BLUE;
DEFAULT_TAG_NAME_COLOR = SC_RED;
DEFAULT_TAG_NAME_BOLD = false;
DEFAULT_PARAM_COLOR = SC_BLUE;
DEFAULT_VALUE_COLOR = SC_GREEN;
DEFAULT_COMMENT_COLOR = SC_GRAY;
DEFAULT_CDATAM_COLOR = SC_GRAY;
DEFAULT_CDATAM_BOLD = true;
DEFAULT_CDATA_COLOR = SC_BLACK;
private const
CSS_CLASS_TEXT = 0;
CSS_CLASS_TAG = 1;
CSS_CLASS_TAG_NAME = 2;
CSS_CLASS_PARAM = 3;
CSS_CLASS_VALUE = 4;
CSS_CLASS_COMMENT = 5;
CSS_CLASS_CDATAMARKER = 6;
CSS_CLASS_CDATA = 7;
CSS_CLASS_HIGH = CSS_CLASS_CDATA;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FValueColor: TColor;
FParamColor: TColor;
FTagColor: TColor;
FCommentColor: TColor;
FTokens: array of array of TFmtBreak;
FTagNameColor: TColor;
FTagNameBold: boolean;
FCDATAMColor: TColor;
FCDATAMBold: boolean;
FCDATAColor: TColor;
procedure SetParamColor(const Value: TColor);
procedure SetTagColor(const Value: TColor);
procedure SetValueColor(const Value: TColor);
function ParseText(AFromLine: integer = 0;
SingleLinePossibility: boolean = false; ANumLines: integer = 1): integer;
function GetChrKind(ALineIndex, ACol: Integer): TXMLChrKind;
procedure SetCommentColor(const Value: TColor);
procedure PushTokensDownFrom(ALineIndex: integer);
procedure PushTokensUpFrom(ALineIndex: integer);
procedure SetTagNameBold(const Value: boolean);
procedure SetTagNameColor(const Value: TColor);
procedure SetCDATAMBold(const Value: boolean);
procedure SetCDATAMColor(const Value: TColor);
procedure SetCDATAColor(const Value: TColor);
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property TagColor: TColor read FTagColor write SetTagColor default DEFAULT_TAG_COLOR;
property TagNameColor: TColor read FTagNameColor write SetTagNameColor default DEFAULT_TAG_NAME_COLOR;
property TagNameBold: boolean read FTagNameBold write SetTagNameBold default DEFAULT_TAG_NAME_BOLD;
property ParamColor: TColor read FParamColor write SetParamColor default DEFAULT_PARAM_COLOR;
property ValueColor: TColor read FValueColor write SetValueColor default DEFAULT_VALUE_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor default DEFAULT_COMMENT_COLOR;
property CDATAMarkerColor: TColor read FCDATAMColor write SetCDATAMColor default DEFAULT_CDATAM_COLOR;
property CDATAMarkerBold: boolean read FCDATAMBold write SetCDATAMBold default DEFAULT_CDATAM_BOLD;
property CDATAColor: TColor read FCDATAColor write SetCDATAColor default DEFAULT_CDATA_COLOR;
end;
TCSSFormattingProcessor = class(TFormattingProcessor)
private type
TCSSChrKind = (ckCssUndefined = -1, ckCssSelector, ckCssBlockDelim,
ckCssProperty, ckCssValue, ckCssImportant, ckCssComment);
TFmtBreak = record
x: integer;
kind: TCSSChrKind;
signature: cardinal;
end;
private const
DEFAULT_SELECTOR_COLOR = SC_RED;
DEFAULT_SELECTOR_BOLD = false;
DEFAULT_PROPERTY_COLOR = SC_BLUE;
DEFAULT_VALUE_COLOR = SC_BLACK;
DEFAULT_COMMENT_COLOR = SC_GRAY;
DEFAULT_BLOCK_DELIM_COLOR = SC_RED;
DEFAULT_BLOCK_DELIM_BOLD = false;
DEFAULT_IMPORTANT_COLOR = SC_INTENSE_RED;
DEFAULT_IMPORTANT_BOLD = true;
private const
CSS_CLASS_SELECTOR = 0;
CSS_CLASS_PROPERTY = 1;
CSS_CLASS_VALUE = 2;
CSS_CLASS_COMMENT = 3;
CSS_CLASS_BLOCK_DELIM = 4;
CSS_CLASS_IMPORTANT = 5;
CSS_CLASS_HIGH = CSS_CLASS_IMPORTANT;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FSelectorColor: TColor;
FSelectorBold: boolean;
FPropertyColor: TColor;
FValueColor: TColor;
FCommentColor: TColor;
FTokens: array of array of TFmtBreak;
FBlockDelimColor: TColor;
FBlockDelimBold: boolean;
FImportantBold: boolean;
FImportantColor: TColor;
procedure SetSelectorColor(const Value: TColor);
procedure SetSelectorBold(const Value: boolean);
procedure SetPropertyColor(const Value: TColor);
procedure SetValueColor(const Value: TColor);
procedure SetCommentColor(const Value: TColor);
function GetChrKind(ALineIndex, ACol: Integer): TCSSChrKind;
function ParseText(AFromLine: integer = 0;
SingleLinePossibility: boolean = false; ANumLines: integer = 1): integer;
procedure SetBlockDelimColor(const Value: TColor);
procedure SetBlockDelimBold(const Value: boolean);
procedure SetImportantBold(const Value: boolean);
procedure SetImportantColor(const Value: TColor);
procedure PushTokensDownFrom(ALineIndex: integer);
procedure PushTokensUpFrom(ALineIndex: integer);
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property SelectorColor: TColor read FSelectorColor write SetSelectorColor default DEFAULT_SELECTOR_COLOR;
property SelectorBold: boolean read FSelectorBold write SetSelectorBold default DEFAULT_SELECTOR_BOLD;
property PropertyColor: TColor read FPropertyColor write SetPropertyColor default DEFAULT_PROPERTY_COLOR;
property ValueColor: TColor read FValueColor write SetValueColor default DEFAULT_VALUE_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor default DEFAULT_COMMENT_COLOR;
property BlockDelimColor: TColor read FBlockDelimColor write SetBlockDelimColor default DEFAULT_BLOCK_DELIM_COLOR;
property BlockDelimBold: boolean read FBlockDelimBold write SetBlockDelimBold default DEFAULT_BLOCK_DELIM_BOLD;
property ImportantColor: TColor read FImportantColor write SetImportantColor default DEFAULT_IMPORTANT_COLOR;
property ImportantBold: boolean read FImportantBold write SetImportantBold default DEFAULT_IMPORTANT_BOLD;
end;
TINIFormattingProcessor = class(TFormattingProcessor)
private const
DEFAULT_SECTION_COLOR = SC_RED;
DEFAULT_SECTION_BOLD = true;
DEFAULT_NAME_COLOR = SC_BLUE;
DEFAULT_VALUE_COLOR = SC_BLACK;
DEFAULT_COMMENT_COLOR = SC_GRAY;
private const
CSS_CLASS_SECTION = 0;
CSS_CLASS_NAME = 1;
CSS_CLASS_VALUE = 2;
CSS_CLASS_COMMENT = 3;
CSS_CLASS_EQUALS = 4;
CSS_CLASS_HIGH = CSS_CLASS_EQUALS;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FSectionColor: TColor;
FSectionBold: boolean;
FValueColor: TColor;
FNameColor: TColor;
FCommentColor: TColor;
procedure SetSectionColor(const Value: TColor);
procedure SetSectionBold(const Value: boolean);
procedure SetCommentColor(const Value: TColor);
procedure SetNameColor(const Value: TColor);
procedure SetValueColor(const Value: TColor);
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property SectionColor: TColor read FSectionColor write SetSectionColor default DEFAULT_SECTION_COLOR;
property SectionBold: boolean read FSectionBold write SetSectionBold default DEFAULT_SECTION_BOLD;
property NameColor: TColor read FNameColor write SetNameColor default DEFAULT_NAME_COLOR;
property ValueColor: TColor read FValueColor write SetValueColor default DEFAULT_VALUE_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor DEFAULT DEFAULT_COMMENT_COLOR;
end;
TPascalFormattingProcessor = class(TFormattingProcessor)
private type
TPascalChrKind = (ckPasUndefined = -1, ckPasKeyword, ckPasString,
ckPasNumber, ckPasComment, ckPasCompilerDirective);
TFmtBreak = record
x: integer;
kind: TPascalChrKind;
signature: cardinal;
end;
private const
PASCAL_IDENTS: array[0..118] of string = ('absolute', 'abstract', 'and',
'array', 'as', 'asm', 'assembler', 'automated', 'begin', 'case', 'cdecl',
'class', 'const', 'constructor', 'contains', 'default', 'delayed',
'deprecated', 'destructor', 'dispid', 'dispinterface', 'div', 'do',
'downto', 'dynamic', 'else', 'end', 'except', 'experimental', 'export',
'exports', 'external', 'far', 'file', 'final', 'finalization', 'finally',
'for', 'forward', 'function', 'goto', 'helper', 'if', 'implementation',
'implements', 'in', 'index', 'inherited', 'initialization', 'inline',
'interface', 'is', 'label', 'library', 'local', 'message', 'mod', 'name',
'near', 'nil', 'nodefault', 'not', 'object', 'of', 'operator', 'or', 'out',
'overload', 'override', 'package', 'packed', 'pascal', 'platform',
'private', 'procedure', 'program', 'property', 'protected', 'public',
'published', 'raise', 'read', 'readonly', 'record', 'reference',
'register', 'reintroduce', 'repeat', 'requires', 'resident',
'resourcestring', 'safecall', 'sealed', 'set', 'shl', 'shr', 'static',
'stdcall', 'stored', 'strict', 'string', 'then', 'threadvar', 'to', 'try',
'type', 'unit', 'unsafe', 'until', 'uses', 'var', 'varargs', 'while',
'winapi', 'virtual', 'with', 'write', 'writeonly', 'xor');
private const
DEFAULT_KEYWORD_COLOR = SC_RED;
DEFAULT_KEYWORD_BOLD = true;
DEFAULT_STRING_COLOR = SC_BLUE;
DEFAULT_NUMBER_COLOR = SC_BLUE;
DEFAULT_COMMENT_COLOR = SC_GREEN;
DEFAULT_COMPILER_DIRECTIVE_COLOR = SC_RED;
private const
CSS_CLASS_DEFAULT = 0;
CSS_CLASS_KEYWORD = 1;
CSS_CLASS_STRING = 2;
CSS_CLASS_NUMBER = 3;
CSS_CLASS_COMMENT = 4;
CSS_CLASS_COMPILER_DIRECTIVE = 5;
CSS_CLASS_HIGH = CSS_CLASS_COMPILER_DIRECTIVE;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FKeywordColor: TColor;
FKeywordBold: boolean;
FStringColor: TColor;
FNumberColor: TColor;
FCommentColor: TColor;
FTokens: array of array of TFmtBreak;
FCompilerDirectiveColor: TColor;
procedure SetKeywordColor(const Value: TColor);
procedure SetKeywordBold(const Value: boolean);
procedure SetStringColor(const Value: TColor);
procedure SetNumberColor(const Value: TColor);
procedure SetCommentColor(const Value: TColor);
procedure SetCompilerDirectiveColor(const Value: TColor);
function ParseText(AFromLine: integer = 0;
SingleLinePossibility: boolean = false; ANumLines: integer = 1): integer;
function GetChrKind(ALineIndex, ACol: Integer): TPascalChrKind;
procedure PushTokensDownFrom(ALineIndex: integer);
procedure PushTokensUpFrom(ALineIndex: integer);
public
constructor Create(AOwner: TComponent); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
function GetCSSRules: TCSSRules; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
function GetCache(out ACache: PByte): Integer; override;
function RestoreCache(ACache: PByte; ASize: Integer): Boolean; override;
procedure ClearCache; override;
published
property KeywordColor: TColor read FKeywordColor write SetKeywordColor default DEFAULT_KEYWORD_COLOR;
property KeywordBold: boolean read FKeywordBold write SetKeywordBold default DEFAULT_KEYWORD_BOLD;
property StringColor: TColor read FStringColor write SetStringColor default DEFAULT_STRING_COLOR;
property NumberColor: TColor read FNumberColor write SetNumberColor default DEFAULT_NUMBER_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor default DEFAULT_COMMENT_COLOR;
property CompilerDirectiveColor: TColor read FCompilerDirectiveColor write SetCompilerDirectiveColor default DEFAULT_COMPILER_DIRECTIVE_COLOR;
end;
TAlgoSimFormattingProcessor = class(TFormattingProcessor)
private const
DEFAULT_KEYWORD_COLOR = SC_RED;
DEFAULT_KEYWORD_BOLD = true;
DEFAULT_STRING_COLOR = SC_BLUE;
DEFAULT_NUMBER_COLOR = SC_BLUE;
DEFAULT_COMMENT_COLOR = SC_GREEN;
private const
CSS_CLASS_DEFAULT = 0;
CSS_CLASS_KEYWORD = 1;
CSS_CLASS_STRING = 2;
CSS_CLASS_NUMBER = 3;
CSS_CLASS_COMMENT = 4;
CSS_CLASS_HIGH = CSS_CLASS_COMMENT;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FKeywordColor: TColor;
FKeywordBold: boolean;
FStringColor: TColor;
FNumberColor: TColor;
FCommentColor: TColor;
procedure SetKeywordColor(const Value: TColor);
procedure SetKeywordBold(const Value: boolean);
procedure SetStringColor(const Value: TColor);
procedure SetNumberColor(const Value: TColor);
procedure SetCommentColor(const Value: TColor);
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property KeywordColor: TColor read FKeywordColor write SetKeywordColor default DEFAULT_KEYWORD_COLOR;
property KeywordBold: boolean read FKeywordBold write SetKeywordBold default DEFAULT_KEYWORD_BOLD;
property StringColor: TColor read FStringColor write SetStringColor default DEFAULT_STRING_COLOR;
property NumberColor: TColor read FNumberColor write SetNumberColor default DEFAULT_NUMBER_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor default DEFAULT_COMMENT_COLOR;
end;
THTMLFormattingProcessor = class(TFormattingProcessor)
private type
THTMLChrKind = (ckHtmlUndefined = -1, ckHtmlText, ckHtmlTag, ckHtmlTagName, ckHtmlParam,
ckHtmlValue, ckHtmlComment, ckHtmlDoctype, ckHtmlCssSelector, ckHtmlCssBlockDelim,
ckHtmlCssProperty, ckHtmlCssValue, ckHtmlCssImportant, ckHtmlCssComment,
ckHtmlScript);
TFmtBreak = record
x: integer;
kind: THtmlChrKind;
signature: cardinal;
end;
private const
DEFAULT_TAG_COLOR = SC_BLUE;
DEFAULT_TAG_NAME_COLOR = SC_RED;
DEFAULT_TAG_NAME_BOLD = false;
DEFAULT_PARAM_COLOR = SC_BLUE;
DEFAULT_VALUE_COLOR = SC_GREEN;
DEFAULT_COMMENT_COLOR = SC_GRAY;
DEFAULT_CSS_SELECTOR_COLOR = SC_RED;
DEFAULT_CSS_SELECTOR_BOLD = false;
DEFAULT_CSS_PROPERTY_COLOR = SC_BLUE;
DEFAULT_CSS_VALUE_COLOR = SC_GREEN;
DEFAULT_CSS_COMMENT_COLOR = SC_GRAY;
DEFAULT_CSS_BLOCK_DELIM_COLOR = SC_RED;
DEFAULT_CSS_BLOCK_DELIM_BOLD = false;
DEFAULT_CSS_IMPORTANT_COLOR = SC_INTENSE_RED;
DEFAULT_CSS_IMPORTANT_BOLD = true;
DEFAULT_DOCTYPE_COLOR = SC_GRAY;
DEFAULT_DOCTYPE_BOLD = false;
DEFAULT_DOCTYPE_ITALICS = true;
private const
CSS_CLASS_TEXT = 0;
CSS_CLASS_TAG = 1;
CSS_CLASS_TAG_NAME = 2;
CSS_CLASS_PARAM = 3;
CSS_CLASS_VALUE = 4;
CSS_CLASS_COMMENT = 5;
CSS_CLASS_CSS_SELECTOR = 6;
CSS_CLASS_CSS_PROPERTY = 7;
CSS_CLASS_CSS_VALUE = 8;
CSS_CLASS_CSS_COMMENT = 9;
CSS_CLASS_CSS_BLOCK_DELIM = 10;
CSS_CLASS_CSS_IMPORTANT = 11;
CSS_CLASS_DOCTYPE = 12;
CSS_CLASS_SCRIPT = 13;
CSS_CLASS_HIGH = CSS_CLASS_SCRIPT;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FValueColor: TColor;
FParamColor: TColor;
FTagColor: TColor;
FTagNameColor: TColor;
FTagNameBold: boolean;
FCommentColor: TColor;
FCssSelectorColor: TColor;
FCssSelectorBold: boolean;
FCssPropertyColor: TColor;
FCssValueColor: TColor;
FCssCommentColor: TColor;
FCssBlockDelimColor: TColor;
FCssBlockDelimBold: boolean;
FCssImportantBold: boolean;
FCssImportantColor: TColor;
FDoctypeColor: TColor;
FDoctypeBold: boolean;
FDoctypeItalics: boolean;
FTokens: array of array of TFmtBreak;
procedure SetParamColor(const Value: TColor);
procedure SetTagColor(const Value: TColor);
procedure SetValueColor(const Value: TColor);
function ParseText(AFromLine: integer = 0;
SingleLinePossibility: boolean = false; ANumLines: integer = 1): integer;
function GetChrKind(ALineIndex, ACol: Integer): THtmlChrKind;
procedure SetCommentColor(const Value: TColor);
procedure SetCssBlockDelimBold(const Value: boolean);
procedure SetCssBlockDelimColor(const Value: TColor);
procedure SetCssCommentColor(const Value: TColor);
procedure SetCssImportantBold(const Value: boolean);
procedure SetCssImportantColor(const Value: TColor);
procedure SetCssPropertyColor(const Value: TColor);
procedure SetCssSelectorBold(const Value: boolean);
procedure SetCssSelectorColor(const Value: TColor);
procedure SetCssValueColor(const Value: TColor);
procedure SetDoctypeBold(const Value: boolean);
procedure SetDoctypeColor(const Value: TColor);
procedure SetDoctypeItalics(const Value: boolean);
procedure SetTagNameBold(const Value: boolean);
procedure SetTagNameColor(const Value: TColor);
procedure PushTokensDownFrom(ALineIndex: integer);
procedure PushTokensUpFrom(ALineIndex: integer);
public
constructor Create(AOwner: TComponent); override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property TagColor: TColor read FTagColor write SetTagColor default DEFAULT_TAG_COLOR;
property TagNameColor: TColor read FTagNameColor write SetTagNameColor default DEFAULT_TAG_NAME_COLOR;
property TagNameBold: boolean read FTagNameBold write SetTagNameBold default DEFAULT_TAG_NAME_BOLD;
property ParamColor: TColor read FParamColor write SetParamColor default DEFAULT_PARAM_COLOR;
property ValueColor: TColor read FValueColor write SetValueColor default DEFAULT_VALUE_COLOR;
property CommentColor: TColor read FCommentColor write SetCommentColor default DEFAULT_COMMENT_COLOR;
property CssSelectorColor: TColor read FCssSelectorColor write SetCssSelectorColor default DEFAULT_CSS_SELECTOR_COLOR;
property CssSelectorBold: boolean read FCssSelectorBold write SetCssSelectorBold default DEFAULT_CSS_SELECTOR_BOLD;
property CssPropertyColor: TColor read FCssPropertyColor write SetCssPropertyColor default DEFAULT_CSS_PROPERTY_COLOR;
property CssValueColor: TColor read FCssValueColor write SetCssValueColor default DEFAULT_CSS_VALUE_COLOR;
property CssCommentColor: TColor read FCssCommentColor write SetCssCommentColor default DEFAULT_CSS_COMMENT_COLOR;
property CssBlockDelimColor: TColor read FCssBlockDelimColor write SetCssBlockDelimColor default DEFAULT_CSS_BLOCK_DELIM_COLOR;
property CssBlockDelimBold: boolean read FCssBlockDelimBold write SetCssBlockDelimBold default DEFAULT_CSS_BLOCK_DELIM_BOLD;
property CssImportantColor: TColor read FCssImportantColor write SetCssImportantColor default DEFAULT_CSS_IMPORTANT_COLOR;
property CssImportantBold: boolean read FCssImportantBold write SetCssImportantBold default DEFAULT_CSS_IMPORTANT_BOLD;
property DoctypeColor: TColor read FDoctypeColor write SetDoctypeColor default DEFAULT_DOCTYPE_COLOR;
property DoctypeBold: boolean read FDoctypeBold write SetDoctypeBold default DEFAULT_DOCTYPE_Bold;
property DoctypeItalics: boolean read FDoctypeItalics write SetDoctypeItalics default DEFAULT_DOCTYPE_Italics;
end;
TMediaWikiFormattingProcessor = class(TFormattingProcessor)
private const
DEFAULT_HEADING1_COLOR = SC_BLUE;
DEFAULT_HEADING1_BOLD = true;
DEFAULT_HEADING1_ITALICS = true;
DEFAULT_HEADING2_COLOR = SC_BLUE;
DEFAULT_HEADING2_BOLD = true;
DEFAULT_HEADING2_ITALICS = false;
DEFAULT_HEADING3_COLOR = SC_BLUE;
DEFAULT_HEADING3_BOLD = false;
DEFAULT_HEADING3_ITALICS = true;
DEFAULT_HEADING4_COLOR = SC_BLUE;
DEFAULT_HEADING4_BOLD = false;
DEFAULT_HEADING4_ITALICS = false;
DEFAULT_HEADING5_COLOR = SC_GRAY;
DEFAULT_HEADING5_BOLD = false;
DEFAULT_HEADING5_ITALICS = true;
DEFAULT_HEADING6_COLOR = SC_GRAY;
DEFAULT_HEADING6_BOLD = false;
DEFAULT_HEADING6_ITALICS = false;
DEFAULT_WIKILINK_COLOR = SC_RED;
DEFAULT_EXTLINK_COLOR = SC_RED;
DEFAULT_TEMPLATE_COLOR = SC_GREEN;
DEFAULT_TEMPLATE_NAME_BOLD = true;
DEFAULT_BOLD_BOLD = true;
DEFAULT_ITALICS_ITALICS = true;
DEFAULT_INDENT_COLOR = SC_GRAY;
private const
CSS_CLASS_TEXT = 0;
CSS_CLASS_HEADING1 = 1;
CSS_CLASS_HEADING2 = 2;
CSS_CLASS_HEADING3 = 3;
CSS_CLASS_HEADING4 = 4;
CSS_CLASS_HEADING5 = 5;
CSS_CLASS_HEADING6 = 6;
CSS_CLASS_WIKILINK = 7;
CSS_CLASS_EXTLINK = 8;
CSS_CLASS_TEMPLATE_NAME = 9;
CSS_CLASS_TEMPLATE = 10;
CSS_CLASS_BOLD = 11;
CSS_CLASS_ITALICS = 12;
CSS_CLASS_BOLDITALICS = 13;
CSS_CLASS_INDENT = 14;
CSS_CLASS_HIGH = CSS_CLASS_INDENT;
CSS_CLASS_LENGTH = CSS_CLASS_HIGH + 1;
private var
FHeading4Color: TColor;
FHeading1Italics: boolean;
FHeading4Italics: boolean;
FHeading2Bold: boolean;
FHeading3Bold: boolean;
FHeading1Bold: boolean;
FHeading4Bold: boolean;
FHeading2Color: TColor;
FHeading3Color: TColor;
FHeading1Color: TColor;
FHeading2Italics: boolean;
FHeading3Italics: boolean;
FWikilinkColor: TColor;
FTemplateColor: TColor;
FBoldBold: boolean;
FItalicsItalics: boolean;
FExtlinkColor: TColor;
FIndentColor: TColor;
FTemplateNameBold: boolean;
FHeading5Color: TColor;
FHeading5Italics: boolean;
FHeading5Bold: boolean;
FHeading6Italics: boolean;
FHeading6Bold: boolean;
FHeading6Color: TColor;
procedure SetHeading1Bold(const Value: boolean);
procedure SetHeading1Color(const Value: TColor);
procedure SetHeading1Italics(const Value: boolean);
procedure SetHeading2Bold(const Value: boolean);
procedure SetHeading2Color(const Value: TColor);
procedure SetHeading2Italics(const Value: boolean);
procedure SetHeading3Bold(const Value: boolean);
procedure SetHeading3Color(const Value: TColor);
procedure SetHeading3Italics(const Value: boolean);
procedure SetHeading4Bold(const Value: boolean);
procedure SetHeading4Color(const Value: TColor);
procedure SetHeading4Italics(const Value: boolean);
procedure SetWikilinkColor(const Value: TColor);
procedure SetTemplateColor(const Value: TColor);
procedure SetBoldBold(const Value: boolean);
procedure SetItalicsItalics(const Value: boolean);
procedure SetExtlinkColor(const Value: TColor);
procedure SetIndentColor(const Value: TColor);
procedure SetTemplateNameBold(const Value: boolean);
procedure SetHeading5Bold(const Value: boolean);
procedure SetHeading5Color(const Value: TColor);
procedure SetHeading5Italics(const Value: boolean);
procedure SetHeading6Bold(const Value: boolean);
procedure SetHeading6Color(const Value: TColor);
procedure SetHeading6Italics(const Value: boolean);
public
constructor Create(AOwner: TComponent); override;
function GetCSSRules: TCSSRules; override;
function GetCharCSSClass(ALineIndex: Integer; ACol: Integer;
AChar: Char): Integer; override;
procedure GetCharFormat(ALineIndex: Integer; ACol: Integer; AChar: Char;
var AFontRecord: TFontRecord); override;
function FileChangeNotification(ChangeType: TChangeType; Data1: Integer;
Data2: Integer; Data3: Integer; Data4: Integer): TChangeRecord; override;
procedure Assign(Source: TPersistent); override;
procedure ApplyColorScheme(const AColorScheme: TColorScheme); override;
published
property Heading1Color: TColor read FHeading1Color write SetHeading1Color default DEFAULT_HEADING1_COLOR;
property Heading1Bold: boolean read FHeading1Bold write SetHeading1Bold default DEFAULT_HEADING1_BOLD;
property Heading1Italics: boolean read FHeading1Italics write SetHeading1Italics default DEFAULT_HEADING1_BOLD;
property Heading2Color: TColor read FHeading2Color write SetHeading2Color default DEFAULT_HEADING2_COLOR;
property Heading2Bold: boolean read FHeading2Bold write SetHeading2Bold default DEFAULT_HEADING2_BOLD;
property Heading2Italics: boolean read FHeading2Italics write SetHeading2Italics default DEFAULT_HEADING2_BOLD;
property Heading3Color: TColor read FHeading3Color write SetHeading3Color default DEFAULT_HEADING3_COLOR;
property Heading3Bold: boolean read FHeading3Bold write SetHeading3Bold default DEFAULT_HEADING3_BOLD;
property Heading3Italics: boolean read FHeading3Italics write SetHeading3Italics default DEFAULT_HEADING3_BOLD;
property Heading4Color: TColor read FHeading4Color write SetHeading4Color default DEFAULT_HEADING4_COLOR;
property Heading4Bold: boolean read FHeading4Bold write SetHeading4Bold default DEFAULT_HEADING4_BOLD;
property Heading4Italics: boolean read FHeading4Italics write SetHeading4Italics default DEFAULT_HEADING4_BOLD;
property Heading5Color: TColor read FHeading5Color write SetHeading5Color default DEFAULT_HEADING5_COLOR;
property Heading5Bold: boolean read FHeading5Bold write SetHeading5Bold default DEFAULT_HEADING5_BOLD;
property Heading5Italics: boolean read FHeading5Italics write SetHeading5Italics default DEFAULT_HEADING5_BOLD;
property Heading6Color: TColor read FHeading6Color write SetHeading6Color default DEFAULT_HEADING6_COLOR;
property Heading6Bold: boolean read FHeading6Bold write SetHeading6Bold default DEFAULT_HEADING6_BOLD;
property Heading6Italics: boolean read FHeading6Italics write SetHeading6Italics default DEFAULT_HEADING6_BOLD;
property WikilinkColor: TColor read FWikilinkColor write SetWikilinkColor default DEFAULT_WIKILINK_COLOR;
property ExtlinkColor: TColor read FExtlinkColor write SetExtlinkColor default DEFAULT_EXTLINK_COLOR;
property TemplateColor: TColor read FTemplateColor write SetTemplateColor default DEFAULT_TEMPLATE_COLOR;
property TemplateNameBold: boolean read FTemplateNameBold write SetTemplateNameBold default DEFAULT_TEMPLATE_NAME_BOLD;
property BoldBold: boolean read FBoldBold write SetBoldBold default DEFAULT_BOLD_BOLD;
property ItalicsItalics: boolean read FItalicsItalics write SetItalicsItalics default DEFAULT_ITALICS_ITALICS;
property IndentColor: TColor read FIndentColor write SetIndentColor default DEFAULT_INDENT_COLOR;
end;
TPrintSettings = class(TPersistent)
strict private var
FVerticalMargin: integer;
FHorizontalMargin: integer;
FWordWrap: boolean;
FNiceWordWrap: boolean;
FWordWrapChar: char;
FShowWordWrapIcon: boolean;
FWordWrapIconColor: TColor;
public const
DEFAULT_VERTICAL_MARGIN = 200;
DEFAULT_HORIZONTAL_MARGIN = 220;
DEFAULT_WORD_WRAP = true;
DEFAULT_NICE_WORD_WRAP = true;
DEFAULT_WORD_WRAP_CHAR = '↳';
DEFAULT_SHOW_WORD_WRAP_ICON = false;
DEFAULT_WORD_WRAP_ICON_COLOR = clBlack;
public
constructor Create;
procedure Assign(Source: TPersistent); override;
published
property VerticalMargin: integer read FVerticalMargin write FVerticalMargin default DEFAULT_VERTICAL_MARGIN;
property HorizontalMargin: integer read FHorizontalMargin write FHorizontalMargin default DEFAULT_HORIZONTAL_MARGIN;
property WordWrap: boolean read FWordWrap write FWordWrap default DEFAULT_WORD_WRAP;
property NiceWordWrap: boolean read FNiceWordWrap write FNiceWordWrap default DEFAULT_NICE_WORD_WRAP;
property WordWrapIcon: char read FWordWrapChar write FWordWrapChar default DEFAULT_WORD_WRAP_CHAR;
property ShowWordWrapIcon: boolean read FShowWordWrapIcon write FShowWordWrapIcon default DEFAULT_SHOW_WORD_WRAP_ICON;
property WordWrapIconColor: TColor read FWordWrapIconColor write FWordWrapIconColor default DEFAULT_WORD_WRAP_ICON_COLOR;
end;
TProgressStartEvent = procedure(Sender: TObject; NumSteps: integer) of object;
TProgressEvent = function(Sender: TObject; CurStep: integer; NumSteps: integer): boolean of object;
TProgressCompleteEvent = TNotifyEvent;
TNotificationMessage = procedure(Sender: TObject; MsgID: cardinal; AClear: boolean = false) of object;
TSimpleNotificationMessage = procedure(Sender: TObject; MsgID: cardinal; const AStr: string) of object;
TGraphicControlCracker = type TGraphicControl;
TBorderType = (btNone, btWin32ThinLine, btWin32SunkenEdge, btThemeBorder,
btSimpleColor);
TTextFileOwner = (tfoEditor, tfoApplication);
TSelectionBarBehaviour = (sbbAlwaysSelect, sbbNeverSelect, sbbAuto, sbbAutoMixed);
TCliGetPromptClassEvent = procedure(Sender: TObject; var AClassName: string) of object;
TCliInputEvent = procedure(Sender: TObject; const AInput: string; var NewPrompt: boolean) of object;
TParamType = (ptConstant, ptCommand);
TScriptParam = record
ParamType: TParamType;
ParamValue: integer;
end;
TEditorCommand = record
Verb: integer;
Param1,
Param2,
Param3,
Param4: TScriptParam;
end;
TEditorScript = array of TEditorCommand;
function MakeEditorCommand(Verb: integer; Param1: integer = 0;
ParamType1: TParamType = ptConstant; Param2: integer = 0;
ParamType2: TParamType = ptConstant; Param3: integer = 0;
ParamType3: TParamType = ptConstant; Param4: integer = 0;
ParamType4: TParamType = ptConstant): TEditorCommand;
const
MultiCharHyphen: array[0..6] of char = (#$002D, #$2010, #$2011, #$00AD, #$2013, #$2014, #$2212);
MultiCharAsterisk: array[0..4] of char = (#$002A, #$2022, #$22C5, #$00D7, #$2219);
MultiCharDoubleQuote: array[0..5] of char = (#$0022, #$201C, #$201D, #$201E, #$00BB, #$00AB);
MultiCharSingleQuote: array[0..5] of char = (#$0027, #$2018, #$2019, #$201A, #$203A, #$2039);
type
TScrollBehaviour = (sbDefault, sbLine, sbPixel);
TTextEditor = class;
TTextEditorDataObject = class(TInterfacedObject, IDataObject)
strict private type
TEnumFormatEtc = class(TInterfacedObject, IEnumFORMATETC)
strict private
FIndex: integer;
public
function Next(celt: Longint; out elt;
pceltFetched: PLongint): HResult; stdcall;
function Skip(celt: Longint): HResult; stdcall;
function Reset: HResult; stdcall;
function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
end;
public const
FMT_UNICODETEXT = 0;
class var
Formats: TFormatEtcArray;
private
FTextEditor: TTextEditor;
FBuffer: string;
function GetMatchingFormatIdx(const AFormatEtc: TFormatEtc): integer;
public
class constructor ClassCreate;
class function CreateHGlobal(Data: pointer; Len: UInt64; uFlags: DWORD;
out hGlobal: HGLOBAL): HRESULT; static;
constructor Create(AEditor: TTextEditor);
function DAdvise(const formatetc: tagFORMATETC; advf: Integer;
const advSink: IAdviseSink; out dwConnection: Integer): HRESULT; stdcall;
function DUnadvise(dwConnection: Integer): HRESULT; stdcall;
function EnumDAdvise(out enumAdvise: IEnumSTATDATA): HRESULT; stdcall;
function EnumFormatEtc(dwDirection: Integer;
out enumFormatEtc: IEnumFORMATETC): HRESULT; stdcall;
function GetCanonicalFormatEtc(const formatetc: tagFORMATETC;
out formatetcOut: tagFORMATETC): HRESULT; stdcall;
function GetData(const formatetcIn: tagFORMATETC;
out medium: tagSTGMEDIUM): HRESULT; stdcall;
function GetDataHere(const formatetc: tagFORMATETC;
out medium: tagSTGMEDIUM): HRESULT; stdcall;
function QueryGetData(const formatetc: tagFORMATETC): HRESULT; stdcall;
function SetData(const formatetc: tagFORMATETC; var medium: tagSTGMEDIUM;
fRelease: LongBool): HRESULT; stdcall;
end;
TTextEditor = class(TCustomControl, IDropTarget, IDropSource)
private type
TTextEditorRegion = (terText, terSelectionBar);
public const
DEFAULT_LINE_HIGHLIGHT_COLOR = $00EEEEEE;
DEFAULT_BRACKET_HIGHLIGHT_COLOR = $0077D9F5;
DEFAULT_RULER_WIDTH = 60;
DEFAULT_MARGIN_LEFT = 80;
DEFAULT_MARGIN_TOP = 4;
DEFAULT_MARGIN_RIGHT = 4;
DEFAULT_MARGIN_BOTTOM = 4;
DEFAULT_NOTIFICATION_MSG_DURATION = 5000;
public const
EN_NULL = 0;
EN_DRAG_MOVE = 1;
EN_DRAG_COPY = 2;
EN_READ_ONLY_ERROR = 3;
EN_INPUT_ERROR = 4;
EN_PRINTING = 5;
EN_SCROLL_MODE = 6;
EN_SCRIPT = 7;
EN_MULTICHAR = 8;
EN_READONLY = 9;
EN_MULTICARET = 10;
EN_MAX = 10;
private const
FNotificationStrs: array[0..EN_MAX] of string =
('',
SNotifyDragMove,
SNotifyDragCopy,
SNotifyReadOnlyError,
SNotifyInputError,
SNotifyPrinting,
SNotifyScrollMode,
SNotifyScript,
SNotifyMultiCharSelect,
SNotifyReadOnlyMode,
SNotifyMultiCaretMode);
private const
EDITOR_NOTIFY = $10000;
private const
WM_MOUSEHWHEEL = $020E;
private var
FTextFile: TTextFile;
FClassArray: TClassArray;
FBkColor: TColor;
FFgColor: TColor;
FSelBkColor: TColor;
FSelFgColor: TColor;
FFndBkColor: TColor;
FFndFgColor: TColor;
FUseSystemColors: boolean;
FForegroundColor: TColor;
FBackgroundColor: TColor;
FFontSize: TSize;
FFont: TFont;
FLetterSpacing: integer;
FLineSpacing: integer;
FAutoIndent: boolean;
FHandleHotkeys: boolean;
FHandleBookmarkHotkeys: boolean;
FSelForegroundColor: TColor;
FSelBackgroundColor: TColor;
FOnSelChange: TNotifyEvent;
FOnChange: TNotifyEvent;
FBeepOnInputError: boolean;
FErrorMessageOnReadOnlyError: boolean;
FOverwrite: boolean;
FOLEDragging: boolean;
FOLEInternalDrop: boolean;
FDropLocation: TPoint;
FLastDropEffect: integer;
FDoubleClicking: Boolean;
FIndentSize: integer;
FScrollPos: TPoint;
FPrevCursorX, FPrevCursorY: integer;
FMouseDownX, FMouseDownY: integer;
FShowHiddenCharacters: boolean;
FOnModified: TNotifyEvent;
FLineHighlight: boolean;
FLineHighlightColor: TColor;
FOldCaretPosY: integer;
FMatchBrackets: boolean;
FBracketHighlight: boolean;
FBracketPos1, FBracketPos2: TPoint;
FBracketHighlightColor: TColor;
FAutoReplace: boolean;
FPopupMenu: TPopupMenu;
FRulerMenu: TPopupMenu;
FImagePopup: TPopupMenu;
FTypeTimer: TTimer;
FMessageInterface: boolean;
FInputTransform: TInputTransform;
FStartOver: boolean;
FGLYPHBM: TBitmap;
FFONTBM: TBitmap;
FFallbackFonts: TStringList;
FGlyphSets: array of PGlyphSet;
FUnicodeFallback: boolean;
FPasswordChar: char;
FNumbersOnly: boolean;
FHintWindow: HWND;
FToolInfo: TToolInfo;
FBalloonPoint: TPoint;
FBalloonPersistence: TBalloonPersistence;
FBalloonTimer: TTimer;
FTabLength: integer;
FLabelStyle: boolean;
FLabelEllipsis: boolean;
FBlinkRemover: TTimer;
FAutoHeight: boolean;
FMultiSize: boolean;
FCurrentFormat: TFontRecord;
FFontSizes: array of TSize;
FAccumLineHeights: array of integer;
FCachedHorizontalExtent: integer;
FLineControls: array of TLineControlRecord;
FNextControlID: cardinal;
FOnBookmarksMoved: TNotifyEvent;
FFormattingProcessor: TFormattingProcessor;
FRulerWidth,
FMarginLeft,
FMarginRight,
FMarginTop,
FMarginBottom: integer;
FRegion: TTextEditorRegion;
FSelectionBarInitialLine: integer;
FRulerFont: TFont;
FCaretVisible: boolean;
FNoScrollToCaret: boolean;
FRulerColor: TColor;
FZoom: integer;
FOnZoomChange: TNotifyEvent;
FPrintSettings: TPrintSettings;
FOnPrintProgress: TProgressEvent;
FOnPrintEnd: TProgressCompleteEvent;
FOnPrintBegin: TProgressStartEvent;
FRightLineColor: TColor;
FRightLinePos: integer;
FRightLine: boolean;
FBorderColor: TColor;
FBorderType: TBorderType;
FTextFileOwner: TTextFileOwner;
FRulerPopupMenu: TPopupMenu;
FSelectionBarBehaviour: TSelectionBarBehaviour;
FNotifications: array of integer;
FOnNotification: TNotificationMessage;
FOnSimpleNotification: TSimpleNotificationMessage;
FScrollMode: boolean;
FNotifyMsgDuration: integer;
FOnCliGetPromptClass: TCliGetPromptClassEvent;
FOnCliInput: TCliInputEvent;
FScriptRunning: Boolean;
FScriptCounter: integer;
FAbortScript: Boolean;
FDesiredColumn: integer;
FPreserveDesiredColumn: boolean;
FCliHistory: array of string;
FCliHistoryIndex: integer;
FListBoxMode: boolean;
FOnListBoxChange: TNotifyEvent;
FOnListBoxSelect: TNotifyEvent;
FValidPaintState: boolean;
FCliMultiOutput: boolean;
FMultiCharSelect: boolean;
FMultiCharSelectDlgFrm: TForm;
FMultiCharReportView: boolean;
Flv: HWND;
FMultiCharSelectDlgDefaultWndProc: TWndMethod;
FASHyphenAsteriskToggle: boolean;
FNoVerifyFont: boolean;
FDisabledEffect: TBitmapEffect;
FBitmapEffect: TBitmapEffect;
FRepeatExNum: integer;
FRepeatExCommand: integer;
FOnFindDataClear: TNotifyEvent;
FOnOverwriteChange: TNotifyEvent;
FVisualUpdateLock: integer;
FScrollBehaviour: TScrollBehaviour;
FSPIScrollLines: integer;
FCaretAfterEOL: boolean;
FMultipleCarets: boolean;
FCarets: TPointArray;
FAllowBitmapPaste: boolean;
FWantTab, FWantReturn: boolean;
FDragDataObj: IDataObject;
FDragCompatFmt: boolean;
FRightDrag: boolean;
FInsertionPoint: TPoint;
FDropMenu: TPopupMenu;
FDropMenuMove, FDropMenuCopy: TMenuItem;
FDropTargetHelper: IDropTargetHelper;
FExpectDragDrop: boolean;
FDragButton: TMouseButton;
FDragButtonOLE: integer;
FMouseContSel: boolean;
FPDict: TDictionary<string, TFormattingProcessor>;
FDragScrollFirstChance: UInt64;
FXDRAG, FYDRAG: integer;
procedure SetUseSystemColors(const Value: boolean);
procedure SetupColors;
procedure SetBackgroundColor(const Value: TColor);
procedure SetForegroundColor(const Value: TColor);
procedure SetupFontMetrics;
procedure SetFont(const Value: TFont);
procedure DrawLine(LineIndex: Integer; From, ATo: integer; AForceFindHighlight: boolean = false); overload;
procedure DrawSpan(const ATextSpan: TTextSpan; AForceFindHighlight: boolean = false);
procedure ApplyFont(const AClassName: string; ATo: TCanvas = nil);
procedure ReapplyFont(ATo: TCanvas = nil); inline;
procedure FontChange(Sender: TObject);
procedure SetLetterSpacing(const Value: integer);
procedure SetLineSpacing(const Value: integer);
procedure TextFileChange(Sender: TObject; ChangeType: TChangeType; Data1,
Data2, Data3, Data4: Integer);
procedure TextFileCaretPosSelChange(Sender: TObject; ChangeType: TChangeType; Data1,
Data2, Data3, Data4: Integer);
procedure TextFileCaretPosChange(Sender: TObject);
procedure SetCaretAfterEOL(const Value: boolean);
procedure TextFileInputError(Sender: TObject);
procedure SetAutoIndent(const Value: boolean);
function GetText: string;
procedure SetText(const Value: string);
procedure SetSelBackgroundColor(const Value: TColor);
procedure SetSelForegroundColor(const Value: TColor);
procedure ApplyInteractiveFormatting(const X, Y: integer; ATo: TCanvas = nil);
procedure ApplyCharacterColors(const X, Y: integer; AForceFindHighlight: boolean = false);
function GetCaretPos: TPoint;
function GetSelEndPos: TPoint;
procedure SetCaretPos(const Value: TPoint);
procedure SetSelEndPos(const Value: TPoint);
function GetSelType: TSelectionType;
procedure SetSelType(const Value: TSelectionType);
procedure VisualUpdate(ChangeType: TChangeType; Data1, Data2, Data3, Data4: integer);
procedure UpdateCaret;
function GetSelText: string;
procedure ChangeCursor(Shift: TShiftState; Y: Integer; X: Integer); overload;
procedure ChangeCursor(Shift: TShiftState); overload;
procedure ChangeCursor; overload;
procedure SetIndentSize(const Value: integer);
function GetSelLength: integer;
function SafeSelLength: integer;
procedure SetSelLength(const Value: integer);
procedure UpdateScrollBars;
procedure SetScrollPosY(Value: integer; Lim: boolean = false);
procedure SetScrollPosX(Value: integer);
function FirstVisibleLine(TrueValue: boolean = false): integer;
function LastVisibleLine(TrueValue: boolean = false): integer;
procedure DrawVisibleLine(LineIndex: Integer; From: Integer = 0);
function ScrollToCaret: boolean;
procedure SetScrollPosXY(X, Y: integer; Lim: boolean = false);
procedure Escape(AAll: boolean = false);
procedure SetEditMode(const Value: TEditMode);
procedure SetShowHiddenCharacters(const Value: boolean);
function Reveal(const C: char): char;
procedure TextFileModified(Sender: TObject);
procedure SetLineHighlight(const Value: boolean);
procedure SetLineHighlightColor(const Value: TColor);
procedure SetMatchBrackets(const Value: boolean);
function IsBracketHighlight(const X, Y: integer): boolean; inline;
procedure SetBracketHighlightColor(const Value: TColor);
procedure MenuPopup(Sender: TObject);
procedure MenuItemMessage(Sender: TObject);
function GetSelStart: integer;
procedure SetSelStart(const Value: integer);
procedure SetOverwrite(const Value: boolean);
procedure TypeTimerTimer(Sender: TObject);
procedure PostType;
procedure SetFindBackgroundColor(const Value: TColor);
procedure SetFindForegroundColor(const Value: TColor);
procedure SelectFindItem(ItemIndex: integer);
procedure SetSingleLine(const Value: boolean);
function GetSingleLine: boolean;
function GetFontChrs(const AFontName: TFontName; out GlyphSet: PGlyphSet): boolean;
function ChrInGlyphSet(GlyphSet: PGlyphSet; Codepoint: integer): boolean; overload;
function ChrInGlyphSet(GlyphSet: PGlyphSet; Character: char): boolean; overload; inline;
procedure UseBestFont(const AChar: Char);
procedure SetFallbackFonts(const Value: TStringList);
procedure FallbackFontsChange(Sender: TObject);
procedure BuildFontDataArray;
procedure FreeFontDataArray;
procedure SetUnicodeFallback(const Value: boolean);
procedure SetPasswordChar(const Value: char);
function GetBalloonPosition: TPoint;
procedure BalloonTimerTimer(Sender: TObject);
procedure SetLabelStyle(const Value: boolean);
procedure SetLabelEllipsis(const Value: boolean);
procedure BlinkBracket;
procedure BlinkRemoverTimer(Sender: TObject);
procedure SetBracketHighlight(const PointA, PointB: TPoint);
procedure ClearBracketHighlight;
procedure HighlightCurrentBracket;
procedure SetAutoHeight(const Value: boolean);
procedure AdjustHeight;
procedure SetMultiSize(const Value: boolean);
function GetClassRecord(Index: integer): TClassRecord;
function GetNumClasses: integer;
procedure UpdateFontBoxSize(ClassIndex: integer);
procedure UpdateFontBoxSizes;
procedure TextFileLineChange(Sender: TObject;
LineChangeType: TLineChangeType; From: integer);
procedure RebuildLineCache;
procedure DoSetCaretPos; inline;
function GetTotalVerticalExtent: integer;
function GetTotalHorizontalExtent: integer;
procedure RecomputeHorizontalExtent;
function GetControlFromID(ID: integer): TControl;
function GetIDFromControl(AControl: TControl): integer;
function GetControlIDFromLine(LineIndex: integer): integer;
function GetLineFromControlID(ID: integer): integer;
function GetLineControlSize(LineIndex: integer): TSize;
procedure ClearControls;
procedure UpdateLineControls;
procedure FixRemovedLineControlLines;
function LineIsControl(LineIndex: integer): boolean;
function LineIsWinControlOrHasPopup(LineIndex: integer): boolean;
function GetControlFromLine(LineIndex: integer): TControl;
function LineWidths(LineIndex: integer): integer;
function MaxLineWidth: integer;
procedure TextFileLineClassChange(Sender: TObject; LineIndex: integer);
procedure TextFileControlRemoved(Sender: TObject; ControlID: integer);
procedure TextFileGetControlText(Sender: TObject; LineIndex: integer;
var ControlText: string);
procedure InvalidateLineControl(LineIndex: integer);
function GetLineTop(LineIndex: integer): integer;
function GetLineBottom(LineIndex: integer): integer;
function GetLineBottomVirtual(LineIndex: integer): integer;
function GetCharLeft(LineIndex, ColIndex: integer): integer;
function GetCharRight(LineIndex, ColIndex: integer): integer;
function ActivateControl: HWND;
procedure ImageMenuCommand(Sender: TObject);
function GetLine(Index: integer): string;
procedure SetLine(Index: integer; const Value: string);
function GetClass(Index: integer): string;
procedure SetClass(Index: integer; const Value: string);
procedure ForceSetClass(Index: integer; const Value: string);
function GetLineCount: integer;
function FileIsEmpty: boolean;
procedure GotoSamePixelAtPrevLine(Shift: boolean);
procedure GotoSamePixelAtNextLine(Shift: boolean);
function GetBookmark(Index: integer): TPoint;
function GetBookmarkCount: integer;
function GetUsedBookmarkCount: integer;
procedure TextFileBookmarksMoved(Sender: TObject);
function GetBookmarkDescr(BookmarkIndex: integer): string;
procedure BookmarkHistoryRecord(const APoint: TPoint);
procedure SetFormattingProcessor(const Value: TFormattingProcessor;
AInitialize: boolean = true);
procedure FormattingProcessorChanged(Sender: TObject);
function FormattingProcessorGetLineWidth(ALineIndex: integer): integer;
function FormattingProcessorGetChar(ALineIndex, ACol: integer): char;
function FormattingProcessorGetLineCount: integer;
function FormattingProcessorGetWord(const APoint: TPoint;
APascalIdent: boolean = false): string;
function FormattingProcessorGetWordBoundary(const APoint: TPoint; out SP,
EP: integer): boolean;
function FPFileChangeNotification(ChangeType: TChangeType; Data1, Data2,
Data3, Data4: Integer): TChangeRecord;
function TextContentRect: TRect;
function NonRulerRect: TRect;
function RulerRect: TRect;
function LeftColumnRect: TRect;
procedure DrawRuler;
procedure RulerFontChange(Sender: TObject);
procedure UpdateRuler;
procedure UpdateRulerLine(const ALineIndex: integer);
procedure BinaryHideCaret;
procedure BinaryShowCaret;
procedure SetMarginBottom(const Value: integer);
procedure SetMarginLeft(const Value: integer);
procedure SetMarginRight(const Value: integer);
procedure SetMarginTop(const Value: integer);
procedure SetRulerWidth(const Value: integer);
function GetRulerVisible: boolean;
procedure SetRulerVisible(const Value: boolean);
procedure SetRulerColor(const Value: TColor);
procedure SetZoom(const Value: integer);
procedure MoveBalloonPostScroll;
procedure SetRightLine(const Value: boolean);
procedure SetRightLineColor(const Value: TColor);
procedure SetRightLinePos(const Value: integer);
procedure SetBorderColor(const Value: TColor);
procedure SetBorderType(const Value: TBorderType);
function GetWrapAt: string;
procedure SetWrapAt(const Value: string);
function GetFalse: boolean;
procedure RestoreWrapAt(const Value: boolean);
procedure SetTextFile(const Value: TTextFile);
procedure ConnectTextFileToEditor;
procedure DisconnectTextFileFromEditor;
function GetEditMode: TEditMode;
procedure SetFormattingProcessorSmple(const Value: TFormattingProcessor);
procedure RulerMenuCommand(Sender: TObject);
procedure RulerPropertiesApply(Sender: TObject);
function GetFunctionalSelectionBarWidth: integer;
function CharAtVirtualPixelEx(Pixel: TPoint; const CP: boolean = false): TPoint;
function CharAtPhysicalPixelEx(Pixel: TPoint; const CP: boolean = false): TPoint;
function NotifyApp(const MsgID: integer): boolean;
function NotifyAppWithTimer(const MsgID: integer): boolean;
procedure RemoveNotification(const MsgID: integer);
function GetNotification(AIndex: integer): integer;
function GetNotificationCount: integer;
function GetNotificationStr(MsgID: integer): string;
procedure TextFileReadOnlyError(Sender: TObject);
procedure UpdateScrollMode;
function GetLineComparer: TLineComparer;
procedure SetLineComparer(const Value: TLineComparer);
function GetSortReverseOrder: boolean;
procedure SetSortReverseOrder(const Value: boolean);
function CliHistoryUp: boolean;
function CliHistoryDown: boolean;
function GetCliHistory(Index: integer): string;
procedure SetCliHistory(Index: integer; const Value: string);
function GetCliHistoryCount: integer;
function GetCliHistoryIndex: integer;
procedure SetListBoxMode(const Value: boolean);
procedure SetListBoxItemIndex(const Value: integer);
function GetListBoxItemIndex: integer;
procedure CliHistoryDialogListBoxSelect(Sender: TObject);
procedure NeedValidPaintState;
procedure CliHistoryDialogListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure DoMultiCharSelect(AChrs: array of char);
procedure MultiCharSelectDlgResize(Sender: TObject);
procedure MultiCharSelectDlgWndProc(var Message: TMessage);
procedure MultiCharSelectDlgActivate(Sender: TObject);
function CharInSet(AChar: char; ASet: array of char): boolean;
function CharInAnyMultiCharSet(AChar: char): boolean;
procedure VerifyFont;
procedure SetDisabledEffect(const Value: TBitmapEffect);
procedure SetBitmapEffect(const Value: TBitmapEffect);
procedure TextFileFindDataClear(Sender: TObject);
procedure CheckCaretBeyondEOL;
procedure TextFileLockVisualUpdates(Sender: TObject);
procedure TextFileUnlockVisualUpdates(Sender: TObject);
procedure UpdateSPI;
procedure DoAutoReplace;
function GetCaretAfterEOL: boolean;
procedure CreateNewCaretAt(const APoint: TPoint);
procedure EnterMultiCaretMode;
function GetLastMultiCaret: TPoint;
function IsCaretVisible: boolean;
procedure IndicateInsertionPoint(const APoint: TPoint);
procedure RemoveInsertionPoint;
{$HINTS OFF}
procedure InvalidateChar(const AChar: TPoint);
{$HINTS ON}
procedure InvalidateCharAndPrev(const AChar: TPoint);
procedure GetDragDropEffect(var dwEffect: Integer; grfKeyState: Integer);
procedure DragDropNotify(dwEffect: Integer);
function FPFromString(const FPClassName: string): TFormattingProcessor;
protected
procedure Paint; override;
procedure KeyPress(var Key: Char); override;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer;
Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X: Integer; Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X: Integer;
Y: Integer); override;
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
procedure DblClick; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
procedure WMMouseHWheel(var Message: TWMMouseWheel); message WM_MOUSEHWHEEL;
procedure WndProc(var Message: TMessage); override;
procedure Loaded; override;
procedure CreateWnd; override;
procedure DestroyWnd; override;
procedure WMEnable(var Message: TWMEnable); message WM_ENABLE;
procedure WMContextMenu(var Message: TWMContextMenu);
message WM_CONTEXTMENU;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
procedure WMNCActivate(var Message: TWMNCActivate); message WM_NCACTIVATE;
procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
function IDropTarget.DragEnter = DropTargetDragEnter;
function DropTargetDragEnter(const dataObj: IDataObject;
grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HRESULT;
stdcall;
function IDropTarget.DragOver = DropTargetDragOver;
function DropTargetDragOver(grfKeyState: Longint; pt: TPoint;
var dwEffect: Longint): HRESULT;
stdcall;
function IDropTarget.DragLeave = DropTargetDragLeave;
function DropTargetDragLeave: HRESULT;
stdcall;
function IDropTarget.Drop = DropTargetDrop;
function DropTargetDrop(const dataObj: IDataObject; grfKeyState:
Longint; pt: TPoint; var dwEffect: Longint): HRESULT; stdcall;
function GiveFeedback(dwEffect: Longint): HRESULT; stdcall;
function QueryContinueDrag(fEscapePRessed: BOOL; grfKeyState: Longint): HRESULT;
stdcall;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure UseDefaultFallbackFonts;
function EditorCommand(Command: integer; Param1: integer = 0;
Param2: integer = 0; Param3: integer = 0; Param4: integer = 0): integer;
function CommandEnabled(Command: integer): boolean;
function CommandVisible(Command: integer): boolean;
procedure BeginVisualUpdate;
procedure EndVisualUpdate(AUpdate: boolean = false);
procedure CutToClipboard;
procedure CopyToClipboard;
procedure CopyAll;
function PasteFromClipboard: boolean;
function PasteFromClipboardAsBlock: boolean;
procedure ClearLine(LineIndex: integer); overload;
procedure ClearLine; overload;
procedure AddLine(const AText: string; const AClassName: string); overload;
procedure AddLine(const AText: string); overload;
procedure AddLine; overload;
procedure BeginAddLine;
procedure EndAddLine;
procedure InsertLine(const AText: string; const AClassName: string; LineIndex: integer); overload;
procedure InsertLine(const AText: string; LineIndex: integer); overload;
procedure InsertLine(LineIndex: integer); overload;
procedure InsertChar(const AChar: Char; AOverwrite: boolean = false);
procedure InsertText(const AText: string);
procedure InsertTextAsBlock(const AText: string);
procedure SurroundText(const APrefix, APostfix: string);
procedure TransformText(Transformation: TTextTransformFunc;
const TransformName: string);
function TransformSelection(Transformation: TTextTransformFunc;
const TransformName: string): boolean;
procedure ChrTransformText(Transformation: TChrTransformFunc;
const TransformName: string);
function ChrTransformSelection(Transformation: TChrTransformFunc;
const TransformName: string): boolean;
function FillWithChar(const AChar: char): boolean;
property TextFile: TTextFile read FTextFile write SetTextFile;
property CaretPos: TPoint read GetCaretPos write SetCaretPos;
property SelEndPos: TPoint read GetSelEndPos write SetSelEndPos;
property SelectionType: TSelectionType read GetSelType write SetSelType;
function GetWordBoundary(const Point: TPoint; out StartPos, EndPos: integer): boolean; overload;
function GetWordBoundary(out StartPos, EndPos: integer): boolean; overload;
function GetWord(const Point: TPoint): string; overload;
function GetWord: string; overload;
function GetURLAtCaret(out AURL: string): boolean;
function OpenURLAtCaret: boolean;
function SelectWord: boolean;
procedure SwapLinesAbove;
procedure SwapLinesBelow;
procedure SelectLines(const ALineA, ALineB: integer);
procedure SelectLine(ALineIndex: integer); overload;
procedure SelectLine; overload;
procedure SelectAll;
procedure SelectNone;
procedure SelectAllNone;
procedure Backspace(Word: boolean = false);
procedure Delete(Word: boolean = false);
procedure Return;
procedure ReplaceCodepoint;
function CharAtVirtualPixel(Pixel: TPoint): TPoint;
function CharAtPhysicalPixel(Pixel: TPoint): TPoint;
function CaretPosAtVirtualPixel(Pixel: TPoint): TPoint;
function CaretPosAtPhysicalPixel(Pixel: TPoint): TPoint;
function VirtualPixelAtChar(const Point: TPoint): TPoint;
function PhysicalPixelAtChar(const Point: TPoint): TPoint;
function GetCharAtCaret: char;
function GetCharBeforeCaret: char;
procedure ClearSelection;
procedure MoveSelection(const ANewPos: TPoint);
procedure CopySelection(const ANewPos: TPoint);
procedure AddIndent;
procedure RemoveIndent;
procedure RemoveAllIndent;
procedure PageUp(Selection: boolean = false);
procedure PageDown(Selection: boolean = false);
function CanUndo: boolean;
function Undo: boolean;
function CanRedo: boolean;
function Redo: boolean;
function GotoHistoryVersion(Index: integer): boolean;
procedure ClearUndoHistory;
procedure MakeUndoRoot;
procedure TypeTimerEnd;
procedure AddUndoRecord(const AComment: string; UID: UNDONAMEID);
procedure Clear;
procedure NewFile;
procedure LoadFromFile(const FileName: TFileName; const Encoding: TEncoding);
procedure SaveToFile(const FileName: TFileName; TrimRight: boolean = false);
procedure Print(const ATitle: string;
AFirstLine: integer = 0; ALastLine: integer = -1); overload;
procedure Print(AFirstLine: integer = 0; ALastLine: integer = -1); overload;
procedure PrintSelection(const ATitle: string); overload;
procedure PrintSelection; overload;
property SelText: string read GetSelText write InsertText;
property SelStart: integer read GetSelStart write SetSelStart;
property SelLength: integer read GetSelLength write SetSelLength;
function Find(AFindQuery: TFindQuery): integer;
function FindNext: integer;
function FindPrevious: integer;
function FindFromTop: integer;
property StartOver: boolean read FStartOver write FStartOver;
function ReplaceAll(const FindQuery: TFindQuery;
const ReplaceText: string; SelOnly: boolean = false): integer;
function ShowBalloon(const ATitle, AText: string; AKind: TBalloonIconKind;
APersistence: TBalloonPersistence; const APoint: TPoint): boolean;
procedure HideBalloon;
function BalloonVisible: boolean;
procedure AddClass(const AClassRecord: TClassRecord);
function RemoveClass(const AClassName: string): boolean;
procedure ClearClasses;
function GetClassFromName(const AClassName: string; out AClassRecord: TClassRecord): boolean;
function GetClassIndex(const AClassName: string): integer;
function ClassExists(const AClassName: string): boolean; overload; inline;
function ClassExists(const AClassName: string; out Index: integer): boolean; overload; inline;
property Classes[Index: integer]: TClassRecord read GetClassRecord;
property ClassCount: integer read GetNumClasses;
procedure AddLineControl(AControl: TControl);
procedure InsertLineControl(AControl: TControl; LineIndex: integer);
procedure AddGraphic(AGraphic: TGraphic);
function DeleteControlAtLine(const LineIndex: integer): boolean;
procedure CenterOnSelection(AReducedScroll: boolean = false);
property TotalVerticalExtent: integer read GetTotalVerticalExtent;
property TotalHorizontalExtent: integer read GetTotalHorizontalExtent;
procedure DeleteAllLineControls;
procedure InsertGraphic(AGraphic: TGraphic; LineIndex: integer);
function ControlInSelection: boolean;
procedure TrimRight;
procedure ClearBookmarks; inline;
procedure AddBookmark(AIndex: integer; const APoint: TPoint); overload; inline;
procedure AddBookmark(AIndex: integer); overload; inline;
function AddBookmark(const APoint: TPoint): integer; overload; inline;
function AddBookmark: integer; overload; inline;
function GotoBookmark(AIndex: integer): boolean; inline;
function BookmarkUsed(AIndex: integer): boolean; inline;
function GetLineBookmark(ALineIndex: integer): integer;
property LineCount: integer read GetLineCount;
property Lines[Index: integer]: string read GetLine write SetLine;
property LineClasses[Index: integer]: string read GetClass write SetClass;
property Bookmarks[Index: integer]: TPoint read GetBookmark;
property BookmarkCount: integer read GetBookmarkCount;
property UsedBookmarkCount: integer read GetUsedBookmarkCount;
procedure ExportToHTML(const FileName: TFileName);
procedure RemoveAllMargins;
procedure RestoreAllMargins;
procedure ZoomIn;
procedure ZoomOut;
procedure ResetZoom;
procedure WordWrap(ALineLength: integer = 80; ANice: boolean = true;
AChr: char = #0);
property Notifications[AIndex: integer]: integer read GetNotification;
property NotificationCount: integer read GetNotificationCount;
property NotificationStr[MsgID: integer]: string read GetNotificationStr;
function HasNotificationMessage(MsgID: integer): boolean;
function Sort(AFirstLine, ALastLine: integer): boolean; overload;
function Sort: boolean; overload;
function SortSelection: boolean;
property LineComparer: TLineComparer read GetLineComparer write SetLineComparer;
property SortReverseOrder: boolean read GetSortReverseOrder write SetSortReverseOrder;
function MakeLinesUnique: boolean;
procedure TruncateAt(AFirstLine, ALastLine, AIndex: integer;
AChar: char = #0; PreserveChar: boolean = false; AReverse: boolean = false); overload;
procedure TruncateAt(AIndex: integer;
AChar: char = #0; PreserveChar: boolean = false; AReverse: boolean = false); overload;
procedure TruncateAtInSelection(AIndex: integer;
AChar: char = #0; PreserveChar: boolean = false; AReverse: boolean = false);
procedure Filter(const AFilterOptions: TFilterOptions); overload;
procedure Filter(const Contains, Starts, Ends: string; CaseSensitive: boolean;
RemoveMatches: boolean); overload;
procedure CliNewPrompt;
procedure CliBeginOutput;
procedure CliEndOutput;
procedure CliWriteLn(const AStr, AClass: string); overload;
procedure CliWriteLn(const AStr: string); overload;
procedure CliWriteLn; overload;
procedure CliAddHistory(const AStr: string);
procedure CliClearHistory;
property CliHistory[Index: integer]: string read GetCliHistory write SetCliHistory;
property CliHistoryCount: integer read GetCliHistoryCount;
property CliHistoryIndex: integer read GetCliHistoryIndex;
function CliHistoryRecall(Index: integer): boolean;
function CliHistoryDialog: integer;
function CliHistoryDialogSelect: boolean;
procedure RunScript(const AScript: TEditorScript; AIterations: integer = 1;
ACounterInit: integer = 1; ACounterInc: integer = 1);
procedure AbortScript;
procedure LoadDefaultClasses;
procedure PushEditorState;
procedure RegisterFP(FormattingProcessor: TFormattingProcessor);
published
property Align;
property AlignWithMargins;
property Anchors;
property BorderType: TBorderType read FBorderType write SetBorderType default btThemeBorder;
property BorderWidth;
property BorderColor: TColor read FBorderColor write SetBorderColor default clSilver;
property Enabled;
property Margins;
property PopupMenu;
property RulerPopupMenu: TPopupMenu read FRulerPopupMenu write FRulerPopupMenu;
property TabStop default true;
property TabOrder;
property OnClick;
property OnDblClick;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseDown;
property OnMouseUp;
property OnMouseActivate;
property OnEnter;
property OnExit;
property BitmapEffect: TBitmapEffect read FBitmapEffect write SetBitmapEffect default beNone;
property DisabledEffect: TBitmapEffect read FDisabledEffect write SetDisabledEffect default beGrayscale;
property HandleHotkeys: boolean read FHandleHotkeys write FHandleHotkeys default true;
property HandleBookmarkHotkeys: boolean read FHandleBookmarkHotkeys write FHandleBookmarkHotkeys default true;
property UseSystemColors: boolean read FUseSystemColors write SetUseSystemColors default true;
property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clWhite;
property ForegroundColor: TColor read FForegroundColor write SetForegroundColor default clBlack;
property SelBackgroundColor: TColor read FSelBackgroundColor write SetSelBackgroundColor default clBlack;
property SelForegroundColor: TColor read FSelForegroundColor write SetSelForegroundColor default clWhite;
property FindBackgroundColor: TColor read FFndBkColor write SetFindBackgroundColor default clYellow;
property FindForegroundColor: TColor read FFndFgColor write SetFindForegroundColor default clBlack;
property Font: TFont read FFont write SetFont;
property LetterSpacing: integer read FLetterSpacing write SetLetterSpacing default 1;
property LineSpacing: integer read FLineSpacing write SetLineSpacing default 1;
property CaretAfterEOL: boolean read GetCaretAfterEOL write SetCaretAfterEOL default true;
property AutoIndent: boolean read FAutoIndent write SetAutoIndent default true;
property PlainText: string read GetText write SetText;
property BeepOnInputError: boolean read FBeepOnInputError write FBeepOnInputError default true;
property ErrorMessageOnReadOnlyError: boolean read FErrorMessageOnReadOnlyError write FErrorMessageOnReadOnlyError default true;
property Overwrite: boolean read FOverwrite write SetOverwrite default false;
property IndentSize: integer read FIndentSize write SetIndentSize default 2;
property EditMode: TEditMode read GetEditMode write SetEditMode default emText;
property ShowHiddenCharacters: boolean read FShowHiddenCharacters write SetShowHiddenCharacters default false;
property LineHighlight: boolean read FLineHighlight write SetLineHighlight default false;
property LineHighlightColor: TColor read FLineHighlightColor write SetLineHighlightColor default DEFAULT_LINE_HIGHLIGHT_COLOR;
property MatchBrackets: boolean read FMatchBrackets write SetMatchBrackets default true;
property BracketHighlightColor: TColor read FBracketHighlightColor write SetBracketHighlightColor default DEFAULT_BRACKET_HIGHLIGHT_COLOR;
property AutoReplace: boolean read FAutoReplace write FAutoReplace default false;
property MessageInterface: boolean read FMessageInterface write FMessageInterface default true;
property InputTransform: TInputTransform read FInputTransform write FInputTransform default itNone;
property SingleLine: boolean read GetSingleLine write SetSingleLine default false;
property FallbackFonts: TStringList read FFallbackFonts write SetFallbackFonts;
property UnicodeFallback: boolean read FUnicodeFallback write SetUnicodeFallback default true;
property PasswordChar: char read FPasswordChar write SetPasswordChar default #0;
property NumbersOnly: boolean read FNumbersOnly write FNumbersOnly default false;
property TabLength: integer read FTabLength write FTabLength default 2;
property LabelStyle: boolean read FLabelStyle write SetLabelStyle default false;
property LabelEllipsis: boolean read FLabelEllipsis write SetLabelEllipsis default true;
property AutoHeight: boolean read FAutoHeight write SetAutoHeight default true;
property MultiSize: boolean read FMultiSize write SetMultiSize default false;
property FormattingProcessor: TFormattingProcessor read FFormattingProcessor write SetFormattingProcessorSmple;
property RulerFont: TFont read FRulerFont write FRulerFont;
property RulerVisible: boolean read GetRulerVisible write SetRulerVisible stored false;
property MarginLeft: integer read FMarginLeft write SetMarginLeft default DEFAULT_MARGIN_LEFT;
property MarginRight: integer read FMarginRight write SetMarginRight default DEFAULT_MARGIN_Right;
property MarginTop: integer read FMarginTop write SetMarginTop default DEFAULT_MARGIN_Top;
property MarginBottom: integer read FMarginBottom write SetMarginBottom default DEFAULT_MARGIN_Bottom;
property RulerWidth: integer read FRulerWidth write SetRulerWidth default DEFAULT_RULER_WIDTH;
property RulerColor: TColor read FRulerColor write SetRulerColor default clDefault;
property PrintSettings: TPrintSettings read FPrintSettings;
property Zoom: integer read FZoom write SetZoom default 100;
property RightLine: boolean read FRightLine write SetRightLine default false;
property RightLinePos: integer read FRightLinePos write SetRightLinePos default 580;
property RightLineColor: TColor read FRightLineColor write SetRightLineColor default clSilver;
property WrapAt: string read GetWrapAt write SetWrapAt;
property WrapAtRestore: boolean read GetFalse write RestoreWrapAt default false;
property TextFileOwner: TTextFileOwner read FTextFileOwner write FTextFileOwner default tfoEditor;
property SelectionBarBehaviour: TSelectionBarBehaviour read FSelectionBarBehaviour write FSelectionBarBehaviour default sbbAutoMixed;
property NotificationMsgDuration: integer read FNotifyMsgDuration write FNotifyMsgDuration default DEFAULT_NOTIFICATION_MSG_DURATION;
property ListBoxMode: boolean read FListBoxMode write SetListBoxMode;
property ListBoxItemIndex: integer read GetListBoxItemIndex write SetListBoxItemIndex;
property MultiCharSelect: boolean read FMultiCharSelect write FMultiCharSelect default true;
property MultiCharReportView: boolean read FMultiCharReportView write FMultiCharReportView default false;
property ScrollBehaviour: TScrollBehaviour read FScrollBehaviour write FScrollBehaviour default sbDefault;
property AllowBitmapPaste: boolean read FAllowBitmapPaste write FAllowBitmapPaste default false;
property Visible;
property WantTab: boolean read FWantTab write FWantTab default true;
property WantReturn: boolean read FWantReturn write FWantReturn default true;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnSelChange: TNotifyEvent read FOnSelChange write FOnSelChange;
property OnModified: TNotifyEvent read FOnModified write FOnModified;
property OnOverwriteChange: TNotifyEvent read FOnOverwriteChange write FOnOverwriteChange;
property OnBookmarksMoved: TNotifyEvent read FOnBookmarksMoved write FOnBookmarksMoved;
property OnZoomChange: TNotifyEvent read FOnZoomChange write FOnZoomChange;
property OnPrintBegin: TProgressStartEvent read FOnPrintBegin write FOnPrintBegin;
property OnPrintProgress: TProgressEvent read FOnPrintProgress write FOnPrintProgress;
property OnPrintEnd: TProgressCompleteEvent read FOnPrintEnd write FOnPrintEnd;
property OnNotification: TNotificationMessage read FOnNotification write FOnNotification;
property OnSimpleNotification: TSimpleNotificationMessage read FOnSimpleNotification write FOnSimpleNotification;
property OnCliGetPromptClass: TCliGetPromptClassEvent read FOnCliGetPromptClass write FOnCliGetPromptClass;
property OnCliInput: TCliInputEvent read FOnCliInput write FOnCliInput;
property OnListBoxChange: TNotifyEvent read FOnListBoxChange write FOnListBoxChange;
property OnListBoxSelect: TNotifyEvent read FOnListBoxSelect write FOnListBoxSelect;
property OnFindDataClear: TNotifyEvent read FOnFindDataClear write FOnFindDataClear;
end;
procedure Register;
const
RTE_CURSOR_BASE = 10;
crBlock = TCursor(RTE_CURSOR_BASE + 1);
crBlockCopy = TCursor(RTE_CURSOR_BASE + 2);
crHand = TCursor(RTE_CURSOR_BASE + 3);
crHandHold = TCursor(RTE_CURSOR_BASE + 4);
crLineSel = TCursor(RTE_CURSOR_BASE + 5);
var
FixedWidthFonts: TStrings;
GlobalFileNumber: integer = 1;
type
DynIntegerArray = array of integer;
DynStringArray = array of string;
function FormatDataSize(const ASize: Int64): string;
function Split(const Str: string; const Delim: string): DynStringArray;
implementation
{$R TextEditorCursors.res}
{$WARN WIDECHAR_REDUCED OFF}
uses Character, StrUtils, Clipbrd, IMouse, SHFolder, Dialogs, ShellAPI,
Printers, Themes, RulerPropertiesWin, MultiInput, StdCtrls, ComCtrls;
const
CARET_WIDTH = 2;
SCROLL_EXTRA = 120;
AUTO_HEIGHT_PADDING = 2;
procedure Register;
begin
RegisterComponents('Rejbrand 2015', [TTextEditor,
TVowelsAndConsonantsFormattingProcessor, TXMLFormattingProcessor,
TCSSFormattingProcessor, TINIFormattingProcessor, TPascalFormattingProcessor,
TAlgoSimFormattingProcessor, THTMLFormattingProcessor,
TMediaWikiFormattingProcessor]);
end;
function B(A: boolean): integer;
begin
if A then
result := 1
else
result := 0;
end;
function GetAppDataFolder: string;
var
i: integer;
begin
SetLength(result, MAX_PATH);
if SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, PChar(result)) <> S_OK then
Exit('');
i := Pos(#0, result);
if i > 0 then
SetLength(result, i-1);
end;
function GetAutoReplaceDataFileName: string;
var
AppData: string;
begin
AppData := GetAppDataFolder;
if AppData = '' then Exit('');
result := AppData + '\Rejbrand\AutoReplace\1.0\autoreplace.dat';
end;
function FontRecord(ASize: integer; AStyle: TFontStyles; AColor: TColor): TFontRecord;
begin
result.Size := ASize;
result.Style := AStyle;
result.Color := AColor;
end;
function MakeClass(const AName: string; ASize: integer; AStyle: TFontStyles; AColor: TColor): TClassRecord;
begin
result.Name := AName;
result.Format := FontRecord(ASize, AStyle, AColor);
end;
function MakeFindQuery(const ASearchString: string; AMatchCase, AMatchWord, ALinebreak: boolean): TFindQuery;
begin
result.SearchString := ASearchString;
result.MatchCase := AMatchCase;
result.MatchWord := AMatchWord;
result.Linebreak := ALinebreak;
result.UCBlock := 0;
end;
function MakeFindQuery(UCBlock: integer): TFindQuery; overload;
begin
result.SearchString := '';
result.MatchCase := false;
result.MatchWord := false;
result.Linebreak := false;
result.UCBlock := UCBlock;
end;
function SamePoint(const Point1, Point2: TPoint): boolean; inline;
begin
result := (Point1.X = Point2.X) and (Point1.Y = Point2.Y);
end;
function SameChangeRecord(const ChangeRecord1, ChangeRecord2: TChangeRecord): boolean; inline;
begin
result := (ChangeRecord1.ChangeType = ChangeRecord2.ChangeType) and
(ChangeRecord1.Data1 = ChangeRecord2.Data1) and
(ChangeRecord1.Data2 = ChangeRecord2.Data2) and
(ChangeRecord1.Data3 = ChangeRecord2.Data3) and
(ChangeRecord1.Data4 = ChangeRecord2.Data4);
end;
function ChangeSubset(const ChangeRecord1, ChangeRecord2: TChangeRecord): boolean;
function IsOneOfThem(const Y, X: integer): boolean;
begin
result := ((Y = ChangeRecord2.Data1) and (X = ChangeRecord2.Data2))
OR
((Y = ChangeRecord2.Data3) and (X = ChangeRecord2.Data4));
end;
begin
result := false;
case ChangeRecord2.ChangeType of
ctFile:
Exit(true);
ctLineRange:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit((ChangeRecord1.Data1 >= ChangeRecord2.Data1) and (ChangeRecord1.Data2 <= ChangeRecord2.Data2));
ctBlock:
Exit((ChangeRecord1.Data1 >= ChangeRecord2.Data1) and (ChangeRecord1.Data2 <= ChangeRecord2.Data2));
ctLine:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2));
ctLineFrom:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2));
ctChar:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2));
ctTwoChars:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2) and InRange(ChangeRecord1.Data3, ChangeRecord2.Data1, ChangeRecord2.Data2));
end;
ctBlock:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit(false);
ctBlock:
Exit((ChangeRecord1.Data1 >= ChangeRecord2.Data1) and (ChangeRecord1.Data2 <= ChangeRecord2.Data2) and (ChangeRecord1.Data3 >= ChangeRecord2.Data3) and (ChangeRecord1.Data4 <= ChangeRecord2.Data4));
ctLine:
Exit(false);
ctLineFrom:
Exit(false);
ctChar:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2) and InRange(ChangeRecord1.Data2, ChangeRecord2.Data3, ChangeRecord2.Data4));
ctTwoChars:
Exit(InRange(ChangeRecord1.Data1, ChangeRecord2.Data1, ChangeRecord2.Data2) and InRange(ChangeRecord1.Data2, ChangeRecord2.Data3, ChangeRecord2.Data4) and InRange(ChangeRecord1.Data3, ChangeRecord2.Data1, ChangeRecord2.Data2) and InRange(ChangeRecord1.Data4, ChangeRecord2.Data3, ChangeRecord2.Data4));
end;
ctLine:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 = ChangeRecord2.Data1));
ctBlock:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 = ChangeRecord2.Data1));
ctLine:
Exit(ChangeRecord1.Data1 = ChangeRecord2.Data1);
ctLineFrom:
Exit(ChangeRecord1.Data1 = ChangeRecord2.Data1);
ctChar:
Exit(ChangeRecord1.Data1 = ChangeRecord2.Data1);
ctTwoChars:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data3 = ChangeRecord2.Data1));
end;
ctLineFrom:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit((ChangeRecord2.Data2 = 0) and (ChangeRecord1.Data1 = ChangeRecord1.Data2) and (ChangeRecord1.Data1 = ChangeRecord2.Data1));
ctBlock:
Exit((ChangeRecord1.Data1 = ChangeRecord1.Data2) and (ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data3 >= ChangeRecord2.Data2));
ctLine:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord2.Data2 = 0));
ctLineFrom:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 >= ChangeRecord2.Data2));
ctChar:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 >= ChangeRecord2.Data2));
ctTwoChars:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 >= ChangeRecord2.Data2) and (ChangeRecord1.Data3 = ChangeRecord2.Data1) and (ChangeRecord1.Data4 >= ChangeRecord2.Data2));
end;
ctChar:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit(false);
ctBlock:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord2.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data3 = ChangeRecord2.Data2) and (ChangeRecord2.Data3 = ChangeRecord2.Data2));
ctLine:
Exit(false);
ctLineFrom:
Exit(false);
ctChar:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 = ChangeRecord2.Data2));
ctTwoChars:
Exit((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 = ChangeRecord2.Data2) and (ChangeRecord1.Data3 = ChangeRecord2.Data1) and (ChangeRecord1.Data4 = ChangeRecord2.Data2));
end;
ctTwoChars:
case ChangeRecord1.ChangeType of
ctNone:
Exit(true);
ctFile:
Exit(false);
ctLineRange:
Exit(false);
ctBlock:
Exit(((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord2.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data3 = ChangeRecord2.Data2) and (ChangeRecord2.Data3 = ChangeRecord2.Data2)) OR ((ChangeRecord1.Data1 = ChangeRecord2.Data3) and (ChangeRecord2.Data1 = ChangeRecord2.Data3) and (ChangeRecord1.Data3 = ChangeRecord2.Data4) and (ChangeRecord2.Data3 = ChangeRecord2.Data4)));
ctLine:
Exit(false);
ctLineFrom:
Exit(false);
ctChar:
Exit(((ChangeRecord1.Data1 = ChangeRecord2.Data1) and (ChangeRecord1.Data2 = ChangeRecord2.Data2)) OR ((ChangeRecord1.Data1 = ChangeRecord2.Data3) and (ChangeRecord1.Data2 = ChangeRecord2.Data4)));
ctTwoChars:
Exit(IsOneOfThem(ChangeRecord1.Data1, ChangeRecord1.Data2) and IsOneOfThem(ChangeRecord1.Data3, ChangeRecord1.Data4));
end;
end;
end;
function MakeChangeRecord(ChangeType: TChangeType; Data1, Data2, Data3, Data4: integer): TChangeRecord;
begin
result.ChangeType := ChangeType;
result.Data1 := Data1;
result.Data2 := Data2;
result.Data3 := Data3;
result.Data4 := Data4;
end;
function ChangeUnion(const ChangeRecord1, ChangeRecord2: TChangeRecord): TChangeRecord;
begin
if (ChangeRecord1.ChangeType = ctFile) or (ChangeRecord2.ChangeType = ctFile) then
Exit(FILE_CHANGE_RECORD);
if ChangeSubset(ChangeRecord1, ChangeRecord2) then
Exit(ChangeRecord2);
if ChangeSubset(ChangeRecord2, ChangeRecord1) then
Exit(ChangeRecord1);
if (ChangeRecord1.ChangeType = ctChar) and (ChangeRecord1.ChangeType = ctChar) then
begin
result.ChangeType := ctTwoChars;
result.Data1 := ChangeRecord1.Data1;
result.Data2 := ChangeRecord1.Data2;
result.Data3 := ChangeRecord2.Data1;
result.Data4 := ChangeRecord2.Data2;
Exit;
end;
if (ChangeRecord1.ChangeType = ctBlock) and (ChangeRecord2.ChangeType = ctBlock) then
begin
result.ChangeType := ctBlock;
result.Data1 := Min(ChangeRecord1.Data1, ChangeRecord2.Data1);
result.Data2 := Max(ChangeRecord1.Data2, ChangeRecord2.Data2);
result.Data3 := Min(ChangeRecord1.Data3, ChangeRecord2.Data3);
result.Data4 := Max(ChangeRecord1.Data4, ChangeRecord2.Data4);
Exit;
end;
if (ChangeRecord1.ChangeType = ctLineRange) and (ChangeRecord2.ChangeType = ctLineRange) then
begin
result.ChangeType := ctLineRange;
result.Data1 := Min(ChangeRecord1.Data1, ChangeRecord2.Data1);
result.Data2 := Max(ChangeRecord1.Data2, ChangeRecord2.Data2);
Exit;
end;
if (ChangeRecord1.ChangeType = ctLineRange) and (ChangeRecord2.ChangeType in [ctLine, ctLineFrom, ctChar]) then
begin
result.ChangeType := ctLineRange;
result.Data1 := Min(ChangeRecord1.Data1, ChangeRecord2.Data1);
result.Data2 := Max(ChangeRecord1.Data2, ChangeRecord2.Data1);
Exit;
end;
if (ChangeRecord2.ChangeType = ctLineRange) and (ChangeRecord1.ChangeType in [ctLine, ctLineFrom, ctChar]) then
begin
result.ChangeType := ctLineRange;
result.Data1 := Min(ChangeRecord2.Data1, ChangeRecord1.Data1);
result.Data2 := Max(ChangeRecord2.Data2, ChangeRecord1.Data1);
Exit;
end;
result := FILE_CHANGE_RECORD;
end;
function MakeEditorCommand(Verb: integer; Param1: integer = 0;
ParamType1: TParamType = ptConstant; Param2: integer = 0;
ParamType2: TParamType = ptConstant; Param3: integer = 0;
ParamType3: TParamType = ptConstant; Param4: integer = 0;
ParamType4: TParamType = ptConstant): TEditorCommand;
begin
result.Verb := Verb;
result.Param1.ParamType := ParamType1;
result.Param1.ParamValue := Param1;
result.Param2.ParamType := ParamType2;
result.Param2.ParamValue := Param2;
result.Param3.ParamType := ParamType3;
result.Param3.ParamValue := Param3;
result.Param4.ParamType := ParamType4;
result.Param4.ParamValue := Param4;
end;
function Occurrences(const Str: string; const Chr: char): integer; overload;
var
i: integer;
begin
result := 0;
for i := 1 to Str.Length do
if Str[i] = Chr then
inc(result);
end;
function Occurrences(const Str: string; const SubStr: string;
out indices: DynIntegerArray): integer; overload;
const
ALLOC_BY = 4096;
var
i: integer;
begin
result := 0;
i := 0;
SetLength(indices, ALLOC_BY);
repeat
i := PosEx(SubStr, Str, i + 1);
if i > 0 then
begin
if result = length(indices) then
SetLength(indices, Length(indices) + ALLOC_BY);
indices[result] := i;
inc(result);
end;
until i = 0;
SetLength(indices, result);
end;
function Occurrences2(const Str: string; const SubStr: string;
out indices: DynIntegerArray): integer; overload;
const
ALLOC_BY = 4096;
var
i: integer;
begin
result := 0;
i := 0;
SetLength(indices, ALLOC_BY);
repeat
i := PosEx(SubStr, Str, i + 1);
if i > 0 then
begin
if result = length(indices) then
SetLength(indices, Length(indices) + ALLOC_BY);
indices[result] := i;
inc(result);
end;
until i = 0;
SetLength(indices, result + 1);
indices[result] := Length(Str) + 1;
end;
function FormatDataSize(const ASize: Int64): string;
const
prefixes: array[0..6] of string = ('', 'k', 'M', 'G', 'T', 'P', 'E');
var
val: real;
n: integer;
begin
if ASize < 0 then
raise Exception.CreateFmt('FormatDataSize: Invalid data size %d.', [ASize]);
val := ASize;
for n := 0 to high(prefixes) do
begin
if (val <= 1000) or (n = high(prefixes)) then
begin
result := FormatFloat('0.##', val) + #32 + prefixes[n] + 'B';
break;
end;
val := val / 1024;
end;
end;
function Split(const Str: string; const Delim: string): DynStringArray;
var
n: integer;
indices: DynIntegerArray;
i: Integer;
begin
n := Occurrences2(Str, Delim, indices);
SetLength(result, n + 1);
if n = 0 then
result[0] := Str
else
begin
result[0] := Copy(Str, 1, indices[0] - 1);
for i := 0 to n - 1 do
result[i+1] := Copy(Str, indices[i] + Length(Delim), indices[i + 1] - indices[i] - Length(Delim));
end;
end;
function imod(const x: integer; const y: integer): integer;
begin
if x >= 0 then
imod := x - floor(x/y) * y
else
imod := x + ceil(-x/y) * y;
end;
function ChrUpperCase(C: char): char;
begin
result := AnsiUpperCase(C)[1];
end;
function ChrLowerCase(C: char): char;
begin
result := AnsiLowerCase(C)[1];
end;
function ChrInvertCase(C: char): char;
begin
if C.IsUpper then
result := AnsiLowerCase(C)[1]
else
result := AnsiUpperCase(C)[1];
end;
function ChrROT13(C: char): char;
begin
if InRange(ord(C), ord('A'), ord('Z')) then
result := Chr(ord('A') + (ord(C) - ord('A') + 13) mod 26)
else if InRange(ord(C), ord('a'), ord('z')) then
result := Chr(ord('a') + (ord(C) - ord('a') + 13) mod 26)
else
result := C;
end;
function ChrCaesar(N: integer): TChrTransformFunc;
begin
result := function(C: char): char
begin
if InRange(ord(C), ord('A'), ord('Z')) then
result := Chr(ord('A') + imod((ord(C) - ord('A') + N), 26))
else if InRange(ord(C), ord('a'), ord('z')) then
result := Chr(ord('a') + imod((ord(C) - ord('a') + N), 26))
else
result := C;
end;
end;
function TxtVigenère(const Key: string; decode: boolean = false): TTextTransformFunc;
var
n: integer;
KeyChrs: array of byte;
i: Integer;
factor: integer;
begin
n := Length(Key);
SetLength(KeyChrs, n);
for i := 1 to n do
if InRange(ord(Key[i]), ord('A'), ord('Z')) then
KeyChrs[i - 1] := ord(Key[i]) - ord('A')
else
raise Exception.Create('Invalid character in Vigenère key.');
factor := IfThen(decode, -1, 1);
result := function(const AText: string): string
var
j: Integer;
begin
SetLength(result, Length(AText));
for j := 1 to Length(AText) do
begin
if InRange(ord(AText[j]), ord('A'), ord('Z')) then
result[j] := Chr(ord('A') + imod(ord(AText[j]) - ord('A') + factor * KeyChrs[(j - 1) mod n], 26))
else if InRange(ord(AText[j]), ord('a'), ord('z')) then
result[j] := Chr(ord('a') + imod(ord(AText[j]) - ord('a') + factor * KeyChrs[(j - 1) mod n], 26))
else
result[j] := AText[j];
end;
end;
end;
function TxtCamelCase(const AText: string): string;
var
i: Integer;
StartOfWord: boolean;
begin
StartOfWord := true;
result := AText;
for i := 1 to Length(AText) do
begin
if StartOfWord and IsCharAlpha(AText[i]) then
begin
result[i] := AnsiUpperCase(AText[i])[1];
StartOfWord := false;
end
else if AText[i].IsWhiteSpace then
StartOfWord := true;
end;
end;
function TxtSentenceCase(const AText: string): string;
var
StartOfSentence: boolean;
i: Integer;
begin
StartOfSentence := true;
result := AText;
for i := 1 to AText.Length do
if StartOfSentence and IsCharAlpha(AText[i]) then
begin
result[i] := AnsiUpperCase(AText[i])[1];
StartOfSentence := false;
end
else if AText[i] in ['.', '!', '?'] then
StartOfSentence := true;
end;
function ReverseText(const AText: string): string;
var
i, j: integer;
begin
SetLength(result, AText.Length);
if AText.IsEmpty then
Exit;
i := 1;
j := result.Length;
while j > 0 do
begin
if (AText[i] = #13) and (i < AText.Length) and (AText[i + 1] = #10) then
begin
result[j] := #10;
result[j - 1] := #13;
inc(i);
dec(j);
end
else
result[j] := AText[i];
inc(i);
dec(j);
end;
end;
function IsKeyDown(const AKey: integer): boolean;
begin
result := GetKeyState(AKey) and $8000 <> 0;
end;
function IsKeyOn(const AKey: integer): boolean;
begin
result := GetKeyState(AKey) and 1 = 1;
end;
function GetScrollMode: boolean;
var
AltDown, ScrlLockOn: boolean;
begin
AltDown := IsKeyDown(VK_LMENU);
ScrlLockOn := IsKeyOn(VK_SCROLL);
result := (AltDown xor ScrlLockOn) and not IsKeyDown(VK_SHIFT);
end;
procedure TTextEditor.ChangeCursor(Shift: TShiftState);
var
P: TPoint;
begin
if GetCursorPos(P) then
with ScreenToClient(P) do
ChangeCursor(Shift, Y, X);
end;
procedure TTextEditor.ChangeCursor(Shift: TShiftState; Y, X: Integer);
var
CP: TPoint;
begin
if not (FValidPaintState and Visible) then Exit;
if FScriptRunning then
begin
Cursor := crHourGlass;
Exit;
end;
CP := CharAtPhysicalPixel(Point(X, Y));
if FScrollMode then
if csLButtonDown in ControlState then
Cursor := crHandHold
else
Cursor := crHand
else if X < GetFunctionalSelectionBarWidth then
Cursor := crLineSel
else
if ((X >= FMarginLeft) and FTextFile.IsCharSel(CP)) and not SingleLine then
if ssCtrl in Shift then
Cursor := crBlockCopy
else
Cursor := crBlock
else
Cursor := crIBeam;
end;
function TTextEditor.CaretPosAtVirtualPixel(Pixel: TPoint): TPoint;
begin
result := CharAtVirtualPixelEx(Pixel, true);
end;
procedure TTextEditor.CenterOnSelection(AReducedScroll: boolean);
var
p1, p2, p: TPoint;
begin
p1 := VirtualPixelAtChar(TextFile.CaretPos.Data);
if TextFile.HasSelection then
p2 := VirtualPixelAtChar(TextFile.CaretPos.SelEnd)
else
p2 := p1;
p.X := p1.X + (p2.X - p1.X) div 2 - ClientWidth div 2;
p.Y := p1.Y + (p2.Y - p1.Y) div 2 - ClientHeight div 2;
if AReducedScroll then
begin
if Abs(FScrollPos.X - p.X) < ClientWidth div 3 then
p.X := FScrollPos.X;
if Abs(FScrollPos.Y - p.Y) < ClientHeight div 3 then
p.Y := FScrollPos.Y;
end;
SetScrollPosXY(p.X, p.Y);
end;
function TTextEditor.CaretPosAtPhysicalPixel(Pixel: TPoint): TPoint;
begin
result := CharAtPhysicalPixelEx(Pixel, true);
end;
function TTextEditor.ChrInGlyphSet(GlyphSet: PGlyphSet;
Codepoint: integer): boolean;
function InInterval(Val, Start, Length: integer): boolean; inline;
begin
InInterval := (Val >= Start) and (Val < Start + Length);
end;
var
i: Integer;
begin
result := false;
if GlyphSet = nil then Exit;
for i := 0 to GlyphSet^.cRanges - 1 do
with GlyphSet^.ranges[i] do
if InInterval(Codepoint, ord(wcLow), cGlyphs) then
Exit(true);
end;
function TTextEditor.ChrInGlyphSet(GlyphSet: PGlyphSet;
Character: char): boolean;
begin
result := ChrInGlyphSet(GlyphSet, ord(Character));
end;
function TTextEditor.ChrTransformSelection(Transformation: TChrTransformFunc;
const TransformName: string): boolean;
begin
TypeTimerEnd;
result := FTextFile.ChrTransform(Transformation);
if result then
AddUndoRecord(Format(SUndoSelectionTransformed, [TransformName]), UID_UNKNOWN);
end;
procedure TTextEditor.ChrTransformText(Transformation: TChrTransformFunc;
const TransformName: string);
begin
TypeTimerEnd;
FTextFile.ChrTransformText(Transformation);
AddUndoRecord(Format(SUndoTextTransformed, [TransformName]), UID_UNKNOWN);
end;
procedure TTextEditor.ClearLine;
begin
TypeTimerEnd;
FTextFile.ClearLine;
AddUndoRecord(SUndoLineCleared, UID_DELETE);
end;
procedure TTextEditor.ClearSelection;
begin
TypeTimerEnd;
FTextFile.ClearSelection;
AddUndoRecord(SUndoSelectionCleared, UID_DELETE);
end;
procedure TTextEditor.ClearUndoHistory;
begin
FTypeTimer.Enabled := false;
FTextFile.ClearUndoHistory;
AddUndoRecord(SUndoFirstPost, UID_UNKNOWN);
end;
procedure TTextEditor.CliAddHistory(const AStr: string);
begin
SetLength(FCliHistory, Length(FCliHistory) + 1);
FCliHistory[high(FCliHistory)] := AStr;
end;
procedure TTextEditor.CliBeginOutput;
begin
FCliMultiOutput := true;
end;
procedure TTextEditor.CliClearHistory;
begin
SetLength(FCliHistory, 0);
end;
procedure TTextEditor.CliEndOutput;
begin
FCliMultiOutput := false;
CliNewPrompt;
end;
procedure TTextEditor.CliHistoryDialogListBoxSelect(Sender: TObject);
begin
if (Sender is TTextEditor) and (TTextEditor(Sender).Parent is TForm) then
TForm(TTextEditor(Sender).Parent).ModalResult := mrOk;
end;
procedure TTextEditor.CliHistoryDialogListBoxKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
if Key = VK_ESCAPE then
if (Sender is TTextEditor) and (TTextEditor(Sender).Parent is TForm) then
TForm(TTextEditor(Sender).Parent).ModalResult := mrCancel;
end;
function TTextEditor.CliHistoryDialog: integer;
var
frm: TForm;
lb: TTextEditor;
i: Integer;
begin
result := -1;
frm := TForm.Create(nil);
try
frm.Caption := SCliHistoryDialogCaption;
frm.BorderStyle := bsSizeToolWin;
frm.ClientWidth := 512;
frm.ClientHeight := 256;
with ClientToScreen(Point(ClientWidth div 2 - frm.ClientWidth div 2,
ClientHeight div 2 - frm.ClientHeight div 2)) do
begin
frm.Left := X;
frm.Top := Y;
end;
lb := TTextEditor.Create(frm);
lb.Parent := frm;
lb.Align := alClient;
lb.TabStop := true;
lb.UseSystemColors := Self.UseSystemColors;
lb.Color := Self.Color;
lb.Font.Assign(Self.Font);
lb.LineHighlightColor := Self.LineHighlightColor;
if lb.Color = lb.LineHighlightColor then
begin
lb.Color := clWhite;
lb.Font.Color := clBlack;
lb.LineHighlightColor := DEFAULT_LINE_HIGHLIGHT_COLOR;
end;
lb.ListBoxMode := true;
lb.RulerWidth := 32;
lb.MarginLeft := 40;
lb.RulerColor := Self.RulerColor;
lb.OnKeyDown := CliHistoryDialogListBoxKeyDown;
lb.OnListBoxSelect := CliHistoryDialogListBoxSelect;
lb.BeginAddLine;
for i := 0 to CliHistoryCount - 1 do
lb.AddLine(CliHistory[i]);
lb.EndAddLine;
if FCliHistoryIndex <> -1 then
lb.ListBoxItemIndex := FCliHistoryIndex;
if frm.ShowModal = mrOk then
result := lb.ListBoxItemIndex;
finally
frm.Free;
end;
end;
function TTextEditor.CliHistoryDialogSelect: boolean;
var
index: integer;
begin
index := CliHistoryDialog;
result := index <> -1;
if result then
CliHistoryRecall(index);
end;
function TTextEditor.CliHistoryDown: boolean;
begin
result := InRange(FCliHistoryIndex, 0, high(FCliHistory) - 1);
if result then
begin
inc(FCliHistoryIndex);
TypeTimerEnd;
Lines[LineCount - 1] := FCliHistory[FCliHistoryIndex];
FTextFile.GotoEOF;
AddUndoRecord(SUndoCliHistory, UID_UNKNOWN);
end;
end;
function TTextEditor.CliHistoryRecall(Index: integer): boolean;
begin
result := InRange(Index, 0, high(FCliHistory));
if result then
begin
FCliHistoryIndex := Index;
TypeTimerEnd;
Lines[LineCount - 1] := FCliHistory[FCliHistoryIndex];
FTextFile.GotoEOF;
AddUndoRecord(SUndoCliHistory, UID_UNKNOWN);
end;
end;
function TTextEditor.CliHistoryUp: boolean;
begin
result := InRange(FCliHistoryIndex, 1, high(FCliHistory) + 1);
if result then
begin
dec(FCliHistoryIndex);
TypeTimerEnd;
Lines[LineCount - 1] := FCliHistory[FCliHistoryIndex];
FTextFile.GotoEOF;
AddUndoRecord(SUndoCliHistory, UID_UNKNOWN);
end;
end;
procedure TTextEditor.CliNewPrompt;
var
ClassName: string;
begin
FTypeTimer.Enabled := false;
ClassName := '';
if Assigned(FOnCliGetPromptClass) then
FOnCliGetPromptClass(Self, ClassName);
AddLine('', ClassName);
ClearUndoHistory;
FCliHistoryIndex := high(FCliHistory) + 1;
end;
procedure TTextEditor.CliWriteLn(const AStr, AClass: string);
begin
if FTextFile.LineIsEmpty(LineCount - 1) then
begin
Lines[LineCount - 1] := AStr;
LineClasses[LineCount - 1] := AClass;
end
else
AddLine(AStr, AClass);
if not FCliMultiOutput then
CliNewPrompt;
end;
procedure TTextEditor.CliWriteLn(const AStr: string);
begin
CliWriteLn(AStr, '');
end;
procedure TTextEditor.CliWriteLn;
begin
CliWriteLn('', '');
end;
procedure TTextEditor.ClearLine(LineIndex: integer);
begin
FTextFile.ClearLine(LineIndex);
end;
function TTextEditor.CommandEnabled(Command: integer): boolean;
var
dummy: string;
begin
result := true;
case Command and $FFFF of
EDITOR_COMMAND_PASTE:
result := (Clipboard.HasFormat(CF_TEXT) or (FAllowBitmapPaste and Clipboard.HasFormat(CF_BITMAP) and not SingleLine)) and Enabled;
EDITOR_COMMAND_PASTE_AS_BLOCK:
result := Clipboard.HasFormat(CF_TEXT) and Enabled;
EDITOR_COMMAND_CUT, EDITOR_COMMAND_COPY, EDITOR_COMMAND_CLEAR_SELECTION:
result := FTextFile.HasSelection and Enabled;
EDITOR_COMMAND_UNDO:
result := CanUndo;
EDITOR_COMMAND_REDO:
result := CanRedo;
EDITOR_COMMAND_SELECT_ALL:
result := (not FTextFile.Empty) and Enabled;
EDITOR_COMMAND_ACTIVATE_CONTROL:
result := LineIsWinControlOrHasPopup(CaretPos.Y);
EDITOR_COMMAND_CLASS_MENU:
result := not LineIsControl(CaretPos.Y);
EDITOR_COMMAND_OPEN_URL_AT_CARET:
result := GetURLAtCaret(dummy);
EDITOR_COMMAND_SEL_UPPER_CASE .. EDITOR_COMMAND_SEL_INVERT_CASE,
EDITOR_COMMAND_SEL_ROT13 .. EDITOR_COMMAND_SEL_CAESAR:
result := FTextFile.HasSelection;
EDITOR_COMMAND_SEL_CAMEL_CASE .. EDITOR_COMMAND_SEL_SENTENCE_CASE,
EDITOR_COMMAND_SEL_VIGENERE, EDITOR_COMMAND_SEL_REVERSE:
result := FTextFile.HasSelection and (FTextFile.CaretPos.SelectionType = stLineBased);
EDITOR_COMMAND_SORT_ALL, EDITOR_COMMAND_SORT:
result := FTextFile.LineCount >= 2;
EDITOR_COMMAND_SORT_SEL:
result := FTextFile.HasSelection;
EDITOR_COMMAND_ABORT_SCRIPT:
result := FScriptRunning;
EDITOR_COMMAND_SAVE, EDITOR_COMMAND_SET_EDIT_MODE:
result := not FTextFile.StrictReadOnly;
end;
end;
function TTextEditor.CommandVisible(Command: integer): boolean;
var
dummy: string;
begin
result := true;
case Command and $FFFF of
EDITOR_COMMAND_ACTIVATE_CONTROL:
result := LineIsWinControlOrHasPopup(CaretPos.Y);
EDITOR_COMMAND_BOOKMARK_SET_MENU,
EDITOR_COMMAND_BOOKMARK_GO_MENU,
EDITOR_COMMAND_BOOKMARK_CLEAR_MENU:
result := not SingleLine;
EDITOR_COMMAND_CLASS_MENU:
result := (ClassCount > 0) and FTextFile.UseLineClasses;
EDITOR_COMMAND_OPEN_URL_AT_CARET:
result := GetURLAtCaret(dummy);
EDITOR_COMMAND_SEL_TRANSFORM_MENU:
result := FTextFile.HasSelection;
end;
end;
function TTextEditor.ControlInSelection: boolean;
var
FirstPoint, SecondPoint: TPoint;
i: Integer;
begin
result := false;
if not FTextFile.ControlAware then Exit;
FTextFile.CaretPos.GetSelBdry(FirstPoint, SecondPoint);
for i := FirstPoint.Y to SecondPoint.Y do
if LineIsControl(i) then
Exit(true);
end;
procedure TTextEditor.CopyAll;
begin
Clipboard.AsText := GetText;
end;
procedure TTextEditor.CopySelection(const ANewPos: TPoint);
var
S: string;
begin
if FTextFile.IsCharSel(ANewPos) then Exit;
TypeTimerEnd;
S := SelText;
FTextFile.CaretPos.SetPoint(ANewPos);
FTextFile.InsertText(S);
AddUndoRecord(SUndoMouseCopy, UID_DRAGDROP);
end;
procedure TTextEditor.CopyToClipboard;
begin
FTextFile.CopyToClipboard;
end;
procedure TTextEditor.FallbackFontsChange(Sender: TObject);
begin
BuildFontDataArray;
Invalidate;
end;
procedure TTextEditor.BalloonTimerTimer(Sender: TObject);
begin
FBalloonTimer.Enabled := false;
HideBalloon;
end;
procedure TTextEditor.UpdateSPI;
begin
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, FSPIScrollLines, 0);
end;
constructor TTextEditor.Create(AOwner: TComponent);
var
item, item2: TMenuItem;
begin
inherited;
FPDict := TDictionary<string, TFormattingProcessor>.Create;
FInsertionPoint := Point(-1, -1);
FWantReturn := true;
FWantTab := true;
FAllowBitmapPaste := false;
UpdateSPI;
FMultipleCarets := false;
SetLength(FCarets, 0);
FCaretAfterEOL := true;
FScrollBehaviour := sbDefault;
FIndentSize := 2;
FAutoIndent := true;
FVisualUpdateLock := 0;
FBitmapEffect := beNone;
FDisabledEffect := beGrayscale;
Width := 400;
Height := 200;
DoubleBuffered := true;
FNoVerifyFont := false;
FMultiCharReportView := false;
FASHyphenAsteriskToggle := false;
FMultiCharSelect := true;
FCliMultiOutput := false;
FValidPaintState := false;
FCliHistoryIndex := -1;
SetLength(FCliHistory, 0);
FPreserveDesiredColumn := false;
FScriptCounter := 0;
FAbortScript := false;
FScriptRunning := false;
FNotifyMsgDuration := DEFAULT_NOTIFICATION_MSG_DURATION;
SetLength(FNotifications, 0);
FSelectionBarBehaviour := sbbAutoMixed;
FTextFileOwner := tfoEditor;
FBorderColor := clSilver;
FRightLine := false;
FRightLinePos := 580;
FRightLineColor := clSilver;
FPrintSettings := TPrintSettings.Create;
FZoom := 100;
FRulerColor := clDefault;
FNoScrollToCaret := false;
FRulerWidth := DEFAULT_RULER_WIDTH;
FMarginLeft := DEFAULT_MARGIN_LEFT;
FMarginRight := DEFAULT_MARGIN_RIGHT;
FMarginTop := DEFAULT_MARGIN_TOP;
FMarginBottom := DEFAULT_MARGIN_BOTTOM;
FNextControlID := 0;
FCachedHorizontalExtent := 0;
FMultiSize := false;
FAutoHeight := true;
FLabelStyle := false;
FLabelEllipsis := true;
FTabLength := 2;
FBalloonTimer := TTimer.Create(nil);
FBalloonTimer.Enabled := false;
FBalloonTimer.Interval := 10000;
FBalloonTimer.OnTimer := BalloonTimerTimer;
FNumbersOnly := false;
FPasswordChar := #0;
FGLYPHBM := TBitmap.Create;
FFONTBM := TBitmap.Create;
FUnicodeFallback := true;
FFallbackFonts := TStringList.Create;
FFallbackFonts.OnChange := FallbackFontsChange;
FBorderType := btThemeBorder;
FStartOver := true;
FFndBkColor := clYellow;
FFndFgColor := clBlack;
FInputTransform := itNone;
FMessageInterface := true;
FAutoReplace := false;
FScrollPos := Point(0, 0);
FBracketHighlight := false;
FShowHiddenCharacters := false;
FLineHighlight := false;
FLineHighlightColor := DEFAULT_LINE_HIGHLIGHT_COLOR;
FBracketHighlightColor := DEFAULT_BRACKET_HIGHLIGHT_COLOR;
FDoubleClicking := false;
Cursor := crIBeam;
FUseSystemColors := true;
FBackgroundColor := clWhite;
FForegroundColor := clBlack;
FSelBackgroundColor := clBlack;
FSelForegroundColor := clWhite;
FLetterSpacing := 1;
FLineSpacing := 1;
FTextFile := TTextFile.Create;
ConnectTextFileToEditor;
FTextFile.AutoIndent := true;
FFont := TFont.Create;
VerifyFont;
FFont.OnChange := FontChange;
SetupColors;
FHandleHotkeys := true;
FHandleBookmarkHotkeys := true;
FBeepOnInputError := true;
FErrorMessageOnReadOnlyError := true;
FOverwrite := false;
FMatchBrackets := true;
FRulerFont := TFont.Create;
FRulerFont.OnChange := RulerFontChange;
ControlStyle := ControlStyle + [csPannable];
FTypeTimer := TTimer.Create(nil);
FTypeTimer.Enabled := false;
FTypeTimer.Interval := 2000;
FTypeTimer.OnTimer := TypeTimerTimer;
Screen.Cursors[crBlock] := LoadImage(hInstance, 'SELHOVER', IMAGE_CURSOR,
0, 0, LR_DEFAULTCOLOR);
Screen.Cursors[crBlockCopy] := LoadImage(hInstance, 'SELCOPY', IMAGE_CURSOR,
0, 0, LR_DEFAULTCOLOR);
Screen.Cursors[crHand] := LoadImage(hInstance, 'HAND', IMAGE_CURSOR, 0, 0,
LR_DEFAULTCOLOR);
Screen.Cursors[crHandHold] := LoadImage(hInstance, 'HANDHOLD', IMAGE_CURSOR,
0, 0, LR_DEFAULTCOLOR);
Screen.Cursors[crLineSel] := LoadImage(hInstance, 'LINESEL', IMAGE_CURSOR,
0, 0, LR_DEFAULTCOLOR);
FPopupMenu := TPopupMenu.Create(nil);
FPopupMenu.OnPopup := MenuPopup;
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuOpenURL;
item.Hint := SMenuOpenURLHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_OPEN_URL_AT_CARET;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := '-';
item.Tag := 0;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuUndo;
item.Hint := SMenuUndoHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_UNDO;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuRedo;
item.Hint := SMenuRedoHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_REDO;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := '-';
item.Tag := 0;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuCut;
item.Hint := SMenuCutHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_CUT;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuCopy;
item.Hint := SMenuCopyHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_COPY;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuPaste;
item.Hint := SMenuPasteHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_PASTE;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuClear;
item.Hint := SMenuClearHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_CLEAR_SELECTION;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := '-';
item.Tag := 0;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuSelectAll;
item.Hint := SMenuSelectAllHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_SELECT_ALL;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := '-';
item.Tag := 0;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuSetBookmark;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_BOOKMARK_SET_MENU;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuGotoBookmark;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_BOOKMARK_GO_MENU;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuClearBookmark;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_BOOKMARK_CLEAR_MENU;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := '-';
item.Tag := 0;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuClasses;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_CLASS_MENU;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuActivateControl;
item.Hint := SMenuActivateControlHint;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_ACTIVATE_CONTROL;
FPopupMenu.Items.Add(item);
item := TMenuItem.Create(FPopupMenu);
item.Caption := SMenuTransform;
item.OnClick := MenuItemMessage;
item.Tag := EDITOR_COMMAND_SEL_TRANSFORM_MENU;
FPopupMenu.Items.Add(item);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformUpperCase;
item2.Hint := SMenuTransformUpperCaseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_UPPER_CASE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformLowerCase;
item2.Hint := SMenuTransformLowerCaseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_LOWER_CASE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformInvertCase;
item2.Hint := SMenuTransformInvertCaseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_INVERT_CASE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformCamelCase;
item2.Hint := SMenuTransformCamelCaseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_CAMEL_CASE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformSentenceCase;
item2.Hint := SMenuTransformSentenceCaseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_SENTENCE_CASE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := '-';
item2.OnClick := MenuItemMessage;
item2.Tag := 0;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformReverse;
item2.Hint := SMenuTransformReverseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_REVERSE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformROT13;
item2.Hint := SMenuTransformROT13Hint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_ROT13;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformCaesar;
item2.Hint := SMenuTransformCaesarHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_CAESAR;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformVigenere;
item2.Hint := SMenuTransformVigenereHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_VIGENERE;
item.Add(item2);
item2 := TMenuItem.Create(item);
item2.Caption := SMenuTransformVigenereInverse;
item2.Hint := SMenuTransformVigenereInverseHint;
item2.OnClick := MenuItemMessage;
item2.Tag := EDITOR_COMMAND_SEL_VIGENERE or $00010000;
item.Add(item2);
FImagePopup := TPopupMenu.Create(nil);
item := TMenuItem.Create(FImagePopup);
item.Caption := SMenuCopyImage;
item.Hint := SMenuCopyImageHint;
item.OnClick := ImageMenuCommand;
item.Tag := IMAGE_COMMAND_COPY;
FImagePopup.Items.Add(item);
item := TMenuItem.Create(FImagePopup);
item.Caption := SMenuDeleteImage;
item.Hint := SMenuDeleteImageHint;
item.OnClick := ImageMenuCommand;
item.Tag := IMAGE_COMMAND_REMOVE;
FImagePopup.Items.Add(item);
item := TMenuItem.Create(FImagePopup);
item.Caption := SMenuChangeImage;
item.Hint := SMenuChangeImageHint;
item.OnClick := ImageMenuCommand;
item.Tag := IMAGE_COMMAND_CHANGE;
FImagePopup.Items.Add(item);
FRulerMenu := TPopupMenu.Create(nil);
item := TMenuItem.Create(FRulerMenu);
item.Caption := SMenuRulerProperties;
item.Hint := SMenuRulerPropertiesHint;
item.OnClick := RulerMenuCommand;
item.Tag := RULER_COMMAND_PROPERTIES;
FRulerMenu.Items.Add(item);
FDropMenu := TPopupMenu.Create(nil);
FDropMenuMove := TMenuItem.Create(FDropMenu);
FDropMenuMove.Caption := SMoveHere;
FDropMenu.Items.Add(FDropMenuMove);
FDropMenuCopy := TMenuItem.Create(FDropMenu);
FDropMenuCopy.Caption := SCopyHere;
FDropMenu.Items.Add(FDropMenuCopy);
item := TMenuItem.Create(FDropMenu);
item.Caption := '-';
FDropMenu.Items.Add(item);
item := TMenuItem.Create(FDropMenu);
item.Caption := SCancel;
FDropMenu.Items.Add(item);
UseDefaultFallbackFonts;
BuildFontDataArray;
FBlinkRemover := TTimer.Create(nil);
FBlinkRemover.Enabled := false;
FBlinkRemover.Interval := 500;
FBlinkRemover.OnTimer := BlinkRemoverTimer;
TabStop := true;
OleInitialize(nil);
CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER,
IID_IDropTargetHelper, FDropTargetHelper);
FXDRAG := Abs(GetSystemMetrics(SM_CXDRAG));
FYDRAG := Abs(GetSystemMetrics(SM_CYDRAG));
end;
procedure TTextEditor.ImageMenuCommand(Sender: TObject);
var
bm: TBitmap;
begin
if not (FImagePopup.PopupComponent is TImage) then Exit;
if not (Sender is TMenuItem) then Exit;
case TMenuItem(Sender).Tag of
IMAGE_COMMAND_COPY:
if TImage(FImagePopup.PopupComponent).Picture.Graphic is TIcon then
begin
bm := TBitmap.Create;
try
bm.SetSize(TImage(FImagePopup.PopupComponent).Picture.Width,
TImage(FImagePopup.PopupComponent).Picture.Height);
bm.Canvas.Draw(0, 0, TImage(FImagePopup.PopupComponent).Picture.Graphic);
Clipboard.Assign(bm);
finally
bm.Free;
end;
end
else
Clipboard.Assign(TImage(FImagePopup.PopupComponent).Picture);
IMAGE_COMMAND_REMOVE:
FTextFile.ClearLine(
GetLineFromControlID(GetIDFromControl(TControl(FImagePopup.PopupComponent))));
IMAGE_COMMAND_CHANGE:
with TOpenDialog.Create(nil) do
try
Options := [ofPathMustExist, ofFileMustExist];
Filter := SImageFilter;
Title := SOpenImageDialogCaption;
if Execute then
begin
TImage(FImagePopup.PopupComponent).Picture.LoadFromFile(FileName);
TextFileLineClassChange(Sender,
GetLineFromControlID(GetIDFromControl(TControl(FImagePopup.PopupComponent))));
end;
finally
Free;
end;
end;
end;
procedure TTextEditor.RulerPropertiesApply(Sender: TObject);
begin
if Sender is TRulerPropertiesFrm then
with TRulerPropertiesFrm(Sender) do
begin
RulerFont.Assign(PrFont);
RulerColor := PrColor;
RulerWidth := PrWidth;
end;
end;
procedure TTextEditor.RulerMenuCommand(Sender: TObject);
begin
if not (Sender is TMenuItem) then Exit;
case TMenuItem(Sender).Tag of
RULER_COMMAND_PROPERTIES:
with TRulerPropertiesFrm.Create(nil) do
try
PrFont.Assign(FRulerFont);
PrColor := FRulerColor;
PrWidth := FRulerWidth;
OnApply := RulerPropertiesApply;
ShowModal;
finally
Free;
end;
end;
end;
procedure TTextEditor.TextFileGetControlText(Sender: TObject; LineIndex: integer;
var ControlText: string);
var
ctl: TControl;
len: integer;
begin
ControlText := '';
ctl := GetControlFromLine(LineIndex);
if Assigned(ctl) then
begin
if ctl is TWinControl then
begin
SetLength(ControlText, 128);
len := GetWindowText(TWinControl(ctl).Handle, PChar(ControlText),
Length(ControlText));
SetLength(ControlText, len);
end
else
ControlText := SPicture;
end;
end;
procedure TTextEditor.TextFileBookmarksMoved(Sender: TObject);
begin
UpdateRuler;
if Assigned(FOnBookmarksMoved) then
FOnBookmarksMoved(Self);
end;
procedure TTextEditor.BlinkRemoverTimer(Sender: TObject);
begin
FBlinkRemover.Enabled := false;
if FMatchBrackets then
HighlightCurrentBracket;
end;
function TTextEditor.BookmarkUsed(AIndex: integer): boolean;
begin
result := not SamePoint(Bookmarks[AIndex], EMPTY_BOOKMARK);
end;
procedure TTextEditor.BuildFontDataArray;
var
i: Integer;
begin
FreeFontDataArray;
SetLength(FGlyphSets, 1 + FFallbackFonts.Count);
for i := low(FGlyphSets) to high(FGlyphSets) do
FGlyphSets[i] := nil;
if Screen.Fonts.IndexOf(FFont.Name) <> -1 then
GetFontChrs(FFont.Name, FGlyphSets[0]);
for i := 0 to FFallbackFonts.Count - 1 do
if Screen.Fonts.IndexOf(FFallbackFonts[i]) <> -1 then
GetFontChrs(FFallbackFonts[i], FGlyphSets[i + 1]);
end;
procedure TTextEditor.FreeFontDataArray;
var
i: Integer;
begin
for i := low(FGlyphSets) to high(FGlyphSets) do
if FGlyphSets[i] <> nil then
FreeMem(FGlyphSets[i]);
SetLength(FGlyphSets, 0);
end;
procedure TTextEditor.TypeTimerEnd;
begin
if FTypeTimer.Enabled then
TypeTimerTimer(Self);
end;
procedure TTextEditor.TypeTimerTimer(Sender: TObject);
begin
FTypeTimer.Enabled := false;
AddUndoRecord(SUndoTyped, UID_TYPING);
end;
procedure TTextEditor.PostType;
begin
FTypeTimer.Enabled := false;
FTypeTimer.Enabled := true;
end;
procedure TTextEditor.Print(AFirstLine, ALastLine: integer);
begin
Print(ExtractFileName(FTextFile.FileName), AFirstLine, ALastLine);
end;
procedure TTextEditor.PrintSelection(const ATitle: string);
var
FirstPoint, SecondPoint: TPoint;
begin
if not FTextFile.HasSelection then Exit;
FTextFile.CaretPos.GetSelBdry(FirstPoint, SecondPoint);
Print(ATitle, FirstPoint.Y, SecondPoint.Y);
end;
procedure TTextEditor.PrintSelection;
begin
PrintSelection(ExtractFileName(FTextFile.FileName));
end;
procedure TTextEditor.PushEditorState;
begin
TypeTimerEnd;
if Assigned(FTextFile) then
begin
if Assigned(FFormattingProcessor) then
FTextFile.EditorState.FormattingProcessor := FFormattingProcessor.ClassName
else
FTextFile.EditorState.FormattingProcessor := '';
FTextFile.EditorState.ScrollPos := FScrollPos;
FTextFile.EditorState.MultiSize := FMultiSize;
FTextFile.EditorState.Overwrite := FOverwrite;
FTextFile.EditorState.HiddenChrs := FShowHiddenCharacters;
FTextFile.EditorState.RulerVisible := RulerVisible;
FTextFile.EditorState.ZoomLevel := FZoom;
if Assigned(FFormattingProcessor) then
FTextFile.EditorState.FFPCacheLen := FFormattingProcessor.GetCache(FTextFile.EditorState.FFPCache)
else
begin
FTextFile.EditorState.FFPCacheLen := 0;
FTextFile.EditorState.FFPCache := nil;
end;
FTextFile.EditorState.Valid := true;
end;
end;
function TTextEditor.QueryContinueDrag(fEscapePRessed: BOOL;
grfKeyState: Longint): HRESULT;
begin
if fEscapePressed then
result := DRAGDROP_S_CANCEL
else if (grfKeyState and FDragButtonOLE) = 0 then
result := DRAGDROP_S_DROP
else
result := S_OK;
end;
procedure TTextEditor.Print(const ATitle: string;
AFirstLine: integer = 0; ALastLine: integer = -1);
var
x, y: integer;
px, py: integer;
fs: TSize;
WrapList: TIntegerDynArray;
LineLength, ChrsPerLine: integer;
procedure CheckNewPage;
begin
if py + fs.cy > Printer.PageHeight - FPrintSettings.VerticalMargin then
begin
Printer.NewPage;
py := FPrintSettings.VerticalMargin;
end;
end;
function WrapNow: boolean;
function ShouldWrapAt(X: integer): boolean;
var
i: Integer;
begin
result := false;
for i := low(WrapList) to high(WrapList) do
if WrapList[i] = X then
Exit(true);
end;
begin
result := FPrintSettings.WordWrap and
(
((not FPrintSettings.NiceWordWrap) and (px > Printer.PageWidth - FPrintSettings.HorizontalMargin))
or
(FPrintSettings.NiceWordWrap and (ShouldWrapAt(x)))
)
end;
function Scale(const ASize: TSize): TSize;
begin
result.cx := ASize.cx * 6;
result.cy := ASize.cy * 6;
end;
var
ctl: TControl;
begin
if ALastLine = -1 then ALastLine := LineCount - 1;
NotifyApp(EN_PRINTING);
if Assigned(FOnPrintBegin) then
FOnPrintBegin(Self, ALastLine - AFirstLine + 1);
Enabled := false;
try
with Printer do
begin
BeginDoc;
Title := ATitle;
py := FPrintSettings.VerticalMargin;
for y := AFirstLine to ALastLine do
begin
ApplyFont(LineClasses[y], Canvas);
if LineIsControl(y) then
fs := Scale(GetLineControlSize(y))
else
fs := Canvas.TextExtent('M');
CheckNewPage;
px := FPrintSettings.HorizontalMargin;
LineLength := FTextFile.VirtualLineWidths[y];
ChrsPerLine := (PageWidth - 2*FPrintSettings.HorizontalMargin) div fs.cx;
if FPrintSettings.WordWrap then
begin
if FPrintSettings.NiceWordWrap then
FTextFile.FindWhereToWrap(y, ChrsPerLine, WrapList)
else
SetLength(WrapList, 0);
end;
for x := 0 to LineLength - 1 do
begin
if WrapNow then
begin
inc(py, fs.cy + LineSpacing);
CheckNewPage;
px := FPrintSettings.HorizontalMargin;
if FPrintSettings.ShowWordWrapIcon then
begin
Canvas.Font.Color := FPrintSettings.WordWrapIconColor;
Canvas.Font.Style := [];
Canvas.TextOut(px - 3 * fs.cx div 2, py, FPrintSettings.WordWrapIcon);
end;
end;
if LineIsControl(y) then
begin
ctl := GetControlFromLine(y);
if ctl is TWinControl then
with TBitmap.Create do
try
SetSize(ctl.Width, ctl.Height);
TWinControl(ctl).PaintTo(Canvas, 0, 0);
StretchBlt(Printer.Handle, px, py, fs.cx, fs.cy,
Canvas.Handle, 0, 0, Width, Height, SRCCOPY);
finally
Free;
end
else if ctl is TGraphicControl then
with TBitmap.Create do
try
SetSize(ctl.Width, ctl.Height);
Canvas.Lock;
TGraphicControl(ctl).Perform(WM_PAINT, Canvas.Handle, 0);
Canvas.Unlock;
StretchBlt(Printer.Handle, px, py, fs.cx, fs.cy,
Canvas.Handle, 0, 0, Width, Height, SRCCOPY);
finally
Free;
end
end
else
begin
ReapplyFont(Canvas);
ApplyInteractiveFormatting(x, y, Canvas);
Canvas.TextOut(px, py, FTextFile.Character[y, x]);
end;
inc(px, fs.cx);
end;
inc(py, fs.cy);
if Assigned(FOnPrintProgress) then
if not FOnPrintProgress(Self, y - AFirstLine + 1, ALastLine - AFirstLine + 1) then
begin
Abort;
SysUtils.Abort;
end;
end;
EndDoc;
end;
finally
Enabled := true;
RemoveNotification(EN_PRINTING);
if Assigned(FOnPrintEnd) then
FOnPrintEnd(Self);
end;
end;
procedure TTextEditor.MenuPopup(Sender: TObject);
var
i, j: Integer;
subitem: TMenuItem;
URL: string;
begin
for i := 0 to FPopupMenu.Items.Count - 1 do
begin
FPopupMenu.Items[i].Enabled := CommandEnabled(FPopupMenu.Items[i].Tag);
FPopupMenu.Items[i].Visible := CommandVisible(FPopupMenu.Items[i].Tag);
case FPopupMenu.Items[i].Tag of
EDITOR_COMMAND_OPEN_URL_AT_CARET:
if GetURLAtCaret(URL) then
FPopupMenu.Items[i].Hint := Format(SMenuOpenURLHint, [URL]);
EDITOR_COMMAND_SEL_TRANSFORM_MENU:
for j := 0 to FPopupMenu.Items[i].Count - 1 do
begin
FPopupMenu.Items[i].Items[j].Enabled := CommandEnabled(FPopupMenu.Items[i].Items[j].Tag);
FPopupMenu.Items[i].Items[j].Visible := CommandVisible(FPopupMenu.Items[i].Items[j].Tag);
end;
EDITOR_COMMAND_BOOKMARK_SET_MENU:
begin
FPopupMenu.Items[i].Clear;
for j := 0 to BookmarkCount - 1 do
begin
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := GetBookmarkDescr(j);
subitem.Hint := SMenuSetBookmarkItemHint;
if InRange(j, 1, 9) then
subitem.ShortCut := ShortCut(ord('0') + j, [ssShift, ssCtrl]);
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_BOOKMARK_SET or (j shl 16);
FPopupMenu.Items[i].Add(subitem);
end;
end;
EDITOR_COMMAND_BOOKMARK_GO_MENU:
begin
FPopupMenu.Items[i].Clear;
for j := 0 to BookmarkCount - 1 do
begin
if not BookmarkUsed(j) then Continue;
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := GetBookmarkDescr(j);
subitem.Hint := SMenuGotoBookmarkItemHint;
if InRange(j, 1, 9) then
subitem.ShortCut := ShortCut(ord('0') + j, [ssCtrl]);
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_BOOKMARK_GO or (j shl 16);
FPopupMenu.Items[i].Add(subitem);
end;
if UsedBookmarkCount = 0 then
begin
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := SMenuNoBookmarksSetParen;
subitem.Enabled := false;
FPopupMenu.Items[i].Add(subitem);
end;
end;
EDITOR_COMMAND_BOOKMARK_CLEAR_MENU:
begin
FPopupMenu.Items[i].Clear;
for j := 0 to BookmarkCount - 1 do
begin
if not BookmarkUsed(j) then Continue;
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := GetBookmarkDescr(j);
subitem.Hint := SMenuClearBookmarkItemHint;
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_BOOKMARK_CLEAR or (j shl 16);
FPopupMenu.Items[i].Add(subitem);
end;
if UsedBookmarkCount = 0 then
begin
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := SMenuNoBookmarksSetParen;
subitem.Enabled := false;
FPopupMenu.Items[i].Add(subitem);
end
else
begin
subitem := TMenUItem.Create(FPopupMenu.Items[i]);
subitem.Caption := '-';
FPopupMenu.Items[i].Add(subitem);
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := SMenuClearAllBookmarks;
subitem.Hint := SMenuClearAllBookmarksHint;
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_BOOKMARK_CLEAR_ALL;
FPopupMenu.Items[i].Add(subitem);
end;
end;
EDITOR_COMMAND_CLASS_MENU:
begin
FPopupMenu.Items[i].Clear;
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := SMenuUseNoClass;
subitem.Hint := SMenuUseNoClassHint;
subitem.Checked := Length(LineClasses[CaretPos.Y]) = 0;
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_CLASS_REMOVE;
FPopupMenu.Items[i].Add(subitem);
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := '-';
FPopupMenu.Items[i].Add(subitem);
for j := 0 to ClassCount - 1 do
begin
subitem := TMenuItem.Create(FPopupMenu.Items[i]);
subitem.Caption := Classes[j].Name;
subitem.Hint := SMenuClassesItemHint;
subitem.Checked := SameStr(LineClasses[CaretPos.Y], Classes[j].Name);
subitem.OnClick := MenuItemMessage;
subitem.Tag := EDITOR_COMMAND_CLASS_USE or (j shl 16);
FPopupMenu.Items[i].Add(subitem);
end;
end;
end;
end;
end;
function TTextEditor.MakeLinesUnique: boolean;
begin
TypeTimerEnd;
result := FTextFile.MakeLinesUnique;
if result then
AddUndoRecord(SUndoMadeLinesUnique, UID_UNKNOWN);
end;
procedure TTextEditor.MakeUndoRoot;
begin
FTypeTimer.Enabled := false;
FTextFile.ClearUndoHistory;
AddUndoRecord(SUndoInitialText, UID_UNKNOWN);
end;
function TTextEditor.MaxLineWidth: integer;
var
i: Integer;
begin
result := 0;
for i := 0 to FTextFile.LineCount - 1 do
if LineWidths(i) > result then
result := LineWidths(i);
end;
procedure TTextEditor.MenuItemMessage(Sender: TObject);
begin
if not Enabled then Exit;
if Sender is TMenuItem then
with Sender as TMenuItem do
EditorCommand(Tag);
end;
procedure TTextEditor.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := Params.Style or WS_HSCROLL or WS_VSCROLL or 0*WS_CLIPCHILDREN;
ControlStyle := ControlStyle - [csNeedsBorderPaint];
case FBorderType of
btNone: ;
btWin32ThinLine:
Params.Style := Params.Style or WS_BORDER;
btWin32SunkenEdge:
Params.ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE;
btThemeBorder:
begin
Params.ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE;
ControlStyle := ControlStyle + [csNeedsBorderPaint];
end;
btSimpleColor: ;
end;
end;
procedure TTextEditor.CreateWnd;
begin
inherited;
FHintWindow := CreateWindowEx(0, TOOLTIPS_CLASS, nil, WS_POPUP or TTS_ALWAYSTIP
or TTS_NOPREFIX or TTS_BALLOON, Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), Handle, 0, HInstance, nil);
if FHintWindow <> 0 then
begin
FToolInfo.cbSize := sizeof(FToolInfo);
FToolInfo.uFlags := TTF_TRANSPARENT or TTF_CENTERTIP or TTF_IDISHWND or
TTF_TRACK or TTF_ABSOLUTE;
FToolInfo.hwnd := Handle;
FToolInfo.uId := Handle;
FToolInfo.hInst := 0;
FToolInfo.lpszText := '';
SendMessage(FHintWindow, TTM_ADDTOOL, 0, LParam(@FToolInfo));
end;
OleCheck(RegisterDragDrop(Handle, Self));
end;
function TTextEditor.GetTotalVerticalExtent: integer;
begin
if FMultiSize then
result := FAccumLineHeights[FTextFile.LineCount - 1] + FFontSizes[FTextFile.LineCount - 1].cy
else
result := FFontSize.cy * FTextFile.LineCount;
end;
function TTextEditor.GetURLAtCaret(out AURL: string): boolean;
begin
result := FTextFile.GetURLAtCaret(AURL);
end;
function TTextEditor.GetUsedBookmarkCount: integer;
begin
result := FTextFile.UsedBookmarkCount;
end;
function TTextEditor.GetTotalHorizontalExtent: integer;
begin
if FMultiSize then
result := FCachedHorizontalExtent
else
result := FFontSize.cx * FTextFile.MaxLineWidth
end;
function TTextEditor.IsCaretVisible: boolean;
begin
result := FCaretVisible and PtInRect(TextContentRect, PhysicalPixelAtChar(GetCaretPos));
end;
procedure TTextEditor.UpdateScrollBars;
var
ScrollInfo: TScrollInfo;
OldVScroll, NewVScroll, OldHScroll, NewHScroll, OldCaretVisible: boolean;
begin
if SingleLine then
begin
ShowScrollBar(Handle, SB_BOTH, false);
Exit;
end;
OldVScroll := GetWindowLong(Handle, GWL_STYLE) and WS_VSCROLL <> 0;
OldHScroll := GetWindowLong(Handle, GWL_STYLE) and WS_HSCROLL <> 0;
OldCaretVisible := IsCaretVisible;
ScrollInfo.cbSize := sizeof(TScrollInfo);
ScrollInfo.fMask := SIF_ALL;
ScrollInfo.nMin := 0;
ScrollInfo.nMax := max(GetTotalVerticalExtent, FScrollPos.Y + ClientHeight - FMarginTop - FMarginBottom - 1);
ScrollInfo.nPage := max(0, ClientHeight - FMarginTop - FMarginBottom);
ScrollInfo.nPos := FScrollPos.Y;
SetScrollInfo(Handle, SB_VERT, ScrollInfo, true);
ScrollInfo.cbSize := sizeof(TScrollInfo);
ScrollInfo.fMask := SIF_ALL;
ScrollInfo.nMin := 0;
ScrollInfo.nMax := max(GetTotalHorizontalExtent, FScrollPos.X - FMarginLeft - FMarginRight + ClientWidth - 1);
ScrollInfo.nPage := max(0, ClientWidth - FMarginLeft - FMarginRight);
ScrollInfo.nPos := FScrollPos.X;
SetScrollInfo(Handle, SB_HORZ, ScrollInfo, true);
NewVScroll := GetWindowLong(Handle, GWL_STYLE) and WS_VSCROLL <> 0;
NewHScroll := GetWindowLong(Handle, GWL_STYLE) and WS_HSCROLL <> 0;
if OldCaretVisible and ((OldVScroll xor NewVScroll) or (OldHScroll xor NewHScroll)) then
ScrollToCaret;
end;
procedure TTextEditor.UpdateScrollMode;
var
OldScrollMode: boolean;
begin
FScrollMode := GetScrollMode;
OldScrollMode := HasNotificationMessage(EN_SCROLL_MODE);
if FScrollMode and not OldScrollMode then
NotifyApp(EN_SCROLL_MODE)
else if OldScrollMode and not FScrollMode then
RemoveNotification(EN_SCROLL_MODE);
end;
procedure TTextEditor.CutToClipboard;
begin
TypeTimerEnd;
FTextFile.CutToClipboard;
AddUndoRecord(SUndoCutToClipboard, UID_CUT);
end;
function TTextEditor.FPFileChangeNotification(ChangeType: TChangeType;
Data1, Data2, Data3, Data4: Integer): TChangeRecord;
var
TC1, TC2: cardinal;
begin
TC1 := GetTickCount;
result := FFormattingProcessor.FileChangeNotification(ChangeType, Data1, Data2, Data3, Data4);
TC2 := GetTickCount;
if TC2 - TC1 > 5000 then
if MessageBox(0, PChar(SFPSlowText), PChar(SFPSlowTitle), MB_ICONQUESTION or MB_YESNO) = ID_YES then
FormattingProcessor := nil;
end;
function TTextEditor.FPFromString(
const FPClassName: string): TFormattingProcessor;
begin
if not FPDict.TryGetValue(FPClassName, result) then
result := nil;
end;
procedure TTextEditor.TextFileChange(Sender: TObject; ChangeType: TChangeType;
Data1, Data2, Data3, Data4: Integer);
var
IFCR: TChangeRecord;
begin
if Assigned(FFormattingProcessor) then
begin
IFCR := FPFileChangeNotification(ChangeType, Data1, Data2, Data3, Data4);
with ChangeUnion(IFCR, MakeChangeRecord(ChangeType, Data1, Data2, Data3, Data4)) do
VisualUpdate(ChangeType, Data1, Data2, Data3, Data4);
end
else
VisualUpdate(ChangeType, Data1, Data2, Data3, Data4);
if FMultiSize then
RecomputeHorizontalExtent;
UpdateScrollBars;
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TTextEditor.TextFileInputError(Sender: TObject);
begin
if FBeepOnInputError then
beep;
NotifyAppWithTimer(EN_INPUT_ERROR);
end;
procedure TTextEditor.TextFileReadOnlyError(Sender: TObject);
begin
if FErrorMessageOnReadOnlyError then
MessageBox(Handle, PChar(SReadOnlyErrorText),
PChar(SReadOnlyErrorTitle), MB_ICONINFORMATION or MB_OK);
NotifyAppWithTimer(EN_READ_ONLY_ERROR);
end;
procedure TTextEditor.TextFileModified(Sender: TObject);
begin
if BalloonVisible and (ord(FBalloonPersistence) <= ord(bpModify)) then
HideBalloon;
if Assigned(FOnModified) then
FOnModified(Self);
end;
function TTextEditor.TransformSelection(
Transformation: TTextTransformFunc; const TransformName: string): boolean;
begin
result := FTextFile.HasSelection and (SelectionType = stLineBased);
if result then
begin
TypeTimerEnd;
FTextFile.InsertText(Transformation(SelText));
AddUndoRecord(Format(SUndoSelectionTransformed, [TransformName]), UID_UNKNOWN);
end;
end;
procedure TTextEditor.TransformText(Transformation: TTextTransformFunc;
const TransformName: string);
begin
TypeTimerEnd;
PlainText := Transformation(PlainText);
AddUndoRecord(Format(SUndoTextTransformed, [TransformName]), UID_UNKNOWN);
end;
procedure TTextEditor.TrimRight;
begin
TypeTimerEnd;
FTextFile.TrimRight;
AddUndoRecord(SUndoTrimRight, UID_UNKNOWN);
end;
procedure TTextEditor.TruncateAt(AIndex: integer; AChar: char;
PreserveChar: boolean; AReverse: boolean);
begin
TruncateAt(0, LineCount - 1, AIndex, AChar, PreserveChar, AReverse);
end;
procedure TTextEditor.TruncateAtInSelection(AIndex: integer; AChar: char;
PreserveChar: boolean; AReverse: boolean);
var
FirstLine, SecondLine: integer;
begin
FirstLine := min(CaretPos.Y, SelEndPos.Y);
SecondLine := max(CaretPos.Y, SelEndPos.Y);
TruncateAt(FirstLine, SecondLine, AIndex, AChar, PreserveChar, AReverse);
end;
procedure TTextEditor.TruncateAt(AFirstLine, ALastLine, AIndex: integer;
AChar: char; PreserveChar: boolean; AReverse: boolean);
begin
TypeTimerEnd;
FTextFile.TruncateAt(AFirstLine, ALastLine, AIndex, AChar, PreserveChar, AReverse);
AddUndoRecord(SUndoLinesTruncated, UID_UNKNOWN);
end;
function TTextEditor.GetLineComparer: TLineComparer;
begin
result := FTextFile.LineComparer;
end;
function TTextEditor.GetLineControlSize(LineIndex: integer): TSize;
var
i: Integer;
ID: integer;
begin
result := FFontSize;
if not (LineIsControl(LineIndex) and TryStrToInt(Copy(FTextFile.Lines[LineIndex],
Length(LINE_CONTROL_PREFIX) + 1), ID)) then
Exit;
for i := 0 to high(FLineControls) do
if (FLineControls[i].ID = ID) and Assigned(FLineControls[i].Control) then
begin
result.cx := FLineControls[i].Control.Width + 2*CARET_WIDTH;
result.cy := FLineControls[i].Control.Height;
break;
end;
end;
function TTextEditor.GetLineCount: integer;
begin
result := FTextFile.LineCount;
end;
function TTextEditor.GetLineFromControlID(ID: integer): integer;
var
i: Integer;
IDStr: string;
begin
result := -1;
IDStr := IntToStr(ID);
for i := 0 to FTextFile.LineCount - 1 do
if LineIsControl(i) and SameStr(Copy(FTextFile.Lines[i], Length(LINE_CONTROL_PREFIX) + 1), IDStr) then
Exit(i);
end;
procedure TTextEditor.ReapplyFont(ATo: TCanvas);
begin
if ATo = nil then ATo := Canvas;
ATo.Font.Size := FCurrentFormat.Size;
ATo.Font.Color := FCurrentFormat.Color;
ATo.Font.Style := FCurrentFormat.Style;
end;
procedure TTextEditor.RebuildLineCache;
var
nLines: integer;
i: integer;
ci: integer;
begin
NeedValidPaintState;
nLines := FTextFile.LineCount;
SetLength(FFontSizes, nLines);
for i := 0 to nLines - 1 do
begin
if SameStr(FTextFile.Classes[i], LINE_CONTROL_CLASS) then
FFontSizes[i] := GetLineControlSize(i)
else
begin
ci := GetClassIndex(FTextFile.Classes[i]);
if ci <> -1 then
FFontSizes[i] := FClassArray[ci].Format.BoxSize
else
FFontSizes[i] := FFontSize;
end;
end;
SetLength(FAccumLineHeights, nLines);
FAccumLineHeights[0] := 0;
for i := 1 to nLines - 1 do
FAccumLineHeights[i] := FAccumLineHeights[i - 1] + FFontSizes[i - 1].cy;
end;
procedure TTextEditor.RecomputeHorizontalExtent;
begin
if FMultiSize then
FCachedHorizontalExtent := MaxLineWidth
else
FCachedHorizontalExtent := FFontSize.cx * FTextFile.MaxLineWidth;
end;
procedure TTextEditor.TextFileLineChange(Sender: TObject;
LineChangeType: TLineChangeType; From: integer);
begin
if FMultiSize then
begin
RebuildLineCache;
UpdateLineControls;
end;
if RulerVisible then
if LineChangeType = lctAppend then
UpdateRulerLine(LineCount - 1)
else
UpdateRuler;
end;
procedure TTextEditor.TextFileLineClassChange(Sender: TObject;
LineIndex: integer);
begin
if FMultiSize then
begin
RebuildLineCache;
RecomputeHorizontalExtent;
UpdateScrollBars;
VisualUpdate(ctLineRange, LineIndex, FTextFile.LineCount - 1, 0, 0);
VisualUpdate(ctPostFile, 0, 0, 0, 0);
UpdateLineControls;
UpdateRuler;
end
else
VisualUpdate(ctLine, LineIndex, 0, 0, 0);
if CaretPos.Y = LineIndex then
UpdateCaret
else
DoSetCaretPos;
end;
procedure TTextEditor.TextFileControlRemoved(Sender: TObject;
ControlID: integer);
var
i: Integer;
j: Integer;
begin
Exit;
for i := 0 to high(FLineControls) do
if FLineControls[i].ID = ControlID then
begin
FLineControls[i].Control.Free;
for j := i to high(FLineControls) - 1 do
FLineControls[j] := FLineControls[j + 1];
SetLength(FLineControls, Length(FLineControls) - 1);
break;
end;
end;
function TTextEditor.ClassExists(const AClassName: string): boolean;
begin
result := GetClassIndex(AClassName) <> -1;
end;
function TTextEditor.ClassExists(const AClassName: string;
out Index: integer): boolean;
begin
Index := GetClassIndex(AClassName);
result := Index <> -1;
end;
procedure TTextEditor.Clear;
begin
Escape(true);
TypeTimerEnd;
FTextFile.Clear;
FTextFile.ControlAware := false;
AddUndoRecord(SUndoTextCleared, UID_UNKNOWN);
end;
procedure TTextEditor.ClearBookmarks;
begin
TypeTimerEnd;
FTextFile.ClearBookmarks;
AddUndoRecord(SUndoBookmarksCleared, UID_UNKNOWN);
UpdateRuler;
end;
procedure TTextEditor.ClearBracketHighlight;
begin
if FBracketHighlight then
begin
FBracketHighlight := false;
VisualUpdate(ctTwoChars, FBracketPos1.Y, FBracketPos1.X, FBracketPos2.Y,
FBracketPos2.X);
end;
end;
procedure TTextEditor.ClearClasses;
begin
SetLength(FClassArray, 0);
end;
procedure TTextEditor.ClearControls;
var
i: Integer;
begin
for i := 0 to high(FLineControls) do
FLineControls[i].Control.Free;
SetLength(FLineControls, 0);
end;
procedure TTextEditor.SetBracketHighlight(const PointA, PointB: TPoint);
begin
if FBracketHighlight then
ClearBracketHighlight;
FBracketHighlight := true;
FBracketPos1 := PointA;
FBracketPos2 := PointB;
VisualUpdate(ctTwoChars, FBracketPos1.Y, FBracketPos1.X, FBracketPos2.Y,
FBracketPos2.X);
end;
procedure TTextEditor.HighlightCurrentBracket;
var
BracketPos: TPoint;
begin
ClearBracketHighlight;
BracketPos := FTextFile.MatchBracket(FTextFile.CaretPos.Data);
if BracketPos.Y <> -1 then
SetBracketHighlight(CaretPos, BracketPos);
end;
procedure TTextEditor.TextFileCaretPosChange(Sender: TObject);
begin
if (not FPreserveDesiredColumn) and FMultiSize then
FDesiredColumn := FTextFile.CaretPos.X * FFontSizes[FTextFile.CaretPos.Y].cx;
if BalloonVisible and (ord(FBalloonPersistence) <= ord(bpCaretPos)) then
HideBalloon;
ChangeCursor;
if FMultiSize and (FTextFile.CaretPos.Y <> FOldCaretPosY) then
UpdateCaret;
if FTextFile.CaretPos.Y <> FOldCaretPosY then
begin
UpdateRulerLine(FTextFile.CaretPos.Y);
UpdateRulerLine(FOldCaretPosY);
end;
if (not ScrollToCaret) and Focused then
DoSetCaretPos;
if FLineHighlight and (FTextFile.CaretPos.Y <> FOldCaretPosY) then
begin
VisualUpdate(ctLine, FOldCaretPosY, 0, 0, 0);
VisualUpdate(ctLine, FTextFile.CaretPos.Y, 0, 0, 0);
end;
if FMatchBrackets then
HighlightCurrentBracket;
if FListBoxMode and (FTextFile.CaretPos.Y <> FOldCaretPosY) then
if Assigned(FOnListBoxChange) then
FOnListBoxChange(Self);
FOldCaretPosY := FTextFile.CaretPos.Y;
if FMultiCharSelect and HasNotificationMessage(EN_MULTICHAR) then
RemoveNotification(EN_MULTICHAR);
if Assigned(FOnSelChange) then
FOnSelChange(Self);
end;
function TTextEditor.ScrollToCaret: boolean;
var
CaretPixel: TPoint;
NewX, NewY: integer;
_ScrollExtra: integer;
begin
if FNoScrollToCaret then Exit(false);
CaretPixel := VirtualPixelAtChar(FTextFile.CaretPos.Data);
if (SCROLL_EXTRA < ClientWidth div 2) and not SingleLine then
_ScrollExtra := SCROLL_EXTRA
else
_ScrollExtra := 0;
if FScrollPos.X + ClientWidth - FMarginLeft - FMarginRight < CaretPixel.X + CARET_WIDTH then
NewX := CaretPixel.X - ClientWidth + FMarginLeft + FMarginRight + CARET_WIDTH + _ScrollExtra
else if FScrollPos.X > CaretPixel.X then
NewX := Max(CaretPixel.X - _ScrollExtra, 0)
else
NewX := FScrollPos.X;
if FScrollPos.Y + ClientHeight - FMarginTop - FMarginBottom < CaretPixel.Y + FFontSize.cy then
NewY := CaretPixel.Y - ClientHeight + FMarginTop + FMarginBottom + FFontSize.cy
else if FScrollPos.Y > CaretPixel.Y then
NewY := CaretPixel.Y
else
NewY := FScrollPos.Y;
result := (NewX <> FScrollPos.X) or (NewY <> FScrollPos.Y);
if result then
SetScrollPosXY(NewX, NewY);
end;
procedure TTextEditor.TextFileCaretPosSelChange(Sender: TObject;
ChangeType: TChangeType; Data1, Data2, Data3, Data4: Integer);
begin
VisualUpdate(ChangeType, Data1, Data2, Data3, Data4);
end;
procedure TTextEditor.WMContextMenu(var Message: TWMContextMenu);
var
p: TPoint;
PmMain: TPopupMenu;
PmRuler: TPopupMenu;
ctl: TControl;
begin
if Assigned(PopupMenu) then
PmMain := PopupMenu
else
PmMain := FPopupMenu;
if Assigned(RulerPopupMenu) then
PmRuler := RulerPopupMenu
else
PmRuler := FRulerMenu;
if (Message.XPos = -1) and (Message.YPos = -1) then
if Windows.GetCaretPos(p) then
with ClientToScreen(p) do
if FMultiSize then
PmMain.Popup(x, y + FFontSizes[CaretPos.Y].cy)
else
PmMain.Popup(x, y + FFontSize.cy)
else
with ClientToScreen(Point(ClientWidth div 2, ClientHeight div 2)) do
PmMain.Popup(x, Y)
else
begin
p := ScreenToClient(SmallPointToPoint(Message.Pos));
if (p.X >= ClientWidth) or (p.Y >= ClientHeight) then
begin
inherited;
Exit;
end
else if p.X >= GetFunctionalSelectionBarWidth then
begin
ctl := ControlAtPos(p, true);
if ctl <> nil then
Message.Result := ctl.Perform(WM_CONTEXTMENU, TMessage(Message).WParam, TMessage(Message).LParam);
if Message.Result = 0 then
PmMain.Popup(Message.XPos, Message.YPos)
end
else if p.X < FRulerWidth then
PmRuler.Popup(Message.XPos, Message.YPos);
end;
Message.Result := 1;
end;
procedure TTextEditor.WMEnable(var Message: TWMEnable);
begin
inherited;
SetupColors;
Invalidate;
end;
procedure TTextEditor.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result := 1;
end;
procedure TTextEditor.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or
IfThen(FWantTab, DLGC_WANTTAB) or IfThen(FWantReturn, DLGC_WANTALLKEYS);
end;
procedure TTextEditor.WMHScroll(var Message: TWMHScroll);
var
ScrollInfo: TScrollInfo;
begin
inherited;
case Message.ScrollCode of
SB_LEFT:
SetScrollPosX(0);
SB_RIGHT:
SetScrollPosX(FFontSize.cx * FTextFile.MaxLineWidth);
SB_LINELEFT:
SetScrollPosX(FScrollPos.X - FFontSize.cx);
SB_LINERIGHT:
SetScrollPosX(FScrollPos.X + FFontSize.cx);
SB_PAGELEFT:
SetScrollPosX(FScrollPos.X - ClientWidth + FMarginLeft + FMarginRight);
SB_PAGERIGHT:
SetScrollPosX(FScrollPos.X + ClientWidth - FMarginLeft - FMarginRight);
SB_THUMBTRACK:
begin
ScrollInfo.cbSize := sizeof(TScrollInfo);
ScrollInfo.fMask := SIF_TRACKPOS;
GetScrollInfo(Handle, SB_HORZ, ScrollInfo);
SetScrollPosX(ScrollInfo.nTrackPos);
end;
end;
end;
procedure TTextEditor.SetScrollPosX(Value: integer);
var
OldScrollPos, diff: integer;
TCR: TRect;
begin
if Value < 0 then Value := 0;
OldScrollPos := FScrollPos.X;
FScrollPos.X := Value;
diff := OldScrollPos - Value;
if diff = 0 then Exit;
UpdateScrollBars;
TCR := TextContentRect;
if abs(diff) < ClientWidth - FMarginLeft - FMarginRight then
ScrollWindowEx(Handle, diff, 0, @TCR, @TCR, 0, nil, SW_INVALIDATE or SW_SCROLLCHILDREN)
else
Invalidate;
DoSetCaretPos;
if FTextFile.ControlAware then
UpdateLineControls;
MoveBalloonPostScroll;
end;
procedure TTextEditor.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
Escape(true);
DestroyCaret;
FCaretVisible := false;
if SingleLine and FLabelStyle then Invalidate;
end;
procedure TTextEditor.WMMouseHWheel(var Message: TWMMouseWheel);
begin
if (GetKeyState(VK_LMENU) and $8000) <> 0 then
begin
if Message.WheelDelta < 0 then
FTextFile.Left
else
FTextFile.Right;
Exit;
end;
if (Message.Keys and MK_SHIFT) <> 0 then
SetScrollPosX(FScrollPos.X + Sign(Message.WheelDelta))
else
SetScrollPosX(FScrollPos.X + round(FFontSize.cx * Message.WheelDelta / WHEEL_DELTA));
Message.Result := 0;
end;
procedure TTextEditor.WMMouseWheel(var Message: TWMMouseWheel);
var
ShiftState: TShiftState;
begin
ShiftState := [];
if Message.Keys and MK_CONTROL <> 0 then
Include(ShiftState, ssCtrl);
if Message.Keys and MK_LBUTTON <> 0 then
Include(ShiftState, ssLeft);
if Message.Keys and MK_MBUTTON <> 0 then
Include(ShiftState, ssMiddle);
if Message.Keys and MK_RBUTTON <> 0 then
Include(ShiftState, ssRight);
if Message.Keys and MK_SHIFT <> 0 then
Include(ShiftState, ssShift);
if IsKeyDown(VK_LMENU) then
Include(ShiftState, ssAlt);
if ssCtrl in ShiftState then
begin
if Message.WheelDelta < 0 then
ZoomOut
else
ZoomIn;
Exit;
end;
if ssAlt in ShiftState then
begin
if Message.WheelDelta < 0 then
FTextFile.Down
else
FTextFile.Up;
Update;
Exit;
end;
if (ssShift in ShiftState) or (FScrollBehaviour = sbPixel) then
SetScrollPosY(FScrollPos.Y - Sign(Message.WheelDelta), true)
else if FScrollBehaviour = sbLine then
SetScrollPosY(FScrollPos.Y - round(FFontSize.cy * Message.WheelDelta / WHEEL_DELTA), true)
else
if FSPIScrollLines >= 0 then
SetScrollPosY(FScrollPos.Y - round(FFontSize.cy * FSPIScrollLines * Message.WheelDelta / WHEEL_DELTA), true)
else if FSPIScrollLines = -1 then
SetScrollPosY(FScrollPos.Y - round(ClientHeight * Message.WheelDelta / WHEEL_DELTA), true);
Message.Result := 0;
with ScreenToClient(Message.Pos) do
ChangeCursor(ShiftState, Y, X);
end;
procedure TTextEditor.WMNCActivate(var Message: TWMNCActivate);
begin
inherited;
end;
procedure TTextEditor.WMNCCalcSize(var Message: TWMNCCalcSize);
var
R: TRect;
begin
DefaultHandler(Message);
R := Message.CalcSize_Params.rgrc0;
InflateRect(R, -BorderWidth, -BorderWidth);
Message.CalcSize_Params.rgrc0 := R;
Message.Result := 0;
end;
procedure TTextEditor.WMNCHitTest(var Message: TWMNCHitTest);
var
pnt: TPoint;
WS: integer;
R: TRect;
ClientWidth, ClientHeight: integer;
begin
if FBorderType = btSimpleColor then
begin
Windows.GetClientRect(Handle, R);
ClientWidth := R.Right - R.Left;
ClientHeight := R.Bottom - R.Top;
pnt := ScreenToClient(SmallPointToPoint(Message.Pos));
WS := GetWindowLong(Handle, GWL_STYLE);
if PtInRect(R, pnt) then
Message.result := HTCLIENT
else if ((WS and WS_VSCROLL) <> 0) and
InRange(pnt.X, ClientWidth, ClientWidth + GetSystemMetrics(SM_CXVSCROLL)) and
InRange(pnt.Y, 0, ClientHeight) then
Message.Result := HTVSCROLL
else if ((WS and WS_HSCROLL) <> 0) and
InRange(pnt.Y, ClientHeight, ClientHeight + GetSystemMetrics(SM_CYHSCROLL)) and
InRange(pnt.X, 0, ClientWidth) then
Message.Result := HTHSCROLL
else
Message.Result := HTBORDER;
end
else
inherited;
end;
procedure TTextEditor.WMNCPaint(var Message: TWMNCPaint);
var
dc: HDC;
WS: integer;
OldColor: TColor;
R: TRect;
Width, Height: integer;
begin
if FBorderType = btSimpleColor then
begin
DefaultHandler(Message);
GetWindowRect(Handle, R);
Width := R.Right - R.Left;
Height := R.Bottom - R.Top;
OldColor := Brush.Color;
dc := GetWindowDC(Handle);
try
WS := GetWindowLong(Handle, GWL_STYLE);
if ((WS and WS_VSCROLL) <> 0) and ((WS and WS_HSCROLL) <> 0) then
begin
Brush.Color := clBtnFace;
FillRect(dc, Rect(Width - BorderWidth - GetSystemMetrics(SM_CXVSCROLL),
Height - BorderWidth - GetSystemMetrics(SM_CXHSCROLL),
Width - BorderWidth,
Height - BorderWidth),
Brush.Handle);
end;
ExcludeClipRect(dc, BorderWidth, BorderWidth,
Width - BorderWidth, Height - BorderWidth);
Brush.Color := FBorderColor;
FillRect(dc, Rect(0, 0, Width, Height), Brush.Handle);
Message.Result := 0;
finally
ReleaseDC(Handle, dc);
Brush.Color := OldColor;
end;
end
else
inherited;
end;
procedure TTextEditor.WMPaint(var Message: TWMPaint);
begin
if Assigned(FDropTargetHelper) and Assigned(FDragDataObj) then
FDropTargetHelper.Show(false);
inherited;
if Assigned(FDropTargetHelper) and Assigned(FDragDataObj) then
FDropTargetHelper.Show(true);
end;
procedure TTextEditor.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
NeedValidPaintState;
UpdateCaret;
UpdateScrollMode;
if SingleLine and FLabelStyle then
Invalidate;
end;
procedure TTextEditor.WMSize(var Message: TWMSize);
begin
inherited;
UpdateScrollBars;
DoSetCaretPos;
end;
procedure TTextEditor.WMVScroll(var Message: TWMVScroll);
var
ScrollInfo: TScrollInfo;
begin
inherited;
case Message.ScrollCode of
SB_TOP:
SetScrollPosY(0);
SB_BOTTOM:
SetScrollPosY(FFontSize.cy * FTextFile.LineCount);
SB_LINEUP:
SetScrollPosY(FScrollPos.Y - FFontSize.cy);
SB_LINEDOWN:
SetScrollPosY(FScrollPos.Y + FFontSize.cy);
SB_PAGEUP:
SetScrollPosY(FScrollPos.Y - ClientHeight + FMarginTop + FMarginBottom);
SB_PAGEDOWN:
SetScrollPosY(FScrollPos.Y + ClientHeight - FMarginTop - FMarginBottom);
SB_THUMBTRACK:
begin
ScrollInfo.cbSize := sizeof(TScrollInfo);
ScrollInfo.fMask := SIF_TRACKPOS;
GetScrollInfo(Handle, SB_VERT, ScrollInfo);
SetScrollPosY(ScrollInfo.nTrackPos);
end;
end;
end;
procedure TTextEditor.WndProc(var Message: TMessage);
function REFontInc(Old, Delta: integer): integer;
function rnd(x: real): integer;
begin
if Delta > 0 then
result := ceil(x)
else
result := floor(x);
end;
begin
result := Old + Delta;
if result < 1 then
result := 1
else if result <= 28 then
result := 2*rnd(result / 2)
else if result <= 36 then
result := 36
else if result <= 48 then
result := 48
else if result <= 72 then
result := 72
else if result <= 80 then
result := 80
else
result := 10*rnd(result / 10);
if result > 1638 then
result := 1638;
end;
const
ECM_FIRST = $1500;
EM_SETCUEBANNER = ECM_FIRST + 1;
EM_GETCUEBANNER = ECM_FIRST + 2;
EM_SHOWBALLOONTIP = ECM_FIRST + 3;
EM_HIDEBALLOONTIP = ECM_FIRST + 4;
EM_GETSCROLLPOS = WM_USER + 221;
EM_SETSCROLLPOS = WM_USER + 222;
EM_GETTOUCHOPTIONS = WM_USER + 310;
EM_GETZOOM = WM_USER + 224;
EM_SETZOOM = WM_USER + 225;
EM_SETFONTSIZE = WM_USER + 223;
type
PCHARRANGE = ^CHARRANGE;
PTEXTRANGE = ^TEXTRANGE;
var
s: string;
i: integer;
begin
inherited;
case Message.Msg of
WM_TIMER:
if Message.WParam and EDITOR_NOTIFY <> 0 then
begin
RemoveNotification(Message.WParam and $FFFF);
if not KillTimer(Handle, Message.WParam) then
RaiseLastOSError;
Message.Result := 0;
Exit;
end;
end;
if not FMessageInterface then Exit;
case Message.Msg of
WM_UNDO:
Message.Result := B(Undo);
EM_UNDO:
Message.Result := B(Undo);
EM_REDO:
Message.Result := B(Redo);
EM_CANUNDO:
Message.Result := B(CanUndo);
EM_CANREDO:
Message.Result := B(CanRedo);
WM_CUT:
CutToClipboard;
WM_COPY:
CopyToClipboard;
WM_PASTE:
PasteFromClipboard;
WM_CLEAR:
ClearSelection;
EM_SETSEL:
begin
if Message.WParam = NativeUInt(-1) then
SelectNone
else if (Message.WParam = 0) and (Message.LParam = -1) then
SelectAll
else if (Integer(Message.WParam) >= 0) and (Message.LParam >= 0) then
begin
FTextFile.CaretPos.SetPoint(FTextFile.GetPointOfIndex(Message.WParam));
FTextFile.CaretPos.SetPoint(FTextFile.GetPointOfIndex(Message.LParam), true);
end;
end;
EM_CHARFROMPOS:
Message.Result := FTextFile.GetIndexOfPoint(CaretPosAtPhysicalPixel(Point(PPOINTL(Message.LParam)^.x, PPOINTL(Message.LParam)^.y)));
EM_EMPTYUNDOBUFFER:
ClearUndoHistory;
EM_GETCUEBANNER:
Message.Result := 0;
EM_GETFIRSTVISIBLELINE:
Message.Result := FirstVisibleLine;
EM_GETHANDLE:
Message.Result := 0;
EM_GETLINE:
begin
if InRange(Message.WParam, 0, FTextFile.LineCount - 1) then
begin
s := FTextFile.Lines[Message.WParam];
i := Min(PWord(Message.LParam)^, Length(s));
Move(s, PChar(Message.LParam)^, i * sizeof(Char));
Message.Result := i;
end
else
Message.Result := 0;
end;
EM_GETLINECOUNT:
Message.Result := FTextFile.LineCount;
EM_GETMARGINS:
Message.Result := 0;
EM_GETMODIFY:
Message.Result := B(FTextFile.FileModified);
EM_GETPASSWORDCHAR:
Message.Result := ord(FPasswordChar);
EM_GETSEL:
begin
if FTextFile.HasSelection then
begin
if Message.WParam <> 0 then
PDWORD(Message.WParam)^ := FTextFile.GetIndexOfPoint(FTextFile.CaretPos.FirstPoint);
if Message.LParam <> 0 then
PDWORD(Message.LParam)^ := FTextFile.GetIndexOfPoint(FTextFile.CaretPos.LastPoint) + 1;
end
else
begin
if Message.WParam <> 0 then
PDWORD(Message.WParam)^ := SelStart;
if Message.LParam <> 0 then
PDWORD(Message.LParam)^ := SelStart;
end;
end;
EM_GETTHUMB:
Message.Result := FScrollPos.Y;
EM_GETWORDBREAKPROC:
Message.Result := 0;
EM_HIDEBALLOONTIP:
begin
HideBalloon;
Message.Result := 1;
end;
EM_LINEFROMCHAR:
if Message.WParam = NativeUInt(-1) then
Message.Result := FTextFile.CaretPos.FirstPoint.Y
else if InRange(Message.WParam, 0, FTextFile.NumCharacters - 1) then
Message.Result := FTextFile.GetPointOfIndex(Message.WParam).Y
else
Message.Result := -1;
EM_LINEINDEX:
if Message.WParam = NativeUInt(-1) then
Message.Result := FTextFile.GetIndexOfPoint(Point(0, FTextFile.CaretPos.FirstPoint.Y))
else if InRange(Message.WParam, 0, FTextFile.LineCount - 1) then
Message.Result := FTextFile.GetIndexOfPoint(Point(0, Message.WParam))
else
Message.Result := -1;
EM_LINELENGTH:
if Message.WParam = NativeUInt(-1) then
with FTextFile.CaretPos.LastPoint do
Message.Result := FTextFile.CaretPos.FirstPoint.X + (FTextFile.VirtualLineWidths[Y] - X)
else if InRange(Message.WParam, 0, FTextFile.LineCount - 1) then
Message.Result := FTextFile.VirtualLineWidths[Message.WParam]
else
Message.Result := 0;
EM_LINESCROLL:
begin
SetScrollPosXY(FScrollPos.X + FFontSize.cx * NativeInt(Message.WParam), FScrollPos.Y + FFontSize.cy * Message.LParam);
Message.Result := IfThen(SingleLine, 0, 1);
end;
EM_POSFROMCHAR:
with VirtualPixelAtChar(FTextFile.GetPointOfIndex(Message.LParam)) do
begin
PPOINTL(Message.WParam)^.x := X;
PPointL(Message.WParam)^.y := Y;
end;
EM_REPLACESEL:
begin
InsertText(PChar(Message.LParam)^);
if Message.WParam = 0 then
ClearUndoHistory;
end;
EM_SCROLL:
begin
if (Message.WParam = SB_LINEDOWN) or (Message.WParam = SB_LINEUP) then
Message.Result := (1 shr 16) or 1
else if (Message.WParam = SB_PAGEDOWN) or (Message.WParam = SB_PAGEUP) then
Message.Result := (1 shr 16) or (ClientHeight div FFontSize.cy)
else
Message.Result := 0;
if Message.Result <> 0 then
Perform(WM_VSCROLL, Message.wParam, 0);
end;
EM_SCROLLCARET:
Message.Result := B(ScrollToCaret);
EM_SETCUEBANNER:
Message.Result := 0;
EM_SETMODIFY:
FTextFile.FileModified := Message.WParam <> 0;
EM_SETPASSWORDCHAR:
SetPasswordChar(chr(Message.WParam));
EM_SETREADONLY:
begin
if Message.WParam <> 0 then
EditMode := emReadOnly
else if EditMode = emReadOnly then
EditMode := emText;
Message.Result := 1;
end;
EM_SETTABSTOPS:
Message.Result := 0;
EM_SHOWBALLOONTIP:
with PEDITBALLOONTIP(Message.LParam)^ do
begin
if cbStruct = sizeof(TEditBalloonTip) then
Message.Result := B(ShowBalloon(pszTitle, pszText,
TBalloonIconKind(ttiIcon), bpRemain, CaretPos))
else
Message.Result := 0;
end;
EM_CANPASTE:
if Message.WParam = 0 then
Message.Result := B(Clipboard.HasFormat(CF_TEXT) or (Clipboard.HasFormat(CF_BITMAP) and not SingleLine))
else
Message.Result := B((Message.WParam = CF_TEXT) or (Message.WParam = CF_UNICODETEXT) or ((Message.WParam = CF_BITMAP) and not SingleLine));
EM_EXGETSEL:
begin
if FTextFile.AllSelected then
begin
PCHARRANGE(Message.LParam)^.cpMin := 0;
PCHARRANGE(Message.LParam)^.cpMax := -1;
end
else if FTextFile.HasSelection then
begin
PCHARRANGE(Message.LParam)^.cpMin := FTextFile.GetIndexOfPoint(FTextFile.CaretPos.FirstPoint);
PCHARRANGE(Message.LParam)^.cpMin := FTextFile.GetIndexOfPoint(FTextFile.CaretPos.LastPoint) + 1
end
else
begin
PCHARRANGE(Message.LParam)^.cpMin := FTextFile.GetIndexOfPoint(FTextFile.CaretPos.FirstPoint);
PCHARRANGE(Message.LParam)^.cpMin := PCHARRANGE(@Message.LParam)^.cpMin;
end;
end;
EM_EXLINEFROMCHAR:
Message.Result := FTextFile.GetPointOfIndex(Message.LParam).Y;
EM_FINDTEXT:
;
EM_FINDTEXTEX:
;
EM_GETREDONAME:
if CanRedo then
Message.Result := FTextFile.HistoryManager.UndoData[FTextFile.HistoryManager.HistoryIndex + 1].UID
else
Message.Result := 0;
EM_GETSCROLLPOS:
begin
PPOINT(Message.LParam)^ := FScrollPos;
Message.Result := 1;
end;
EM_GETSELTEXT:
begin
s := SelText;
i := Length(SelText);
Move(s, PChar(Message.LParam), i * sizeof(Char));
Message.Result := i;
end;
EM_GETTEXTLENGTHEX:
if (PDWORD(Message.WParam)^ and GTL_USECRLF) <> 0 then
Message.Result := FTextFile.VirtualTextLength
else
Message.Result := FTextFile.NumCharacters;
EM_GETTEXTMODE:
Message.Result := TM_PLAINTEXT or TM_MULTILEVELUNDO or TM_MULTICODEPAGE;
EM_GETTEXTRANGE:
with PTEXTRANGE(Message.LParam)^ do
begin
if (chrg.cpMin = 0) and (chrg.cpMax = -1) then
s := PlainText + #0
else
s := Copy(PlainText, chrg.cpMin + 1, chrg.cpMax - chrg.cpMin) + #0;
Move(s[1], lpstrText^, Length(s))
end;
EM_GETTOUCHOPTIONS:
Message.Result := 0;
EM_GETUNDONAME:
if CanUndo then
Message.Result := FTextFile.HistoryManager.UndoData[FTextFile.HistoryManager.HistoryIndex].UID
else
Message.Result := 0;
EM_GETZOOM:
begin
Message.WParam := FZoom;
Message.LParam := 100;
Message.Result := 1;
end;
EM_HIDESELECTION:
;
EM_SELECTIONTYPE:
if FTextFile.HasSelection then
Message.Result := SEL_TEXT or IfThen(SelLength > 1, SEL_MULTICHAR)
else
Message.Result := SEL_EMPTY;
EM_SETBKGNDCOLOR:
begin
Message.Result := FBkColor;
SetUseSystemColors(Message.WParam <> 0);
if not FUseSystemColors then
SetBackgroundColor(Message.LParam);
end;
EM_SETCHARFORMAT:
;
EM_SETFONTSIZE:
begin
Message.Result := B(InRange(Message.WParam, -1637, 1638));
if Message.Result <> 0 then
FFont.Size := REFontInc(FFont.Size, Message.WParam);
end;
EM_SETSCROLLPOS:
begin
Message.Result := 1;
with PPoint(Message.LParam)^ do
SetScrollPosXY(X, Y);
end;
EM_SETZOOM:
begin
Message.Result := B((Message.WParam > 0) and (Message.LParam > 0));
if Message.Result <> 0 then
SetZoom(100 * NativeInt(Message.WParam) div Message.LParam);
end;
EM_STOPGROUPTYPING:
if FTypeTimer.Enabled then
TypeTimerTimer(Self);
end;
end;
procedure TTextEditor.WordWrap(ALineLength: integer; ANice: boolean;
AChr: char);
begin
TypeTimerEnd;
FTextFile.WordWrap(ALineLength, ANice, AChr);
AddUndoRecord(SUndoWordWrap, UID_UNKNOWN);
end;
procedure TTextEditor.TextFileFindDataClear(Sender: TObject);
begin
Invalidate;
if Assigned(FOnFindDataClear) then
FOnFindDataClear(Self);
end;
procedure TTextEditor.TextFileLockVisualUpdates(Sender: TObject);
begin
inc(FVisualUpdateLock);
end;
procedure TTextEditor.BeginVisualUpdate;
begin
inc(FVisualUpdateLock);
end;
procedure TTextEditor.TextFileUnlockVisualUpdates(Sender: TObject);
begin
dec(FVisualUpdateLock);
if FVisualUpdateLock = 0 then
DoSetCaretPos;
end;
procedure TTextEditor.EndVisualUpdate(AUpdate: boolean = false);
begin
dec(FVisualUpdateLock);
if FVisualUpdateLock = 0 then
begin
Invalidate;
DoSetCaretPos;
if AUpdate then Update;
end;
end;
procedure TTextEditor.ConnectTextFileToEditor;
begin
FTextFile.OnChange := TextFileChange;
FTextFile.OnCaretPosChange := TextFileCaretPosChange;
FTextFile.OnCaretPosSelChange := TextFileCaretPosSelChange;
FTextFile.OnInputError := TextFileInputError;
FTextFile.OnReadOnlyError := TextFileReadOnlyError;
FTextFile.OnFileModified := TextFileModified;
FTextFile.OnLineChange := TextFileLineChange;
FTextFile.OnLineClassChange := TextFileLineClassChange;
FTextFile.OnControlRemoved := TextFileControlRemoved;
FTextFile.OnGetControlText := TextFileGetControlText;
FTextFile.OnBookmarksMoved := TextFileBookmarksMoved;
FTextFile.OnFindDataClear := TextFileFindDataClear;
FTextFile.OnLockVisualUpdates := TextFileLockVisualUpdates;
FTextFile.OnUnlockVisualUpdates := TextFileUnlockVisualUpdates;
FTextFile.IndentSize := Self.IndentSize;
FTextFile.AutoIndent := Self.AutoIndent;
FTextFile.CaretAfterEOL := FCaretAfterEOL ;
end;
procedure TTextEditor.DisconnectTextFileFromEditor;
begin
FTextFile.OnChange := nil;
FTextFile.OnCaretPosChange := nil;
FTextFile.OnCaretPosSelChange := nil;
FTextFile.OnInputError := nil;
FTextFile.OnFileModified := nil;
FTextFile.OnLineChange := nil;
FTextFile.OnLineClassChange := nil;
FTextFile.OnControlRemoved := nil;
FTextFile.OnGetControlText := nil;
FTextFile.OnBookmarksMoved := nil;
FTextFile.OnLockVisualUpdates := nil;
FTextFile.OnUnlockVisualUpdates := nil;
end;
procedure TTextEditor.ZoomIn;
begin
Zoom := Zoom + 10;
end;
procedure TTextEditor.ZoomOut;
begin
Zoom := Max(Zoom - 10, 10);
end;
procedure TTextEditor.SetScrollPosY(Value: integer; Lim: boolean = false);
var
OldScrollPos, diff: integer;
TCR: TRect;
begin
if (Value < 0) or SingleLine then Value := 0;
if Lim then
begin
if GetLineBottomVirtual(LineCount - 1) < (ClientHeight - FMarginTop - FMarginBottom) then
Value := 0
else if Value > GetLineBottomVirtual(LineCount - 1) - (ClientHeight - FMarginTop - FMarginBottom) then
Value := GetLineBottomVirtual(LineCount - 1) - (ClientHeight - FMarginTop - FMarginBottom);
end;
OldScrollPos := FScrollPos.Y;
FScrollPos.Y := Value;
diff := OldScrollPos - Value;
if diff = 0 then Exit;
UpdateScrollBars;
TCR := TextContentRect;
TCR.Left := 0;
if abs(diff) < ClientHeight - FMarginTop - FMarginBottom then
ScrollWindowEx(Handle, 0, diff, @TCR, @TCR, 0, nil, SW_INVALIDATE or SW_SCROLLCHILDREN)
else
Invalidate;
UpdateRuler;
DoSetCaretPos;
if FTextFile.ControlAware then
UpdateLineControls;
MoveBalloonPostScroll;
end;
procedure TTextEditor.SetScrollPosXY(X, Y: integer; Lim: boolean = false);
var
OldScrollPos: TPoint;
diffX, diffY: integer;
TCR: TRect;
begin
if SingleLine then Y := 0;
if X < 0 then X := 0;
if Y < 0 then Y := 0;
if Lim then
begin
if GetLineBottomVirtual(LineCount - 1) < (ClientHeight - FMarginTop - FMarginBottom) then
Y := 0
else if Y > GetLineBottomVirtual(LineCount - 1) - (ClientHeight - FMarginTop - FMarginBottom) then
Y := GetLineBottomVirtual(LineCount - 1) - (ClientHeight - FMarginTop - FMarginBottom);
end;
if (X = FScrollPos.X) then
begin
SetScrollPosY(Y);
Exit;
end
else if (Y = FScrollPos.Y) then
begin
SetScrollPosX(X);
Exit;
end;
OldScrollPos := FScrollPos;
FScrollPos := Point(X, Y);
diffX := OldScrollPos.X - X;
diffY := OldScrollPos.Y - Y;
UpdateScrollBars;
TCR := TextContentRect;
if (abs(diffY) < ClientHeight - FMarginTop - FMarginBottom) and (abs(diffX) < ClientWidth - FMarginLeft - FMarginRight) then
ScrollWindowEx(Handle, diffX, diffY, @TCR, @TCR, 0, nil, SW_INVALIDATE or SW_SCROLLCHILDREN)
else
Invalidate;
UpdateRuler;
DoSetCaretPos;
if FTextFile.ControlAware then
UpdateLineControls;
MoveBalloonPostScroll;
end;
procedure TTextEditor.UpdateLineControls;
var
i: Integer;
LineIndex: integer;
begin
for i := 0 to high(FLineControls) do
begin
if not Assigned(FLineControls[i].Control) then Continue;
LineIndex := GetLineFromControlID(FLineControls[i].ID);
if LineIndex = -1 then
begin
FLineControls[i].Control.Visible := false;
Continue;
end;
FLineControls[i].Control.Visible := true;
FLineControls[i].Control.SetBounds(FMarginLeft - FScrollPos.X + CARET_WIDTH,
FMarginTop + FAccumLineHeights[LineIndex] - FScrollPos.Y,
FLineControls[i].Control.Width,
FLineControls[i].Control.Height);
end;
end;
procedure TTextEditor.FontChange(Sender: TObject);
begin
VerifyFont;
SetupFontMetrics;
BuildFontDataArray;
AdjustHeight;
Invalidate;
end;
procedure TTextEditor.UpdateRuler;
begin
InvalidateRect(Handle, RulerRect, false);
end;
procedure TTextEditor.RulerFontChange(Sender: TObject);
begin
UpdateRuler;
end;
function TTextEditor.GetCaretAfterEOL: boolean;
begin
FCaretAfterEOL := FTextFile.CaretAfterEOL;
result := FCaretAfterEOL;
end;
function TTextEditor.GetCaretPos: TPoint;
begin
result := FTextFile.CaretPos.Data;
end;
function TTextEditor.GetCharAtCaret: char;
begin
if (SelLength = 1) and (SafeSelLength = 1) then
result := SelText[1]
else if FTextFile.CaretPos.X < FTextFile.VirtualLineWidths[FTextFile.CaretPos.Y] then
result := FTextFile.Lines[FTextFile.CaretPos.Y][FTextFile.CaretPos.X + 1]
else
result := #0;
end;
function TTextEditor.GetCharBeforeCaret: char;
begin
if (SelLength = 1) and (SafeSelLength = 1) then
result := SelText[1]
else if FTextFile.CharacterExists(FTextFile.CaretPos.Y, FTextFile.CaretPos.X - 1) then
result := FTextFile.Lines[FTextFile.CaretPos.Y][FTextFile.CaretPos.X]
else
result := #0;
end;
function TTextEditor.GetClassRecord(Index: integer): TClassRecord;
begin
result := FClassArray[Index];
end;
function TTextEditor.GetCliHistory(Index: integer): string;
begin
result := FCliHistory[Index];
end;
function TTextEditor.GetCliHistoryCount: integer;
begin
result := Length(FCliHistory);
end;
function TTextEditor.GetCliHistoryIndex: integer;
begin
result := FCliHistoryIndex;
end;
function TTextEditor.GetControlFromID(ID: integer): TControl;
var
i: Integer;
begin
result := nil;
for i := low(FLineControls) to high(FLineControls) do
if FLineControls[i].ID = ID then
Exit(FLineControls[i].Control);
end;
function TTextEditor.GetControlFromLine(LineIndex: integer): TControl;
begin
result := GetControlFromID(GetControlIDFromLine(LineIndex));
end;
function TTextEditor.GetControlIDFromLine(LineIndex: integer): integer;
var
tmp: integer;
begin
result := -1;
if LineIsControl(LineIndex) and TryStrToInt(Copy(FTextFile.Lines[LineIndex],
Length(LINE_CONTROL_PREFIX) + 1), tmp) then result := tmp;
end;
function TTextEditor.GetEditMode: TEditMode;
begin
result := FTextFile.EditMode;
end;
function TTextEditor.GetClass(Index: integer): string;
begin
result := FTextFile.Classes[Index];
end;
function TTextEditor.GetClassFromName(const AClassName: string;
out AClassRecord: TClassRecord): boolean;
var
i: Integer;
begin
for i := low(FClassArray) to high(FClassArray) do
if SameStr(AClassName, FClassArray[i].Name) then
begin
AClassRecord := FClassArray[i];
Exit(true);
end;
result := false;
end;
function TTextEditor.GetClassIndex(const AClassName: string): integer;
var
i: Integer;
begin
if not AClassName.IsEmpty then
for i := low(FClassArray) to high(FClassArray) do
if SameStr(AClassName, FClassArray[i].Name) then
Exit(i);
result := -1;
end;
function TTextEditor.GetFalse: boolean;
begin
result := false;
end;
function TTextEditor.GetFontChrs(const AFontName: TFontName;
out GlyphSet: PGlyphSet): boolean;
var
size: integer;
begin
FGLYPHBM.Canvas.Font.Name := AFontName;
size := GetFontUnicodeRanges(FGLYPHBM.Canvas.Handle, nil);
GetMem(GlyphSet, size);
result := GetFontUnicodeRanges(FGLYPHBM.Canvas.Handle, GlyphSet) > 0;
end;
function TTextEditor.GetIDFromControl(AControl: TControl): integer;
var
i: Integer;
begin
for i := low(FLineControls) to high(FLineControls) do
if FLineControls[i].Control = AControl then
Exit(i);
result := -1;
end;
function TTextEditor.GetNotification(AIndex: integer): integer;
begin
result := FNotifications[AIndex];
end;
function TTextEditor.GetNotificationCount: integer;
begin
result := Length(FNotifications);
end;
function TTextEditor.GetNotificationStr(MsgID: integer): string;
begin
result := FNotificationStrs[MsgID];
end;
function TTextEditor.GetNumClasses: integer;
begin
result := Length(FClassArray);
end;
function TTextEditor.GetRulerVisible: boolean;
begin
result := FRulerWidth > 0;
end;
function TTextEditor.GetSelEndPos: TPoint;
begin
result := FTextFile.CaretPos.SelEnd;
end;
function TTextEditor.GetSelLength: integer;
begin
result := FTextFile.SelLength;
end;
function TTextEditor.GetSelStart: integer;
begin
result := FTextFile.SelStart;
end;
function TTextEditor.GetSelText: string;
begin
result := FTextFile.SelText;
end;
function TTextEditor.GetSelType: TSelectionType;
begin
result := FTextFile.CaretPos.SelectionType;
end;
function TTextEditor.GetSingleLine: boolean;
begin
result := FTextFile.SingleLine;
end;
function TTextEditor.GetSortReverseOrder: boolean;
begin
result := FTextFile.SortReverseOrder;
end;
function TTextEditor.GetText: string;
begin
result := FTextFile.PlainText;
end;
function TTextEditor.GetWord: string;
begin
result := FTextFile.GetWord;
end;
function TTextEditor.GetWord(const Point: TPoint): string;
begin
result := FTextFile.GetWord(Point);
end;
function TTextEditor.GetWordBoundary(out StartPos, EndPos: integer): boolean;
begin
result := FTextFile.GetWordBoundary(StartPos, EndPos);
end;
function TTextEditor.GetWrapAt: string;
begin
result := FTextFile.WrapAt;
end;
function TTextEditor.GiveFeedback(dwEffect: Longint): HRESULT;
begin
result := DRAGDROP_S_USEDEFAULTCURSORS;
end;
function TTextEditor.GotoBookmark(AIndex: integer): boolean;
begin
result := FTextFile.GotoBookmark(AIndex);
end;
function TTextEditor.GotoHistoryVersion(Index: integer): boolean;
begin
if FTypeTimer.Enabled then
TypeTimerTimer(Self);
FNoScrollToCaret := true;
try
result := FTextFile.GotoHistoryVersion(Index);
if FTextFile.ControlAware then
FixRemovedLineControlLines;
finally
FNoScrollToCaret := false;
end;
if result then
CenterOnSelection(true);
end;
procedure TTextEditor.GotoSamePixelAtNextLine(Shift: boolean);
var
px: TPoint;
begin
if FTextFile.AtLastLine then
begin
TextFileInputError(Self);
Exit;
end;
if not FMultiSize then
begin
FTextFile.Down(Shift);
Exit;
end;
px := VirtualPixelAtChar(CaretPos);
if FDesiredColumn <> 0 then
px.X := FDesiredColumn;
inc(px.Y, FFontSizes[CaretPos.Y].cy + FFontSizes[CaretPos.Y + 1].cy div 2);
FPreserveDesiredColumn := true;
try
FTextFile.CaretPos.SetPoint(CaretPosAtVirtualPixel(px), Shift);
finally
FPreserveDesiredColumn := false;
end;
end;
procedure TTextEditor.GotoSamePixelAtPrevLine(Shift: boolean);
var
px: TPoint;
begin
if CaretPos.Y = 0 then
begin
TextFileInputError(Self);
Exit;
end;
if not FMultiSize then
begin
FTextFile.Up(Shift);
Exit;
end;
px := VirtualPixelAtChar(CaretPos);
if FDesiredColumn <> 0 then
px.X := FDesiredColumn;
dec(px.Y, FFontSizes[CaretPos.Y - 1].cy div 2);
FPreserveDesiredColumn := true;
try
FTextFile.CaretPos.SetPoint(CaretPosAtVirtualPixel(px), Shift);
finally
FPreserveDesiredColumn := false;
end;
end;
function TTextEditor.HasNotificationMessage(MsgID: integer): boolean;
var
i: Integer;
begin
for i := low(FNotifications) to high(FNotifications) do
if FNotifications[i] = MsgID then
Exit(true);
result := false;
end;
procedure TTextEditor.HideBalloon;
begin
if FHintWindow <> 0 then
SendMessage(FHintWindow, TTM_TRACKACTIVATE, 0, LParam(@FToolInfo));
end;
function TTextEditor.GetWordBoundary(const Point: TPoint; out StartPos,
EndPos: integer): boolean;
begin
result := FTextFile.GetWordBoundary(Point, StartPos, EndPos);
end;
function UnicodeSuperscript(const AChar: char): char;
begin
result := AChar;
case AChar of
'0':
result := '⁰';
'1':
result := '¹';
'2':
result := '²';
'3':
result := '³';
'4':
result := '⁴';
'5':
result := '⁵';
'6':
result := '⁶';
'7':
result := '⁷';
'8':
result := '⁸';
'9':
result := '⁹';
'+':
result := '⁺';
'-', '−':
result := '⁻';
'=':
result := '⁼';
'(':
result := '⁽';
')':
result := '⁾';
'n':
result := 'ⁿ';
end;
end;
function UnicodeSubscript(const AChar: char): char;
begin
result := AChar;
case AChar of
'0':
result := '₀';
'1':
result := '₁';
'2':
result := '₂';
'3':
result := '₃';
'4':
result := '₄';
'5':
result := '₅';
'6':
result := '₆';
'7':
result := '₇';
'8':
result := '₈';
'9':
result := '₉';
'+':
result := '₊';
'-', '−':
result := '₋';
'=':
result := '₌';
'(':
result := '₍';
')':
result := '₎';
end;
end;
function UnicodeCircled(const AChar: char): char;
begin
result := AChar;
if InRange(ord(AChar), ord('A'), ord('Z')) then
result := chr($24B6 + ord(AChar) - ord('A'))
else if InRange(ord(AChar), ord('a'), ord('z')) then
result := chr($24D0 + ord(AChar) - ord('a'))
else if InRange(ord(AChar), ord('1'), ord('9')) then
result := chr($2460 + ord(AChar) - ord('1'))
else if AChar = '0' then
result := #$24EA;
end;
function UnicodeParenthesized(const AChar: char): char;
begin
result := AChar;
if InRange(ord(AChar), ord('a'), ord('z')) then
result := chr($249C + ord(AChar) - ord('a'))
else if InRange(ord(AChar), ord('1'), ord('9')) then
result := chr($2474 + ord(AChar) - ord('1'))
end;
function UnicodeFullStop(const AChar: char): char;
begin
result := AChar;
if InRange(ord(AChar), ord('1'), ord('9')) then
result := chr($2488 + ord(AChar) - ord('1'))
end;
function UnicodeDoublyCircled(const AChar: char): char;
begin
result := AChar;
if InRange(ord(AChar), ord('1'), ord('9')) then
result := chr($24F5 + ord(AChar) - ord('1'))
end;
function TTextEditor.GetBalloonPosition: TPoint;
begin
result := ClientToScreen(PhysicalPixelAtChar(FBalloonPoint));
inc(result.Y, FFontSize.cy);
inc(result.X, CARET_WIDTH div 2);
end;
function TTextEditor.GetBookmark(Index: integer): TPoint;
begin
result := FTextFile.Bookmarks[Index];
end;
function TTextEditor.GetBookmarkCount: integer;
begin
result := FTextFile.BookmarkCount;
end;
function TTextEditor.GetBookmarkDescr(BookmarkIndex: integer): string;
begin
if not InRange(BookmarkIndex, 0, BookmarkCount - 1) then
Exit(SBookmarkDescriptionInvalid);
if BookmarkUsed(BookmarkIndex) then
result := Format(SBookmarkDescription,
[BookmarkIndex, Bookmarks[BookmarkIndex].Y + 1, Bookmarks[BookmarkIndex].X + 1])
else
result := Format(SBookmarkDescriptionEmpty, [BookmarkIndex]);
end;
procedure TTextEditor.InsertChar(const AChar: Char; AOverwrite: boolean = false);
var
BChar: char;
begin
if FTextFile.ControlAware and LineIsControl(FTextFile.CaretPos.Y) then
begin
TextFileInputError(Self);
ShowBalloon(SControlLineInputTitle, SControlLineInputText, bikError, bpCaretPos,
GetCaretPos);
Exit;
end;
if FNumbersOnly and not AChar.IsDigit and (FHintWindow <> 0) then
begin
TextFileInputError(Self);
ShowBalloon(SNumOnlyErrorTitle, SNumOnlyErrorText, bikError, bpCaretPos,
GetCaretPos);
Exit;
end;
BChar := AChar;
case FInputTransform of
itUpperCase:
BChar := AnsiUpperCase(AChar)[1];
itLowerCase:
BChar := AnsiLowerCase(AChar)[1];
itSuperscript:
BChar := UnicodeSuperscript(AChar);
itSubscript:
BChar := UnicodeSubscript(AChar);
itCircled:
BChar := UnicodeCircled(AChar);
itParenthesized:
BChar := UnicodeParenthesized(AChar);
itFullStop:
BChar := UnicodeFullStop(AChar);
itDoublyCircled:
BChar := UnicodeDoublyCircled(AChar);
end;
if FMultipleCarets then
FTextFile.MultiInsertChar(FCarets, BChar, Overwrite)
else
FTextFile.InsertChar(BChar, AOverwrite);
PostType;
if FMatchBrackets and ((BChar = '❩') or (BChar = ')') or (BChar = '}') or (BChar = ']')) then
BlinkBracket;
end;
procedure TTextEditor.InsertGraphic(AGraphic: TGraphic; LineIndex: integer);
var
img: TImage;
begin
img := TImage.Create(Self);
try
img.AutoSize := true;
img.Stretch := false;
img.Proportional := true;
img.Center := true;
img.Cursor := crArrow;
img.Picture.Graphic := AGraphic;
img.PopupMenu := FImagePopup;
InsertLineControl(img, LineIndex);
except
img.Free;
raise;
end;
end;
procedure TTextEditor.InsertLine(const AText, AClassName: string;
LineIndex: integer);
begin
FTextFile.InsertLine(AText, AClassName, LineIndex);
end;
procedure TTextEditor.InsertLine(const AText: string; LineIndex: integer);
begin
FTextFile.InsertLine(AText, LineIndex);
end;
procedure TTextEditor.InsertLine(LineIndex: integer);
begin
FTextFile.InsertLine('', LineIndex);
end;
procedure TTextEditor.RemoveAllMargins;
begin
if FMarginLeft + FMarginRight + FMarginTop + FMarginBottom > 0 then
begin
FMarginLeft := 0;
FMarginRight := 0;
FMarginTop := 0;
FMarginBottom := 0;
FRulerWidth := 0;
UpdateScrollBars;
Invalidate;
DoSetCaretPos;
end;
end;
procedure TTextEditor.InsertLineControl(AControl: TControl; LineIndex: integer);
begin
RemoveAllMargins;
MultiSize := true;
FTextFile.ControlAware := true;
SetLength(FLineControls, Length(FLineControls) + 1);
FLineControls[high(FLineControls)].ID := FNextControlID;
FLineControls[high(FLineControls)].Control := AControl;
InsertLine(LINE_CONTROL_PREFIX + IntToStr(FNextControlID), LINE_CONTROL_CLASS, LineIndex);
inc(FNextControlID);
AControl.Parent := Self;
AControl.Visible := true;
end;
procedure TTextEditor.BlinkBracket;
var
start: TPoint;
NewBracket: TPoint;
begin
NewBracket := Point(FTextFile.CaretPos.X - 1, FTextFile.CaretPos.Y);
start := FTextFile.MatchBracket(NewBracket);
if start.Y <> -1 then
begin
SetBracketHighlight(NewBracket, start);
FBlinkRemover.Enabled := false;
FBlinkRemover.Enabled := true;
end;
end;
procedure TTextEditor.InsertText(const AText: string);
begin
TypeTimerEnd;
FTextFile.InsertText(AText);
AddUndoRecord(SUndoTextInserted, UID_UNKNOWN);
end;
procedure TTextEditor.InsertTextAsBlock(const AText: string);
begin
TypeTimerEnd;
FTextFile.InsertTextAsBlock(AText);
AddUndoRecord(SUndoTextInserted, UID_UNKNOWN);
end;
function TTextEditor.Undo: boolean;
begin
if FTypeTimer.Enabled then
TypeTimerTimer(Self);
FNoScrollToCaret := true;
try
result := FTextFile.Undo;
if result and FTextFile.ControlAware then
FixRemovedLineControlLines;
finally
FNoScrollToCaret := false;
end;
if result then
CenterOnSelection(true);
end;
function TTextEditor.TextContentRect: TRect;
begin
result := ClientRect;
inc(result.Left, FMarginLeft);
inc(result.Top, FMarginTop);
dec(result.Right, FMarginRight);
dec(result.Bottom, FMarginBottom);
end;
procedure TTextEditor.UpdateCaret;
begin
if not Focused then Exit;
if FListBoxMode then Exit;
if FMultiSize then
CreateCaret(Handle, IfThen(FTextFile.EditMode = emReadOnly, 1, 0), IfThen(FOverwrite, FFontSizes[FTextFile.CaretPos.Y].cx, CARET_WIDTH), FFontSizes[FTextFile.CaretPos.Y].cy)
else
CreateCaret(Handle, IfThen(FTextFile.EditMode = emReadOnly, 1, 0), IfThen(FOverwrite, FFontSize.cx, CARET_WIDTH), FFontSize.cy);
ShowCaret(Handle);
FCaretVisible := true;
DoSetCaretPos;
end;
procedure TTextEditor.MultiCharSelectDlgResize(Sender: TObject);
begin
if Sender is TForm then
with TForm(Sender) do
SetWindowPos(Flv, HWND_TOP, 0, 0, ClientWidth, ClientHeight,
SWP_NOOWNERZORDER or SWP_NOZORDER or SWP_SHOWWINDOW);
end;
procedure TTextEditor.MultiCharSelectDlgWndProc(var Message: TMessage);
type
LPNMLVKEYDOWN = ^NMLVKEYDOWN;
NMLVKEYDOWN = packed record
hdr: NMHDR;
wVKey: WORD;
flags: UINT;
end;
var
index: integer;
buf: array[0..32] of char;
begin
FMultiCharSelectDlgDefaultWndProc(Message);
case Message.Msg of
WM_NOTIFY:
if PNMHDR(Message.LParam).hwndFrom = Flv then
case PNMHDR(Message.LParam).code of
LVN_KEYDOWN:
if LPNMLVKEYDOWN(Message.LParam).wVKey = VK_ESCAPE then
FMultiCharSelectDlgFrm.ModalResult := mrCancel;
NM_RETURN, NM_DBLCLK:
begin
index := ListView_GetNextItem(Flv, -1, LVNI_SELECTED);
if index <> -1 then
begin
ListView_GetItemText(Flv, index, 1, @buf[0], Length(buf));
if (buf[0] = 'U') and (buf[1]= '+') then
FMultiCharSelectDlgFrm.Tag := StrToInt('$' + Copy(PChar(@buf[0]), 3));
end;
FMultiCharSelectDlgFrm.ModalResult := mrOk;
end;
end;
end;
end;
procedure TTextEditor.MultiCharSelectDlgActivate(Sender: TObject);
begin
Windows.SetFocus(Flv);
end;
procedure TTextEditor.DoMultiCharSelect(AChrs: array of char);
var
frm: TForm;
lv: HWND;
c: char;
tvi: TLVTileViewInfo;
li: TLVItem;
cl: TLVColumn;
index: integer;
il: TImageList;
bm: TBitmap;
i: integer;
R: TRect;
S: string;
const
colinfo: array[0..1] of integer = (1, 2);
begin
frm := TForm.Create(nil);
lv := 0;
try
frm.Caption := SMultiSelectCaption;
frm.BorderStyle := bsSizeToolWin;
frm.Width := 600;
frm.Height := 400;
frm.OnActivate := MultiCharSelectDlgActivate;
frm.OnResize := MultiCharSelectDlgResize;
FMultiCharSelectDlgFrm := frm;
FMultiCharSelectDlgDefaultWndProc := frm.WindowProc;
frm.WindowProc := MultiCharSelectDlgWndProc;
with ClientToScreen(Point(ClientWidth div 2 - frm.ClientWidth div 2,
ClientHeight div 2 - frm.ClientHeight div 2)) do
begin
frm.Left := X;
frm.Top := Y;
end;
il := TImageList.Create(frm);
il.Width := 64;
il.Height := 64;
bm := TBitmap.Create;
try
bm.SetSize(64, 64);
R := Rect(0, 0, bm.Width, bm.Height);
bm.Canvas.Font.Assign(Self.Font);
bm.Canvas.Font.Height := 64;
bm.Canvas.Font.Color := clBlack;
for c in AChrs do
begin
bm.Canvas.Brush.Color := clWhite;
bm.Canvas.FillRect(R);
S := c;
bm.Canvas.TextRect(R, S, [tfSingleLine, tfCenter, tfVerticalCenter]);
il.Add(bm, nil);
end;
finally
bm.Free;
end;
lv := CreateWindowEx(0, WC_LISTVIEW, nil,
WS_CHILD or WS_VISIBLE or LVS_REPORT or LVS_NOSORTHEADER or LVS_SINGLESEL or LVS_AUTOARRANGE,
0, 0, frm.ClientWidth, frm.ClientHeight, frm.Handle, 0, HInstance, nil);
Flv := lv;
ListView_SetExtendedListViewStyle(lv, LVS_EX_AUTOSIZECOLUMNS or LVS_EX_FULLROWSELECT);
ListView_SetImageList(lv, il.Handle, LVSIL_NORMAL);
if not FMultiCharReportView then
begin
ListView_SetView(lv, LV_VIEW_TILE);
tvi.cbSize := sizeof(tvi);
tvi.dwMask := LVTVIM_COLUMNS;
tvi.cLines := 2;
ListView_SetTileViewInfo(lv, tvi);
end;
cl.mask := LVCF_SUBITEM or LVCF_TEXT or LVCF_ORDER or LVCF_WIDTH;
cl.iSubItem := 0;
cl.pszText := PChar(SMultiCharDlgLvColumnTitleDescription);
cl.iOrder := 0;
cl.cx := 200;
ListView_InsertColumn(lv, 0, cl);
cl.iSubItem := 1;
cl.pszText := PChar(SMultiCharDlgLvColumnTitleCodepoint);
cl.iOrder := 1;
cl.cx := 75;
ListView_InsertColumn(lv, 1, cl);
cl.iSubItem := 2;
cl.pszText := PChar(SMultiCharDlgLvColumnTitleBlock);
cl.iOrder := 2;
cl.cx := 200;
ListView_InsertColumn(lv, 2, cl);
li.mask := LVIF_TEXT or LVIF_IMAGE or LVIF_STATE or LVIF_COLUMNS;
li.stateMask := 0;
li.iSubItem := 0;
li.state := 0;
li.iImage := 0;
li.cColumns := 2;
li.puColumns := PUINT(@colinfo[0]);
ListView_SetItemCount(lv, Length(AChrs));
i := 0;
for c in AChrs do
begin
li.iImage := i;
inc(i);
li.pszText := PChar(UCD.GetChrName(c));
index := ListView_InsertItem(lv, li);
ListView_SetItemText(lv, index, 1, PChar(UCD.GetChrCodepointStr(c)));
ListView_SetItemText(lv, index, 2, PChar(UCD.GetChrBlock(c)));
end;
frm.Tag := 0;
if frm.ShowModal = mrOk then
if frm.Tag <> 0 then
begin
Backspace;
InsertChar(Chr(frm.Tag));
end;
finally
if lv <> 0 then DestroyWindow(lv);
frm.Free;
end;
end;
procedure TTextEditor.DoSetCaretPos;
var
pt: TPoint;
begin
if FVisualUpdateLock > 0 then Exit;
if FListBoxMode or not Focused then Exit;
if FMultiSize then
pt := Point(FMarginLeft +
FTextFile.CaretPos.X * FFontSizes[FTextFile.CaretPos.Y].cx - FScrollPos.X,
FMarginTop + FAccumLineHeights[FTextFile.CaretPos.Y] - FScrollPos.Y)
else
pt := Point(FMarginLeft + FTextFile.CaretPos.X * FFontSize.cx - FScrollPos.X,
FMarginTop + FTextFile.CaretPos.Y * FFontSize.cy - FScrollPos.Y);
if PtInRect(TextContentRect, pt) then
begin
BinaryShowCaret;
Windows.SetCaretPos(pt.X, pt.Y)
end
else
BinaryHideCaret;
end;
procedure TTextEditor.BinaryHideCaret;
begin
if FCaretVisible then
begin
HideCaret(Handle);
FCaretVisible := false;
end;
end;
procedure TTextEditor.BinaryShowCaret;
begin
if not FCaretVisible then
begin
ShowCaret(Handle);
FCaretVisible := true;
end;
end;
function TTextEditor.GetLineTop(LineIndex: integer): integer;
begin
if FMultiSize then
result := FMarginTop + FAccumLineHeights[LineIndex] - FScrollPos.Y
else
result := FMarginTop + FFontSize.cy * LineIndex - FScrollPos.Y;
end;
function TTextEditor.GetListBoxItemIndex: integer;
begin
result := CaretPos.Y;
end;
function TTextEditor.GetLastMultiCaret: TPoint;
begin
if Length(FCarets) > 0 then
result := FCarets[high(FCarets)]
else
result := CaretPos;
end;
function TTextEditor.GetLine(Index: integer): string;
begin
result := FTextFile.Lines[Index];
end;
function TTextEditor.GetLineBookmark(ALineIndex: integer): integer;
var
i: Integer;
begin
for i := 0 to FTextFile.BookmarkCount - 1 do
if FTextFile.Bookmarks[i].Y = ALineIndex then
Exit(i);
result := -1;
end;
function TTextEditor.GetLineBottom(LineIndex: integer): integer;
begin
if FMultiSize then
result := FMarginTop + FAccumLineHeights[LineIndex] + FFontSizes[LineIndex].cy - FScrollPos.Y
else
result := FMarginTop + FFontSize.cy * (LineIndex + 1) - FScrollPos.Y;
end;
function TTextEditor.GetLineBottomVirtual(LineIndex: integer): integer;
begin
if FMultiSize then
result := FMarginTop + FAccumLineHeights[LineIndex] + FFontSizes[LineIndex].cy
else
result := FMarginTop + FFontSize.cy * (LineIndex + 1);
end;
function TTextEditor.GetCharLeft(LineIndex, ColIndex: integer): integer;
begin
if FMultiSize then
result := FMarginLeft + FFontSizes[LineIndex].cx * ColIndex - FScrollPos.X
else
result := FMarginLeft + FFontSize.cx * ColIndex - FScrollPos.X;
end;
function TTextEditor.GetCharRight(LineIndex, ColIndex: integer): integer;
begin
if FMultiSize then
result := FMarginLeft + FFontSizes[LineIndex].cx * (ColIndex + 1) - FScrollPos.X
else
result := FMarginLeft + FFontSize.cx * (ColIndex + 1) - FScrollPos.X;
end;
procedure TTextEditor.VisualUpdate(ChangeType: TChangeType; Data1, Data2, Data3,
Data4: integer);
var
i: Integer;
begin
if (FVisualUpdateLock > 0) or not (FValidPaintState and Visible) then Exit;
begin
case ChangeType of
ctFile:
Invalidate;
ctLineRange:
InvalidateRect(Handle, Rect(0, GetLineTop(Data1), ClientWidth, GetLineBottom(Data2)), false);
ctBlock:
if FMultiSize then
for i := max(FirstVisibleLine, Data1) to min(LastVisibleLine, Data2) do
InvalidateRect(Handle, Rect(GetCharLeft(i, Data3), GetLineTop(i), GetCharRight(i, Data4), GetLineBottom(i)), false)
else
InvalidateRect(Handle, Rect(GetCharLeft(Data1, Data3), GetLineTop(Data1), GetCharRight(Data1, Data4), GetLineBottom(Data2)), false);
ctLine:
InvalidateRect(Handle, Rect(0, GetLineTop(Data1), ClientWidth, GetLineBottom(Data1)), false);
ctLineFrom:
InvalidateRect(Handle, Rect(GetCharLeft(Data1, Data2), GetLineTop(Data1), ClientWidth, GetLineBottom(Data1)), false);
ctChar:
InvalidateRect(Handle, Rect(GetCharLeft(Data1, Data2), GetLineTop(Data1), GetCharRight(Data1, Data2), GetLineBottom(Data1)), false);
ctTwoChars:
begin
InvalidateRect(Handle, Rect(GetCharLeft(Data1, Data2), GetLineTop(Data1), GetCharRight(Data1, Data2), GetLineBottom(Data1)), false);
InvalidateRect(Handle, Rect(GetCharLeft(Data3, Data4), GetLineTop(Data3), GetCharRight(Data3, Data4), GetLineBottom(Data3)), false);
end;
ctPostFile:
InvalidateRect(Handle, Rect(0, GetLineBottom(FTextFile.LineCount - 1), ClientWidth, ClientHeight), false);
end;
Update;
end
end;
function TTextEditor.EditorCommand(Command, Param1, Param2, Param3,
Param4: integer): integer;
var
S: string;
i: integer;
begin
result := 0;
if (Command and $FFFF0000) <> 0 then
begin
Param1 := Command shr 16;
Command := Command and $0000FFFF;
end;
case Command of
EDITOR_COMMAND_RIGHT:
FTextFile.Right(Param1 <> 0, Param2 <> 0, Param3 <> 0);
EDITOR_COMMAND_LEFT:
FTextFile.Left(Param1 <> 0, Param2 <> 0, Param3 <> 0);
EDITOR_COMMAND_DOWN:
FTextFile.Down(Param1 <> 0, Param2 <> 0);
EDITOR_COMMAND_UP:
FTextFile.Up(Param1 <> 0, Param2 <> 0);
EDITOR_COMMAND_HOME:
FTextFile.Home(Param1 <> 0, Param2 <> 0);
EDITOR_COMMAND_END:
FTextFile.KEnd(Param1 <> 0, Param2 <> 0);
EDITOR_COMMAND_PAGE_UP:
PageUp(Param1 <> 0);
EDITOR_COMMAND_PAGE_DOWN:
PageDown(Param1 <> 0);
EDITOR_COMMAND_BACKSPACE:
Backspace(Param1 <> 0);
EDITOR_COMMAND_DELETE:
Delete(Param1 <> 0);
EDITOR_COMMAND_CLEAR_SELECTION:
ClearSelection;
EDITOR_COMMAND_SELECT_ALL:
SelectAll;
EDITOR_COMMAND_SELECT_NONE:
SelectNone;
EDITOR_COMMAND_SELECT_ALL_NONE:
SelectAllNone;
EDITOR_COMMAND_SELECT_WORD:
result := B(SelectWord);
EDITOR_COMMAND_SELECT_LINE:
SelectLine;
EDITOR_COMMAND_CLEAR_LINE:
ClearLine(Param1);
EDITOR_COMMAND_CUT:
CutToClipboard;
EDITOR_COMMAND_COPY:
CopyToClipboard;
EDITOR_COMMAND_PASTE:
PasteFromClipboard;
EDITOR_COMMAND_UNDO:
result := B(Undo);
EDITOR_COMMAND_REDO:
result := B(Redo);
EDITOR_COMMAND_CLEAR_UNDO_BUFFER:
ClearUndoHistory;
EDITOR_COMMAND_GOTO_SOF:
FTextFile.GotoSOF(Param1 <> 0);
EDITOR_COMMAND_GOTO_EOF:
FTextFile.GotoEOF(Param1 <> 0);
EDITOR_COMMAND_RETURN:
Return;
EDITOR_COMMAND_CHAR:
InsertChar(Char(Param1), Param2 <> 0);
EDITOR_COMMAND_GET_AT_SOF:
result := B(FTextFile.AtSOF);
EDITOR_COMMAND_GET_AT_EOL:
result := B(FTextFile.AtEOL);
EDITOR_COMMAND_GET_BEYOND_EOL:
result := B(FTextFile.AtOrBeyondEOL);
EDITOR_COMMAND_GET_AT_EOF:
result := B(FTextFile.AtEOF);
EDITOR_COMMAND_GET_AT_LAST_LINE:
result := B(FTextFile.AtLastLine);
EDITOR_COMMAND_GET_HAS_SELECTION:
result := B(FTextFile.HasSelection);
EDITOR_COMMAND_GET_LINE_NUMBER_0:
result := FTextFile.CaretPos.Y;
EDITOR_COMMAND_GET_COL_NUMBER_0:
result := FTextFile.CaretPos.X;
EDITOR_COMMAND_GET_CHR_INDEX:
result := SelStart;
EDITOR_COMMAND_GOTO_POINT:
FTextFile.CaretPos.SetPoint(Param1, Param2, Param3 <> 0);
EDITOR_COMMAND_GOTO_INDEX:
SelStart := Param1;
EDITOR_COMMAND_GET_SEL_LENGTH:
result := SelLength;
EDITOR_COMMAND_SET_SEL_LENGTH:
SelLength := Param1;
EDITOR_COMMAND_GET_EDIT_MODE:
result := ord(FTextFile.EditMode);
EDITOR_COMMAND_SET_EDIT_MODE:
SetEditMode(TEditMode(Param1));
EDITOR_COMMAND_GET_SELECTION_MODE:
result := ord(GetSelType);
EDITOR_COMMAND_SET_SELECTION_MODE:
SetSelType(TSelectionType(Param1));
EDITOR_COMMAND_GET_OVERWRITE:
result := B(FOverwrite);
EDITOR_COMMAND_SET_OVERWRITE:
SetOverwrite(Param1 <> 0);
EDITOR_COMMAND_GET_AUTO_REPLACE:
result := B(FAutoReplace);
EDITOR_COMMAND_SET_AUTO_REPLACE:
AutoReplace := Param1 <> 0;
EDITOR_COMMAND_GET_CHAR:
result := Integer(GetCharAtCaret);
EDITOR_COMMAND_ADD_INDENT:
AddIndent;
EDITOR_COMMAND_REMOVE_INDENT:
RemoveIndent;
EDITOR_COMMAND_TRIM_INDENT:
RemoveAllIndent;
EDITOR_COMMAND_SWAP_UP:
SwapLinesAbove;
EDITOR_COMMAND_SWAP_DOWN:
SwapLinesBelow;
EDITOR_COMMAND_GET_AUTO_INDENT:
result := B(FAutoIndent);
EDITOR_COMMAND_SET_AUTO_INDENT:
SetAutoIndent(Param1 <> 0);
EDITOR_COMMAND_GET_CARET_BEYOND_EOL:
result := B(FTextFile.CaretAfterEOL);
EDITOR_COMMAND_SET_CARET_BEYOND_EOL:
SetCaretAfterEOL(Param1 <> 0);
EDITOR_COMMAND_GET_NUM_CHARACTERS:
result := FTextFile.NumCharacters;
EDITOR_COMMAND_GET_TEXT_SIZE:
result := FTextFile.VirtualTextLength;
EDITOR_COMMAND_GET_NUM_LINES:
result := FTextFile.LineCount;
EDITOR_COMMAND_GET_MAX_WIDTH:
result := FTextFile.MaxLineWidth;
EDITOR_COMMAND_SCROLL_TO_CARET:
result := B(ScrollToCaret);
EDITOR_COMMAND_CENTER_ON_SELECTION:
CenterOnSelection(Param1 <> 0);
EDITOR_COMMAND_REPLACE_TOKEN:
DoAutoReplace;
EDITOR_COMMAND_REPLACE_CODEPOINT:
FTextFile.ReplaceCodepoint;
EDITOR_COMMAND_UPDATE_SCROLLBARS:
UpdateScrollBars;
EDITOR_COMMAND_UPDATE_CARET:
UpdateCaret;
EDITOR_COMMAND_UPDATE_CURSOR:
ChangeCursor;
EDITOR_COMMAND_REDRAW:
Invalidate;
EDITOR_COMMAND_REDRAW_LINE:
VisualUpdate(ctLine, Param1, 0, 0, 0);
EDITOR_COMMAND_REDRAW_LINE_RANGE:
VisualUpdate(ctLineRange, Param1, Param2, 0, 0);
EDITOR_COMMAND_REDRAW_BLOCK:
VisualUpdate(ctBlock, Param1, Param2, Param3, Param4);
EDITOR_COMMAND_GET_MODIFIED:
result := B(FTextFile.FileModified);
EDITOR_COMMAND_SET_MODIFIED:
FTextFile.FileModified := Param1 <> 0;
EDITOR_COMMAND_NEW:
NewFile;
EDITOR_COMMAND_CLEAR:
FTextFile.Clear;
EDITOR_COMMAND_OPEN:
LoadFromFile(PChar(Param1), TEncoding.UTF8);
EDITOR_COMMAND_SAVE:
SaveToFile(PChar(Param1));
EDITOR_COMMAND_GET_HIDDEN:
result := B(FShowHiddenCharacters);
EDITOR_COMMAND_SET_HIDDEN:
SetShowHiddenCharacters(Param1 <> 0);
EDITOR_COMMAND_SET_SELECTION:
begin
FTextFile.CaretPos.SetPoint(Param1, Param2, false);
FTextFile.CaretPos.SetPoint(Param3, Param4, true);
end;
EDITOR_COMMAND_GET_MATCH_BRACKETS:
result := B(FMatchBrackets);
EDITOR_COMMAND_SET_MATCH_BRACKETS:
SetMatchBrackets(Param1 <> 0);
EDITOR_COMMAND_GET_BRACKET_HIGHLIGHT:
result := B(FBracketHighlight);
EDITOR_COMMAND_GET_SCROLL_POS_X:
result := FScrollPos.X;
EDITOR_COMMAND_GET_SCROLL_POS_Y:
result := FScrollPos.Y;
EDITOR_COMMAND_SET_SCROLL_POS:
SetScrollPosXY(Param1, Param2);
EDITOR_COMMAND_REDRAW_CHAR:
VisualUpdate(ctChar, Param1, Param2, 0, 0);
EDITOR_COMMAND_REDRAW_CHARS:
VisualUpdate(ctChar, Param1, Param2, Param3, Param4);
EDITOR_COMMAND_GET_INDENT:
result := FIndentSize;
EDITOR_COMMAND_SET_INDENT:
SetIndentSize(Param1);
EDITOR_COMMAND_GET_TAB_LENGTH:
result := FTabLength;
EDITOR_COMMAND_SET_TAB_LENGTH:
FTabLength := Param1;
EDITOR_COMMAND_GET_SINGLE_LINE:
result := B(SingleLine);
EDITOR_COMMAND_SET_SINGLE_LINE:
SetSingleLine(Param1 <> 0);
EDITOR_COMMAND_GET_LABEL_MODE:
result := B(FLabelStyle);
EDITOR_COMMAND_SET_LABEL_MODE:
SetLabelStyle(Param1 <> 0);
EDITOR_COMMAND_GET_ELLIPSIS_MODE:
result := B(FLabelEllipsis);
EDITOR_COMMAND_SET_ELLIPSIS_MODE:
SetLabelEllipsis(Param1 <> 0);
EDITOR_COMMAND_GET_INPUT_TRANSFORM:
result := ord(FInputTransform);
EDITOR_COMMAND_SET_INPUT_TRANSFORM:
FInputTransform := TInputTransform(Param1);
EDITOR_COMMAND_GET_NUMBERS_ONLY:
result := B(FNumbersOnly);
EDITOR_COMMAND_SET_NUMBERS_ONLY:
FNumbersOnly := Param1 <> 0;
EDITOR_COMMAND_GET_PASSWORD_CHAR:
result := ord(FPasswordChar);
EDITOR_COMMAND_SET_PASSWORD_CHAR:
SetPasswordChar(Chr(Param1));
EDITOR_COMMAND_GET_UNICODE_FALLBACK:
result := B(FUnicodeFallback);
EDITOR_COMMAND_SET_UNICODE_FALLBACK:
SetUnicodeFallback(Param1 <> 0);
EDITOR_COMMAND_ESCAPE:
Escape(Param1 <> 0);
EDITOR_COMMAND_USE_DEFAULT_FALLBACK_FONTS:
UseDefaultFallbackFonts;
EDITOR_COMMAND_SHOW_BALLOON:
result := B(ShowBalloon(PChar(Param1), PChar(Param2), TBalloonIconKind(Param3),
TBalloonPersistence(Param4), CaretPos));
EDITOR_COMMAND_HIDE_BALLOON:
HideBalloon;
EDITOR_COMMAND_SHOW_BALLOON_POS:
result := B(ShowBalloon(PChar(Param1), PChar(Param2), TBalloonIconKind(Byte(Param3)),
TBalloonPersistence(Byte(Param3 shr 8)), FTextFile.GetPointOfIndex(Param4)));
EDITOR_COMMAND_IS_BALLOON_VISIBLE:
result := B(BalloonVisible);
EDITOR_COMMAND_ADJUST_HEIGHT:
begin
result := B(SingleLine);
if result <> 0 then
ClientHeight := FFontSize.cy + AUTO_HEIGHT_PADDING;
end;
EDITOR_COMMAND_GET_UNDO_LENGTH:
result := FTextFile.HistoryManager.Count;
EDITOR_COMMAND_GET_UNDO_SIZE:
result := FTextFile.HistoryManager.Size;
EDITOR_COMMAND_GET_UNDO_MAX_SIZE:
result := FTextFile.HistoryManager.MaxSize;
EDITOR_COMMAND_SET_UNDO_MAX_SIZE:
FTextFile.HistoryManager.MaxSize := Param1;
EDITOR_COMMAND_GET_UNDO_FIRST_INDEX:
result := FTextFile.HistoryManager.FirstItem;
EDITOR_COMMAND_GET_UNDO_LAST_INDEX:
result := FTextFile.HistoryManager.LastItem;
EDITOR_COMMAND_GET_UNDO_POSITION:
result := FTextFile.HistoryManager.HistoryIndex;
EDITOR_COMMAND_WINDOWS_MESSAGE:
result := Perform(Param1, Param2, Param3);
EDITOR_COMMAND_COPY_ALL:
CopyAll;
EDITOR_COMMAND_FIND:
result := Find(MakeFindQuery(PChar(Param1), Param2 <> 0, Param3 <> 0,
Param4 <> 0));
EDITOR_COMMAND_GET_FIND_COUNT:
result := FTextFile.FindCount;
EDITOR_COMMAND_FIND_NEXT:
result := FindNext;
EDITOR_COMMAND_FIND_PREV:
result := FindPrevious;
EDITOR_COMMAND_FIND_FROM_TOP:
result := FindFromTop;
EDITOR_COMMAND_GET_START_OVER:
result := B(FStartOver);
EDITOR_COMMAND_SET_START_OVER:
FStartOver := Param1 <> 0;
EDITOR_COMMAND_REPLACE_ALL:
result := ReplaceAll(MakeFindQuery(PChar(Param1), (Param3 and 1) <> 0,
(Param3 and 2) <> 0, (Param3 and 4) <> 0), PChar(Param2));
EDITOR_COMMAND_ADD_UNDO_RECORD:
AddUndoRecord(PChar(Param1), UNDONAMEID(Param2));
EDITOR_COMMAND_POSTTYPE:
PostType;
EDITOR_COMMAND_TYPE_TIMER_EMD:
TypeTimerEnd;
EDITOR_COMMAND_TYPE_TIMER_DISABLE:
FTypeTimer.Enabled := false;
EDITOR_COMMAND_TYPE_TIMER_DISCONNECT:
FTypeTimer.OnTimer := nil;
EDITOR_COMMAND_TYPE_TIMER_CONNECT:
FTypeTimer.OnTimer := TypeTimerTimer;
EDITOR_COMMAND_GET_ENABLED:
result := B(Enabled);
EDITOR_COMMAND_SET_ENABLED:
Enabled := Param1 <> 0;
EDITOR_COMMAND_IS_FOCUSED:
result := B(Focused);
EDITOR_COMMAND_TRY_FOCUS:
begin
result := B(CanFocus);
if result <> 0 then
SetFocus;
end;
EDITOR_COMMAND_GET_FIRST_VISIBLE_LINE:
result := FirstVisibleLine(true);
EDITOR_COMMAND_GET_LAST_VISIBLE_LINE:
result := LastVisibleLine(true);
EDITOR_COMMAND_RECOMPUTE_HOR_EXTENT:
begin
RecomputeHorizontalExtent;
result := FCachedHorizontalExtent;
end;
EDITOR_COMMAND_ACTIVATE_CONTROL:
result := ActivateControl;
EDITOR_COMMAND_REMOVE_LINE_CONTROL:
result := B(FTextFile.DeleteControlAtLine(Param1));
EDITOR_COMMAND_ADD_LINE_CONTROL:
AddLineControl(TControl(Param1));
EDITOR_COMMAND_ADD_GRAPHICS:
AddGraphic(TGraphic(Param1));
EDITOR_COMMAND_INSERT_LINE_CONTROL:
InsertLineControl(TControl(Param1), Param2);
EDITOR_COMMAND_INSERT_GRAPHICS:
InsertGraphic(TGraphic(Param1), Param2);
EDITOR_COMMAND_TRIM_RIGHT:
TrimRight;
EDITOR_COMMAND_BOOKMARK_SET:
AddBookmark(Param1);
EDITOR_COMMAND_BOOKMARK_GO:
GotoBookmark(Param1);
EDITOR_COMMAND_BOOKMARK_CLEAR:
AddBookmark(Param1, EMPTY_BOOKMARK);
EDITOR_COMMAND_BOOKMARK_CLEAR_ALL:
ClearBookmarks;
EDITOR_COMMAND_CLASS_USE:
SetClass(CaretPos.Y, Classes[Param1].Name);
EDITOR_COMMAND_CLASS_REMOVE:
SetClass(CaretPos.Y, '');
EDITOR_COMMAND_SET_FP:
SetFormattingProcessor(TFormattingProcessor(Param1));
EDITOR_COMMAND_EXPORT_HTML:
ExportToHTML(PChar(Param1));
EDITOR_COMMAND_OPEN_URL_AT_CARET:
OpenURLAtCaret;
EDITOR_COMMAND_SELECT_LINE_INDEX:
SelectLine(Param1);
EDITOR_COMMAND_SELECT_LINE_RANGE:
SelectLines(Param1, Param2);
EDITOR_COMMAND_DISABLE_SCROLL_TO_CARET:
FNoScrollToCaret := true;
EDITOR_COMMAND_ENABLE_SCROLL_TO_CARET:
FNoScrollToCaret := false;
EDITOR_COMMAND_CREATE_SELECTION:
FTextFile.CaretPos.CreateSelection(Point(Param1, Param2),
Point(Param3, Param4), stLineBased);
EDITOR_COMMAND_CREATE_BLOCK_SELECTION:
FTextFile.CaretPos.CreateSelection(Point(Param1, Param2),
Point(Param3, Param4), stBlock);
EDITOR_COMMAND_GET_LINE_HIGHLIGHT:
result := B(FLineHighlight);
EDITOR_COMMAND_SET_LINE_HIGHLIGHT:
SetLineHighlight(Param1 <> 0);
EDITOR_COMMAND_REDRAW_RULER:
UpdateRuler;
EDITOR_COMMAND_REDRAW_RULER_LINE:
UpdateRulerLine(Param1);
EDITOR_COMMAND_PRINT:
if Param1 <> 0 then
Print(PChar(Param1), Param2, Param3)
else
Print(Param2, Param3);
EDITOR_COMMAND_PRINT_SELECTION:
if Param1 <> 0 then
PrintSelection(PChar(Param1))
else
PrintSelection;
EDITOR_COMMAND_SET_PRINT_MARGINS:
begin
FPrintSettings.HorizontalMargin := Param1;
FPrintSettings.VerticalMargin := Param2;
end;
EDITOR_COMMAND_SET_PRINT_WW_OPTIONS:
begin
FPrintSettings.WordWrap := Param1 <> 0;
FPrintSettings.NiceWordWrap := Param2 <> 0;
if Param3 = 0 then
FPrintSettings.ShowWordWrapIcon := false
else
begin
FPrintSettings.ShowWordWrapIcon := true;
FPrintSettings.WordWrapIcon := Char(Param3);
FPrintSettings.WordWrapIconColor := TColor(Param4);
end;
end;
EDITOR_COMMAND_PRINT_DIALOG:
begin
with TPrintDialog.Create(nil) do
try
if FTextFile.HasSelection then
Options := [poSelection, poWarning]
else
Options := [poWarning];
if Execute then
if PrintRange = prSelection then
PrintSelection(SDefaultPrintJobTitle)
else
Print(SDefaultPrintJobTitle);
finally
Free;
end;
end;
EDITOR_COMMAND_GET_PRINT_VMARGIN:
result := FPrintSettings.VerticalMargin;
EDITOR_COMMAND_GET_PRINT_HMARGIN:
result := FPrintSettings.HorizontalMargin;
EDITOR_COMMAND_GET_PRINT_WW_OPTIONS:
result := B(FPrintSettings.WordWrap) or
(B(FPrintSettings.NiceWordWrap) shl 16);
EDITOR_COMMAND_GET_PRINT_WW_CHAR:
if FPrintSettings.ShowWordWrapIcon then
result := ord(FPrintSettings.WordWrapIcon)
else
result := 0;
EDITOR_COMMAND_GET_PRINT_WW_COLOR:
result := FPrintSettings.WordWrapIconColor;
EDITOR_COMMAND_WORDWRAP:
WordWrap(Param1, Param2 <> 0, Char(Param3));
EDITOR_COMMAND_UPPER_CASE:
ChrTransformText(ChrUpperCase, STransformNameUpperCase);
EDITOR_COMMAND_LOWER_CASE:
ChrTransformText(ChrLowerCase, STransformNameLowerCase);
EDITOR_COMMAND_INVERT_CASE:
ChrTransformText(ChrInvertCase, STransformNameInvertCase);
EDITOR_COMMAND_SEL_UPPER_CASE:
ChrTransformSelection(ChrUpperCase, STransformNameUpperCase);
EDITOR_COMMAND_SEL_LOWER_CASE:
ChrTransformSelection(ChrLowerCase, STransformNameLowerCase);
EDITOR_COMMAND_SEL_INVERT_CASE:
ChrTransformSelection(ChrInvertCase, STransformNameInvertCase);
EDITOR_COMMAND_CAMEL_CASE:
TransformText(TxtCamelCase, STransformNameCamelCase);
EDITOR_COMMAND_SENTENCE_CASE:
TransformText(TxtSentenceCase, STransformNameSentenceCase);
EDITOR_COMMAND_SEL_CAMEL_CASE:
TransformSelection(TxtCamelCase, STransformNameCamelCase);
EDITOR_COMMAND_SEL_SENTENCE_CASE:
TransformSelection(TxtSentenceCase, STransformNameSentenceCase);
EDITOR_COMMAND_SEL_REVERSE:
TransformSelection(ReverseText, STransformNameReverse);
EDITOR_COMMAND_ROT13:
ChrTransformText(ChrRot13, STransformNameRot13);
EDITOR_COMMAND_SEL_ROT13:
ChrTransformSelection(ChrRot13, STransformNameRot13);
EDITOR_COMMAND_CAESAR:
if (Param1 <> 0) or TMultiInputBox.NumInputBox(GetParentForm(Self), SCaesarNTitle, SCaesarNText, Param1, ord('A') - ord('Z') - 1, ord('Z') - ord('A') + 1) then
ChrTransformText(ChrCaesar(Param1), Format(STransformNameCaesarN, [Param1]));
EDITOR_COMMAND_SEL_CAESAR:
if (Param1 <> 0) or TMultiInputBox.NumInputBox(GetParentForm(Self), SCaesarNTitle, SCaesarNText, Param1, ord('A') - ord('Z') - 1, ord('Z') - ord('A') + 1) then
ChrTransformSelection(ChrCaesar(Param1), Format(STransformNameCaesarN, [Param1]));
EDITOR_COMMAND_VIGENERE:
if Param2 <> 0 then
TransformText(TxtVigenère(PChar(Param2), Param1 <> 0), STransformNameVigenere)
else
if TMultiInputBox.TextInputBox(GetParentForm(Self), SVigenereTitle, SVigenereText, S, ecUpperCase, false, [aoCapitalAZ]) then
TransformText(TxtVigenère(S, Param1 <> 0), STransformNameVigenere);
EDITOR_COMMAND_SEL_VIGENERE:
if Param2 <> 0 then
TransformSelection(TxtVigenère(PChar(Param2), Param1 <> 0), STransformNameVigenere)
else
if TMultiInputBox.TextInputBox(GetParentForm(Self), SVigenereTitle, SVigenereText, S, ecUpperCase, false, [aoCapitalAZ]) then
TransformSelection(TxtVigenère(S, Param1 <> 0), STransformNameVigenere);
EDITOR_COMMAND_UPDATE_SCROLL_MODE:
UpdateScrollMode;
EDITOR_COMMAND_GET_SCROLL_MODE:
result := B(FScrollMode);
EDITOR_COMMAND_SORT:
result := B(Sort(Param1, Param2));
EDITOR_COMMAND_SORT_ALL:
result := B(Sort);
EDITOR_COMMAND_SORT_SEL:
result := B(SortSelection);
EDITOR_COMMAND_SET_LINE_COMPARER:
SetLineComparer(TLineComparer(Param1));
EDITOR_COMMAND_GET_LINE_COMPARER:
result := integer(@LineComparer);
EDITOR_COMMAND_SET_SORT_REVERSE:
SortReverseOrder := Param1 <> 0;
EDITOR_COMMAND_GET_SORT_REVERSE:
result := B(SortReverseOrder);
EDITOR_COMMAND_MAKE_LINES_UNIQUE:
result := B(MakeLinesUnique);
EDITOR_COMMAND_CLI_NEW_PROMPT:
CliNewPrompt;
EDITOR_COMMAND_CLI_WRITELN:
CliWriteLn(PChar(Param1), PChar(Param2));
EDITOR_COMMAND_ABORT_SCRIPT:
FAbortScript := true;
EDITOR_COMMAND_WRITE_INT:
SelText := IntToStr(Param1);
EDITOR_COMMAND_ABORT_SCRIPT_IF_EOL:
if FTextFile.AtOrBeyondEOL then
FAbortScript := true;
EDITOR_COMMAND_ABORT_SCRIPT_IF_LL:
if FTextFile.AtLastLine then
FAbortScript := true;
EDITOR_COMMAND_ABORT_SCRIPT_IF_EOF:
if FTextFile.AtOrBeyondEOF then
FAbortScript := true;
EDITOR_COMMAND_ABORT_SCRIPT_IF_SOF:
if FTextFile.AtSOF then
FAbortScript := true;
EDITOR_COMMAND_SET_SCRIPT_COUNTER:
FScriptCounter := Param1;
EDITOR_COMMAND_GET_SCRIPT_COUNTER:
result := FScriptCounter;
EDITOR_COMMAND_GET_LINE_NUMBER_1:
result := FTextFile.CaretPos.Y + 1;
EDITOR_COMMAND_GET_COL_NUMBER_1:
result := FTextFile.CaretPos.X + 1;
EDITOR_COMMAND_WRITE_DATE:
SelText := DateToStr(Date);
EDITOR_COMMAND_WRITE_TIME:
SelText := TimeToStr(Time);
EDITOR_COMMAND_WRITE_DATETIME:
SelText := DateTimeToStr(Now);
EDITOR_COMMAND_GET_TICKCOUNT:
result := GetTickCount;
EDITOR_COMMAND_GET_RANDOM_INTEGER:
if Param2 > Param1 then
result := RandomRange(Param1, Param2)
else
result := RandomRange(0, MaxInt);
EDITOR_COMMAND_FIX_REMOVED_LINE_CONTROLS:
FixRemovedLineControlLines;
EDITOR_COMMAND_CLI_HISTORY_UP:
result := B(CliHistoryUp);
EDITOR_COMMAND_CLI_HISTORY_DOWN:
result := B(CliHistoryDown);
EDITOR_COMMAND_CLI_HISTORY_CLEAR:
CliClearHistory;
EDITOR_COMMAND_CLI_HISTORY_ADD:
CliAddHistory(PChar(Param1));
EDITOR_COMMAND_CLI_GET_HISTORY_LENGTH:
result := CliHistoryCount;
EDITOR_COMMAND_CLI_GET_HISTORY_INDEX:
result := CliHistoryIndex;
EDITOR_COMMAND_CLI_HISTORY_RECALL:
result := B(CliHistoryRecall(Param1));
EDITOR_COMMAND_BEGIN_ADD_LINES:
BeginAddLine;
EDITOR_COMMAND_END_ADD_LINES:
EndAddLine;
EDITOR_COMMAND_GET_LISTBOX_MODE:
result := B(ListBoxMode);
EDITOR_COMMAND_SET_LISTBOX_MODE:
ListBoxMode := Param1 <> 0;
EDITOR_COMMAND_WRITE_STRING:
SelText := PChar(Param1);
EDITOR_COMMAND_WRITE_INPUT_DIALOG:
begin
S := PChar(Param3);
if TMultiInputBox.TextInputBox(GetParentForm(Self), PChar(Param1), PChar(Param2), S) then
SelText := S;
end;
EDITOR_COMMAND_SET_AS_HYPHEN_ASTERISK_TOGGLE:
FASHyphenAsteriskToggle := Param1 <> 0;
EDITOR_COMMAND_SET_MULTI_CHAR_SELECT:
MultiCharSelect := Param1 <> 0;
EDITOR_COMMAND_GET_MULTI_CHAR_SELECT:
result := B(FMultiCharSelect);
EDITOR_COMMAND_SET_MULTI_CHAR_REPORT_VIEW:
MultiCharReportView := Param1 <> 0;
EDITOR_COMMAND_GET_MULTI_CHAR_REPORT_VIEW:
result := B(FMultiCharReportView);
EDITOR_COMMAND_SET_NO_VERIFY_FONT:
FNoVerifyFont := Param1 <> 0;
EDITOR_COMMAND_SET_DOUBLE_BUFFERING:
DoubleBuffered := Param1 <> 0;
EDITOR_COMMAND_REPLACE_ALL_IN_SELECTION:
result := ReplaceAll(MakeFindQuery(PChar(Param1), (Param3 and 1) <> 0,
(Param3 and 2) <> 0, (Param3 and 4) <> 0), PChar(Param2), true);
EDITOR_COMMAND_SET_BITMAP_EFFECT:
if InRange(Param1, ord(low(TBitmapEffect)), ord(high(TBitmapEffect))) then
begin
result := 1;
BitmapEffect := TBitmapEffect(Param1);
end
else
result := 0;
EDITOR_COMMAND_GET_BITMAP_EFFECT:
result := ord(FBitmapEffect);
EDITOR_COMMAND_SET_DISABLED_EFFECT:
if InRange(Param1, ord(low(TBitmapEffect)), ord(high(TBitmapEffect))) then
begin
result := 1;
DisabledEffect := TBitmapEffect(Param1);
end
else
result := 0;
EDITOR_COMMAND_GET_DISABLED_EFFECT:
result := ord(FDisabledEffect);
EDITOR_COMMAND_REPEAT:
for i := 1 to trunc(Param1) do
EditorCommand(Param2, Param3, Param4);
EDITOR_COMMAND_REPEAT_EX_SET_NUM:
FRepeatExNum := trunc(Param1);
EDITOR_COMMAND_REPEAT_EX_SET_COMMAND:
FRepeatExCommand := trunc(Param1);
EDITOR_COMMAND_REPEAT_EX:
for i := 1 to FRepeatExNum do
EditorCommand(FRepeatExCommand, Param1, Param2, Param3, Param4);
EDITOR_COMMAND_RESTORE_MARGINS:
RestoreAllMargins;
EDITOR_COMMAND_FILL_WITH_CHAR:
result := B(FillWithChar(char(Param1)));
EDITOR_COMMAND_PASTE_AS_BLOCK:
result := B(PasteFromClipboardAsBlock);
EDITOR_COMMAND_TRUNCATE_AT:
TruncateAt(Param1, Param2, Param3, Char(Word(Param4)), Param4 and $FFFF0000 <> 0);
EDITOR_COMMAND_TRUNCATE_AT_IN_FILE:
TruncateAt(Param1, Char(Word(Param2)), Param3 <> 0);
EDITOR_COMMAND_TRUNCATE_AT_IN_SELECTION:
TruncateAtInSelection(Param1, Char(Word(Param2)), Param3 <> 0);
EDITOR_COMMAND_GET_JUST_OPENED:
result := B(FTextFile.RecentlyOpened);
EDITOR_COMMAND_LOAD_DEFAULT_CLASSES:
LoadDefaultClasses;
EDITOR_COMMAND_BEGIN_VISUAL_UPDATE:
BeginVisualUpdate;
EDITOR_COMMAND_END_VISUAL_UPDATE:
EndVisualUpdate(Param1 <> 0);
EDITOR_COMMAND_SURROUND_SEL:
SurroundText(PChar(Param1), PChar(Param2));
EDITOR_COMMAND_FILTER_LINES:
if Param1 = SizeOf(TFilterOptions) then
begin
Filter(PFilterOptions(Param2)^);
result := 1;
end
else
result := 0;
EDITOR_COMMAND_UPDATE_SPI:
UpdateSPI;
EDITOR_COMMAND_SET_STRICT_READONLY:
FTextFile.StrictReadOnly := Param1 <> 0;
EDITOR_COMMAND_REMOVE_GHOST_BOOKMARKS:
result := B(FTextFile.RemoveGhostBookmarks);
EDITOR_COMMAND_CHARACTER_FIND:
result := Find(MakeFindQuery(Param1));
end;
end;
procedure TTextEditor.EndAddLine;
begin
FTextFile.EndAddLine;
end;
procedure TTextEditor.AbortScript;
begin
FAbortScript := true;
end;
function TTextEditor.ActivateControl: HWND;
var
ctl: TControl;
begin
result := 0;
ctl := GetControlFromLine(CaretPos.Y);
if Assigned(ctl) and (ctl is TWinControl) then
begin
TWinControl(ctl).SetFocus;
result := TWinControl(ctl).Handle;
end
else if Assigned(ctl) and (ctl is TImage) and Assigned(TImage(ctl).PopupMenu) then
begin
TImage(ctl).PopupMenu.PopupComponent := TImage(ctl);
with ClientToScreen(Point(0, GetLineTop(CaretPos.Y))) do
TImage(ctl).PopupMenu.Popup(X, Y);
result := Handle;
end;
end;
procedure TTextEditor.Escape(AAll: boolean);
begin
if FMultipleCarets then
begin
FMultipleCarets := false;
SetLength(FCarets, 0);
Invalidate;
RemoveNotification(EN_MULTICARET);
if not AAll then Exit;
end;
if BalloonVisible then
begin
HideBalloon;
if not AAll then Exit;
end;
if (EditMode = emConsole) and FTextFile.AtLastLine and not AAll then
ClearLine;
end;
procedure TTextEditor.ExportToHTML(const FileName: TFileName);
function Q(const S: string): string;
begin
if Pos(#32, S) > 0 then
result := '"' + S + '"'
else
result := S;
end;
function MakeClassName(const S: string): string;
var
i: Integer;
begin
result := '';
for i := 1 to Length(S) do
if S[i].IsLetterOrDigit then
result := result + S[i];
end;
function HtmlEscape(const C: char): string;
begin
if C = '<' then
result := '<'
else if C = '>' then
result := '>'
else if C = '&' then
result := '&'
else
result := C;
end;
var
SL: TStringList;
DocumentName, FPName: string;
Indent: string;
rules: TCSSRules;
oldc, c: Integer;
i: Integer;
j: Integer;
L: string;
begin
Indent := DupeString(#32, FIndentSize);
DocumentName := FTextFile.FileName;
if DocumentName = '' then
DocumentName := SDefaultFileName;
if Assigned(FFormattingProcessor) then
FPName := FFormattingProcessor.ClassName
else
FPName := SNoInteractiveFormattingParen;
SL := TStringList.Create;
try
SL.Add('<!DOCTYPE html>');
SL.Add('');
SL.Add('<html xmlns="http://www.w3.org/1999/xhtml">');
SL.Add('<head>');
SL.Add('');
SL.Add('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
SL.Add('<title>' + ExtractFileName(DocumentName) + '</title>');
SL.Add('');
SL.Add('<style>');
SL.Add('main {');
SL.Add(Indent + 'background-color: ' + CSSColor(FBackgroundColor) + ';');
SL.Add(Indent + 'color: ' + CSSColor(FForegroundColor) + ';');
SL.Add('}');
SL.Add('pre {');
SL.Add(Indent + 'font-family: ' + Q(FFont.Name) + ';');
SL.Add(Indent + 'font-size: ' + IntToStr(FFont.Size) + 'pt;');
SL.Add('}');
if (Length(FClassArray) > 0) and FTextFile.UseLineClasses then
begin
SL.Add('');
for i := 0 to high(FClassArray) do
begin
SL.Add('.' + MakeClassName(FClassArray[i].Name) + ' {');
SL.Add(Indent + 'font-size: ' + IntToStr(FClassArray[i].Format.Size) + 'pt;');
SL.Add(Indent + 'color: ' + CSSColor(FClassArray[i].Format.Color) + ';');
if fsBold in FClassArray[i].Format.Style then
SL.Add(Indent + 'font-weight: ' + 'bold;');
if fsItalic in FClassArray[i].Format.Style then
SL.Add(Indent + 'font-style: ' + 'italic;');
if fsUnderline in FClassArray[i].Format.Style then
SL.Add(Indent + 'text-decoration: ' + 'underline;');
SL.Add('}');
end;
end;
if Assigned(FFormattingProcessor) then
begin
SL.Add('');
rules := FFormattingProcessor.GetCSSRules;
for i := low(rules) to high(rules) do
begin
SL.Add('.' + rules[i].Selector + ' {');
for j := low(rules[i].Declarations) to high(rules[i].Declarations) do
SL.Add(Indent + rules[i].Declarations[j].CSSProperty + ': ' + rules[i].Declarations[j].Value + ';');
SL.Add('}');
end;
end;
SL.Add('</style>');
SL.Add('');
SL.Add('</head>');
SL.Add('');
SL.Add('<body>');
SL.Add('');
SL.Add('<header>');
SL.Add('');
SL.Add(Indent + '<h1>' + ExtractFileName(DocumentName) + '</h1>');
SL.Add('');
SL.Add(Indent + '<dl>');
SL.Add(Indent + Indent + '<dt>' + SHTMLExportFileName + '</dt>');
SL.Add(Indent + Indent + '<dd>' + DocumentName + '</dd>');
SL.Add(Indent + Indent + '<dt>' + SHTMLExportDate + '</dt>');
SL.Add(Indent + Indent + '<dd><time>' + FormatDateTime('yyyy"-"mm"-"dd', Date) + '</time></dd>');
SL.Add(Indent + Indent + '<dt>' + SHTMLExportTime + '</dt>');
SL.Add(Indent + Indent + '<dd><time>' + FormatDateTime('hh":"mm":"ss', Time) + '</time></dd>');
SL.Add(Indent + Indent + '<dt>' + SHTMLExportFP + '</dt>');
SL.Add(Indent + Indent + '<dd>' + FPName + '</dd>');
SL.Add(Indent + '</dl>');
SL.Add('');
SL.Add('</header>');
SL.Add('');
SL.Add('<main>');
SL.Add('');
SL.Add(Indent + '<pre>');
oldc := -1;
c := -1;
for i := 0 to FTextFile.LineCount - 1 do
begin
L := '';
if LineClasses[i] <> '' then
L := '<span class="' + MakeClassName(LineClasses[i]) + '">';
if c <> -1 then
L := L + '<span class="' + rules[c].Selector + '">';
for j := 0 to FTextFile.PhysicalLineWidths[i] - 1 do
begin
if Assigned(FFormattingProcessor) then
c := FFormattingProcessor.GetCharCSSClass(i, j, FTextFile.Character[i, j]);
if c <> oldc then
begin
if oldc <> -1 then
L := L + '</span>';
if c shr 16 = 0 then
L := L + '<span class="' + rules[c].Selector + '">'
else
L := L + '<span class="' + rules[c and $FFFF].Selector + ' ' + rules[c shr 16].Selector + '">'
end;
L := L + HtmlEscape(FTextFile.Character[i, j]);
oldc := c;
end;
if c <> -1 then
L := L + '</span>';
if LineClasses[i] <> '' then
L := L + '</span>';
SL.Add(L);
end;
SL.Add('</pre>');
SL.Add('');
SL.Add('</main>');
SL.Add('');
SL.Add('</body>');
SL.Add('</html>');
SL.SaveToFile(FileName, TEncoding.UTF8);
finally
SL.Free;
end;
end;
function TTextEditor.CharInSet(AChar: char; ASet: array of char): boolean;
var
i: Integer;
begin
result := false;
for i := low(ASet) to high(ASet) do
if AChar = ASet[i] then
Exit(true);
end;
function TTextEditor.CharInAnyMultiCharSet(AChar: char): boolean;
begin
result := CharInSet(AChar, MultiCharHyphen) or CharInSet(AChar, MultiCharAsterisk) or
CharInSet(AChar, MultiCharDoubleQuote) or CharInSet(AChar, MultiCharSingleQuote);
end;
procedure TTextEditor.KeyDown(var Key: Word; Shift: TShiftState);
var
c: char;
begin
inherited;
UpdateScrollMode;
if Key in [VK_SHIFT, VK_CONTROL, VK_MENU, VK_SCROLL] then
ChangeCursor(Shift);
if (EditMode = emConsole) and (Key = VK_F7) then
begin
CliHistoryDialogSelect;
Exit;
end;
if (Key = VK_F9) and FMultiCharSelect then
begin
c := GetCharBeforeCaret;
if CharInSet(c, MultiCharHyphen) then
DoMultiCharSelect(MultiCharHyphen)
else if CharInSet(c, MultiCharAsterisk) then
DoMultiCharSelect(MultiCharAsterisk)
else if CharInSet(c, MultiCharDoubleQuote) then
DoMultiCharSelect(MultiCharDoubleQuote)
else if CharInSet(c, MultiCharSingleQuote) then
DoMultiCharSelect(MultiCharSingleQuote);
Exit;
end;
if FScrollMode then
begin
case Key of
VK_UP:
SetScrollPosY(FScrollPos.Y - IfThen(ssCtrl in Shift, 1, FFontSize.cy));
VK_DOWN:
SetScrollPosY(FScrollPos.Y + IfThen(ssCtrl in Shift, 1, FFontSize.cy));
VK_LEFT:
SetScrollPosX(FScrollPos.X - IfThen(ssCtrl in Shift, 1, FFontSize.cx));
VK_RIGHT:
SetScrollPosX(FScrollPos.X + IfThen(ssCtrl in Shift, 1, FFontSize.cx));
VK_PRIOR:
SetScrollPosY(FScrollPos.Y - ClientHeight);
VK_NEXT:
SetScrollPosY(FScrollPos.Y + ClientHeight);
VK_HOME:
SetScrollPosY(0);
VK_END:
SetScrollPosY(FTextFile.LineCount * FFontSize.cy - ClientHeight);
end;
Exit;
end;
if [ssShift, ssCtrl] <= Shift then
case Key of
VK_UP:
begin
SwapLinesAbove;
Exit;
end;
VK_DOWN:
begin
SwapLinesBelow;
Exit;
end;
ord('1')..ord('9'):
if FHandleBookmarkHotkeys then
begin
AddBookmark(Key - ord('0'));
Exit;
end;
end;
if (ssCtrl in Shift) and (FTextFile.EditMode = emText) then
case Key of
VK_UP:
begin
with GetLastMultiCaret do
if Y > 0 then
CreateNewCaretAt(Point(X, Y - 1));
Exit;
end;
VK_DOWN:
begin
with GetLastMultiCaret do
if Y < LineCount - 1 then
CreateNewCaretAt(Point(X, Y + 1));
Exit;
end;
end;
if FHandleBookmarkHotkeys and (Shift = [ssCtrl]) and
(Key in [ord('1')..ord('9')]) then
begin
GotoBookmark(ord(key) - ord('0'));
Exit;
end;
case Key of
VK_BACK:
Backspace(ssCtrl in Shift);
VK_DELETE:
begin
Delete(ssCtrl in Shift);
if FMatchBrackets then
TextFileCaretPosChange(Self);
end;
VK_LEFT:
FTextFile.Left(ssCtrl in Shift, ssShift in Shift, ssAlt in Shift);
VK_RIGHT:
FTextFile.Right(ssCtrl in Shift, ssShift in Shift, ssAlt in Shift);
VK_UP:
if (FTextFile.EditMode = emConsole) and FTextFile.AtLastLine and not (ssCtrl in Shift) then
CliHistoryUp
else if FMultiSize and not (ssAlt in Shift) then
GotoSamePixelAtPrevLine(ssShift in Shift)
else
FTextFile.Up(ssShift in Shift, ssAlt in Shift);
VK_DOWN:
if (FTextFile.EditMode = emConsole) and FTextFile.AtLastLine and not (ssCtrl in Shift) then
CliHistoryDown
else if FMultiSize and not (ssAlt in Shift) then
GotoSamePixelAtNextLine(ssShift in Shift)
else
FTextFile.Down(ssShift in Shift, ssAlt in Shift);
VK_RETURN:
begin
if FAutoReplace then DoAutoReplace;
Return;
end;
VK_HOME:
FTextFile.Home(ssCtrl in Shift, ssShift in Shift);
VK_END:
FTextFile.KEnd(ssCtrl in Shift, ssShift in Shift);
VK_PRIOR:
PageUp(ssShift in Shift);
VK_NEXT:
PageDown(ssShift in Shift);
VK_INSERT:
SetOverwrite(not FOverwrite);
VK_ESCAPE:
Escape;
VK_PAUSE:
case EditMode of
emText:
EditMode := emReadOnly;
emConsole: ;
emReadOnly:
EditMode := emText;
end;
end;
if FHandleHotkeys then