📄 rm_jveditorcommon.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvEditorCommon.PAS, released on 2004-01-25
The Initial Developers of the Original Code are: Andrei Prygounkov <a dott prygounkov att gmx dott de>
Copyright (c) 1999, 2002 Andrei Prygounkov
All Rights Reserved.
Contributor(s):
Burov Dmitry, translation of russian text.
Andreas Hausladen
Peter Th鰎nqvist
Remko Bonte
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
-----------------------------------------------------------------------------}
// $Id: JvEditorCommon.pas 10484 2006-04-14 10:36:04Z obones $
{ history
(JVCL Library versions) :
1.00:
- first release;
1.01:
- reduce caret blinking - method KeyUp;
- fix bug with setting SelLength to 0;
- changing SelStart now reset SelLength to 0;
- very simple tab - two blanks;
1.02:
- SmartTab;
- KeepTrailingBlanks;
- CursorBeyondEOF;
- AutoIndent;
- BackSpaceUnindents;
- two-key commands;
- automatically expands tabs when setting Lines property;
1.04:
- some bugs fixed in Completion;
- fix bug with reading SelLength property;
- new method TJvEditorStrings .SetLockText;
- new dynamic method TextAllChanged;
1.11:
- method StatusChanged;
- fixed bug with setting Lines.Text property;
- new method GetText with TIEditReader syntax;
1.14:
- selected color intialized with system colors;
1.17:
some improvements and bug fixes by Rafal Smotrzyk - rsmotrzyk att mikroplan dott com dott pl :
- AutoIndent now worked when SmartTab Off;
- method GetTextLen for TMemo compatibility;
- Indent, Unindent commands;
- WM_COPY, WM_CUT, WM_PASTE message handling;
1.17.1:
- painting and scrolling changed:
bug with scrolling JvEditor if other StayOnTop
window overlapes JvEditor window FIXED;
- right click now not unselect text;
- changing RightMargin, RightMarginVisible and RightMarginColor
Invalidates window;
1.17.2:
another good stuf by Rafal Smotrzyk - rsmotrzyk att mikroplan dott com dott pl :
- fixed bug with backspace pressed when text selected;
- fixed bug with disabling Backspace Unindents when SmartTab off;
- fixed bug in GetTabStop method when SmartTab off;
- new commands: DeleteWord, DeleteLine, ToUpperCase, ToLowerCase;
1.17.3:
- TabStops;
1.17.4:
- undo for selection modifiers;
- UndoBuffer.BeginCompound, UndoBuffer.EndCompound for
compound commands, that must interpreted by UndoBuffer as one operation;
now not implemented, but must be used for feature compatibility;
- fixed bug with undoable Delete on end of line;
- new command ChangeCase;
1.17.5:
- UndoBuffer.BeginCompound, UndoBuffer.EndCompound fully implemented;
- UndoBuffer property in TJvCustomEditor;
1.17.6:
- fixed bug with compound undo;
- fixed bug with scrolling (from v 1.171);
1.17.7:
- UndoBuffer.BeginCompound and UndoBuffer.EndCompound moved to TJvCustomEditor;
- Macro support: BeginRecord, EndRecord, PlayMacro; not complete;
- additional support for compound operations: prevent updating and other;
1.17.8:
- bug fixed with compound commands in macro;
1.21.2:
- fixed bug with pressing End-key if CursorBeoyondEOF enabled
(greetings to Martijn Laan)
1.21.4:
- fixed bug in commands ecNextWord and ecPrevWord
(greetings to Ildar Noureeslamov)
1.21.6:
- in OnGetLineAttr now it is possible to change attributes of right
trailing blanks.
1.23:
- fixed bug in completion (range check error)
(greetings to Willo vd Merwe)
1.51.1 (JVCL Library 1.51 with Update 1):
- methods Lines.Add and Lines.Insert now properly updates editor window.
1.51.2 (JVCL Library 1.51 with Update 2):
- "Courier New" is default font now.
1.51.3 (JVCL Library 1.51 with Update 2)::
- fixed bug: double click on empty editor raise exception;
- fixed bug: backspace at EOF raise exception;
- fixed bug: gutter not repainted on vertical scrolling;
1.53:
- fixed bug: GetWordOnCaret returns invalid Word if caret stays on start of Word;
1.54.1:
- new: undo now works in overwrite mode;
1.54.2:
- fixed bug: double click not selects Word on first line;
- selection work better after consecutive moving to begin_of_line and
end_of_line, and in other cases;
- 4 block format supported now: NonInclusive (default), Inclusive,
Line (initial support), Column;
- painting was improved;
1.60:
- DblClick work better (thanks to Constantin M. Lushnikov);
- fixed bug: caret moved when mouse moves over JvEditor after
click on any other windows placed over JvEditor, which loses focus
after this click; (anyone understand me ? :)
- bug fixed: accelerator key do not work on window,
where JvEditor is placed (thanks to Luis David Cardenas Bucio);
1.61:
- support for mouse with wheel (thanks to Michael Serpik);
- ANY font can be used (thanks to Rients Politiek);
- bug fixed: completion ranges error on first line
(thanks to Walter Campelo);
- new functions: CanCopy, CanPaste, CanCut in TJvCustomEditor
and function CanUndo in TJvUndoBuffer (TJvCustomEditor.UndoBuffer);
2.00:
- removed dependencies from JvUtils.pas unit;
- bugfixed: TJvDeleteUndo and TJvBackspaceUndo do not work always properly
(thanks to Pavel Chromy);
- bugfixed: workaround bug with some fonts in Win9x
(thanks to Dmitry Rubinstain);
2.10.2: (changes by Andreas Hausladen)
- speed optimation (font cache, many Lines.Text references were removed)
- fixed bug: TJvBackspaceUndo, TJvInsertUndo, TJvDeleteUndo still do not work
always properly
- fixed bug: caret movement and selections set Modified to TRUE
- Undo restores Modified-field
- added [Ctrl][Backspace] (ecBackspaceWord) and [Shift][Backspace] command
- added [Shift]+MouseDown selections
- added [Alt]+MouseDown selections (column)
- new event TKeyboard.OnCommand2
- fixed bug: CodeCompletition catches VK_HOME, VK_END
- fixed bug: on empty editor pressing [Ctrl][End] raises "Index out of
bounds (-1)"
- fixed bug: caret moves into gutter on horz. scrolling
- added OnGutterClick and OnGutterDblClick events
- renamed all "Identifer" to "Identifier"
2.10.3 (changes by Andreas Hausladen)
- added new mouse wheel functionality: [Ctrl]+Wheel and [Shift]+Wheel
- faster TJvReplaceUndo and ReplaceWord/ReplaceWord2
- bug fixed: first complete selected line stops drawing selection on cell 80
- added SelectAll, ClearSelection
- full support for SelBlockFormat = bfColumn and bfLine
- improved TJvCompletion.ReplaceWord
- undo system overworked
- fixed bug: [Shift][Tab] is the same as [Tab]
- reduced TextAllChanged() calls
- added: Un-/IndentColumns, Un-/IndentLines, Un-/IndentSelLines
- new Undo: TJvUnindentColumnUndo, TJvIndentColumnUndo
- moved: FSelBegX, FSelBegY, ... FSelected into TJvSelectionRec
- added GetAutoIndentStop and removed AutoIndent code from GetTabStop
- fixed bug: CanPaste raises Exception SCannotOpenClipboard (new: catches exception)
- fixed bug: in readonly mode [Return] does nothing
- added BlockOverwrite property
- added PeristentBlocks
2.10.4 (changed by peter3, Andreas Hausladen)
- fixed bug where pressing Enter/Return while the completion list is open inserts a line break (andreas)
- fixed GetNextWordPosEx (andreas)
- added default popupmenu if none assigned (JvFixedEditPopup)
- added handling of WM_CLEAR, WM_GETTEXTLENGTH, EM_SETREADONLY, EM_SETSEL, EM_GETSEL and EM_CANUNDO
3.0 (changes by Andreas Hausladen)
- speed optimation: GetTextLen is now faster
- fixed: GetSelStart returned caret position
- fixed: ecBackspace with BackSpaceUnindents=True may destroy the line
- fixed a bug in InsertText
- optimized ExpandTabs
2004-01-25: file split into JvEditor and JvEditorCommon
Further history: see CVS
}
unit rm_JvEditorCommon;
{$I rm_jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
rm_JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Windows, Messages, ShellAPI, SysUtils, Classes, Contnrs, Graphics, Controls,
Forms, StdCtrls, ExtCtrls, Menus,
rm_JvFixedEditPopup, rm_JvUnicodeCanvas, {rm_JvComponent,} rm_JvExControls;
const
Max_X = 1024; {max symbols per row}
Max_X_Scroll = Max_X;
{max symbols per row for scrollbar}
GutterRightMargin = 2;
{$IFDEF VCL}
WM_EDITCOMMAND = WM_USER + $101;
WM_COMPOUND = WM_USER + $102;
{$ENDIF VCL}
{$IFDEF VisualCLX}
WM_EDITCOMMAND = CM_BASE + $101;
WM_COMPOUND = CM_BASE + $102;
{$ENDIF VisualCLX}
CM_RESETCAPTURECONTROL = CM_BASE + $103;
type
EJvEditorError = class(Exception);
TJvCustomEditorBase = class; // base class for both Ansi and Unicode editor
TJvCompletionBase = class;
TCellRect = record
Width: Integer;
Height: Integer;
end;
TLineAttr = packed record { CompareMem() requires "packed" }
FC: TColor;
BC: TColor;
Style: TFontStyles;
Border: TColor;
end;
TLineAttrs = array {[0..Max_X]} of TLineAttr;
TDynIntArray = array of Integer;
TDynBoolArray = array of Boolean;
TModifiedAction =
(maAll, maInsert, maDelete, maInsertColumn, maDeleteColumn, maReplace);
TBookmark = record
X: Integer;
Y: Integer;
Valid: Boolean;
end;
TBookmarkNum = 0..9;
TBookmarks = array [TBookmarkNum] of TBookmark;
{ Borland Block Type:
00 - inclusive;
01 - line;
02 - column;
03 - noninclusive; }
TJvSelBlockFormat = (bfInclusive, bfLine, bfColumn, bfNonInclusive);
TOnPaintGutter = procedure(Sender: TObject; Canvas: TCanvas) of object;
TOnGutterClick = procedure(Sender: TObject; Line: Integer) of object;
TJvLineChangeEvent = procedure(Sender: TObject; Line: Integer) of object;
TEditCommand = Word;
TMacro = AnsiString; { used as buffer (array of char) }
TJvEditKey = class(TObject)
public
Key1: Word;
Key2: Word;
Shift1: TShiftState;
Shift2: TShiftState;
Command: TEditCommand;
constructor Create(const ACommand: TEditCommand; const AKey1: Word;
const AShift1: TShiftState);
constructor Create2(const ACommand: TEditCommand; const AKey1: Word;
const AShift1: TShiftState; const AKey2: Word;
const AShift2: TShiftState);
end;
TCommand2Event = procedure(Sender: TObject; const Key1: Word; const Shift1: TShiftState;
const Key2: Word; const Shift2: TShiftState; var Command: TEditCommand) of object;
TJvKeyboard = class(TPersistent)
private
FList: TObjectList;
FOnCommand2: TCommand2Event;
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure Add(const ACommand: TEditCommand; const AKey1: Word;
const AShift1: TShiftState);
procedure Add2(const ACommand: TEditCommand; const AKey1: Word;
const AShift1: TShiftState; const AKey2: Word;
const AShift2: TShiftState);
procedure Add2Ctrl(const ACommand: TEditCommand; const AKey1: Word;
const AShift1: TShiftState; const AKey2: Word);
procedure Remove(const AKey1: Word; const AShift1: TShiftState);
procedure Remove2(const AKey1: Word; const AShift1: TShiftState;
const AKey2: Word; const AShift2: TShiftState);
procedure RemoveCtrl(const ACommand: TEditCommand);
procedure Clear;
function Command(const AKey: Word; const AShift: TShiftState): TEditCommand;
function Command2(const AKey1: Word; const AShift1: TShiftState;
const AKey2: Word; const AShift2: TShiftState): TEditCommand;
procedure SetDefLayout;
property OnCommand2: TCommand2Event read FOnCommand2 write FOnCommand2;
end;
{ TJvSelectionRec contains all text selection information }
PJvSelectionRec = ^TJvSelectionRec;
TJvSelectionRec = record
IsSelected: Boolean; // maybe a function that checks BegX/Y EndX/Y would be better
Selecting: Boolean;
SelBlockFormat: TJvSelBlockFormat;
SelBegX: Integer;
SelBegY: Integer;
SelEndX: Integer;
SelEndY: Integer;
SelStartX: Integer;
SelStartY: Integer;
SelLineOrgBegX, SelLineOrgEndX: Integer;
end;
TJvLineSelectStyle =
(lssUnselected, lssBreakpoint, lssDebugPoint, lssErrorPoint);
TAdjustPersistentBlockMode =
(amInsert, amDelete, amDeleteLine, amLineConcat, amLineBreak);
TCompletionList = (cmIdentifiers, cmTemplates);
TOnCompletion = procedure(Sender: TObject; var Cancel: Boolean) of object;
TJvUndo = class;
IJvUndoCompound = interface
['{D326A114-0A57-4654-A7F0-16D3BBD0A2CE}']
end;
IJvBackspaceUndo = interface
['{88BE2C69-2C5C-48C0-AC46-888146DD70AD}']
end;
IJvBackspaceUnindentUndo = interface
['{A78B524C-684E-43BD-B8A4-A540CD0B022D}']
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -