Here is the version for Delphi 5, 6, 7 and 2007.
Code: Select all
uses RVUni, RVTypes;
type
TRVCapitalizeState = (rvcsWord, rvcsWhitespace);
function IsEndOfSentencePunctuation(Ch: TRVUnicodeChar): Boolean;
begin
case Ord(Ch) of
$00021, $0002E, $0003F, $00589, $0061F, $006D4,
$00700..$00702, $007F9, $00964, $00965, $0104A, $0104B,
$01362, $01367, $01368, $0166E, $01803, $01809,
$01944, $01945, $01AA8..$01AAB, $01B5A, $01B5B,
$01B5E, $01B5F, $01C3B, $01C3C, $01C7E, $01C7F,
$0203C, $0203D, $02047..$02049, $02E2E, $03002,
$0A4FF, $0A60E, $0A60F, $0A6F3, $0A6F7,
$0A876, $0A877, $0A8CE, $0A8CF, $0A92F,
$0A9C8, $0A9C9, $0AA5D..$0AA5F, $0AAF0, $0AAF1,
$0ABEB, $0FE52, $0FE56, $0FE57, $0FF01, $0FF0E,
$0FF1F, $0FF61{, $11047, $11048, $110BE, $110BF,
$110C0, $110C1, $11141..$11143, $111C5, $111C6}:
Result := True;
else
Result := False;
end;
end;
function RvIsLetterOrDigit(Ch: TRVUnicodeChar): Boolean;
begin
Result := IsCharAlphaNumericW(Ch);
end;
function RvIsWhiteSpace(Ch: TRVUnicodeChar): Boolean;
begin
case Ord(Ch) of
$0020, $0009..$000D, $00A0, $0085, $2028, $2029,
$1680, $2000..$200A, $202F, $205F, $3000:
Result := True
else
Result := False;
end;
end;
function RvIsLower(Ch: TRVUnicodeChar): Boolean; overload;
begin
Result := IsCharLowerW(Ch)
end;
function RvToUpper(Ch: TRVUnicodeChar): TRVUnicodeChar;
var
S: TRVUnicodeString;
begin
S := Ch;
CharUpperW(PRVUnicodeChar(S));
Result := S[1];
end;
function ShouldCapitalizeWord(rve: TCustomRichViewEdit;
CapitalizeFirstCellChar, CapitalizeLists: Boolean): Boolean;
var
ItemNo, Offs: Integer;
S: TRVUnicodeString;
State: TRVCapitalizeState;
WhiteSpaceLength: Integer;
function FinishItem: Boolean; // result: continue?
begin
Result := not rve.IsFromNewLine(ItemNo);
end;
function StartItem(ChangeOffs: Boolean): Boolean; // result: continue?
begin
Result := ItemNo >= 0;
if not Result then
exit;
if rve.GetItemStyle(ItemNo) < 0 then
begin
Result := (rve.GetItemStyle(ItemNo) = rvsTab) and (State = rvcsWhitespace);
if Result then
inc(WhiteSpaceLength);
end
else
begin
Result := not rve.Style.TextStyles[rve.GetItemStyle(ItemNo)].IsSymbolCharset;
if Result then
begin
S := rve.GetItemTextW(ItemNo);
if ChangeOffs then
Offs := Length(S);
end;
end;
end;
begin
Result := False;
rve := rve.TopLevelEditor;
if rve.SelectionExists then
exit;
ItemNo := rve.CurItemNo;
Offs := rve.OffsetInCurItem;
if (Offs <= rve.GetOffsBeforeItem(ItemNo)) then
if rve.IsFromNewLine(ItemNo) then
begin
Result := True;
if not CapitalizeFirstCellChar and (rve.RVData.GetSourceRVData is TRVTableCellData) and (ItemNo = 0) then
Result := False;
exit;
end
else
begin
dec(ItemNo);
if ItemNo < 0 then
exit
else
Offs := rve.GetOffsAfterItem(ItemNo);
end;
dec(Offs);
State := rvcsWhitespace;
WhiteSpaceLength := 0;
if not StartItem(False) then
begin
if CapitalizeLists and (ItemNo >=0) and
(rve.GetItemStyle(ItemNo) = rvsListMarker) then
Result := True;
exit;
end;
while True do
begin
if (rve.GetItemStyle(ItemNo) >= 0) and (Offs > 0) then
begin
case State of
rvcsWhitespace:
if RvIsWhiteSpace(S[Offs]) then
inc(WhiteSpaceLength)
else if IsEndOfSentencePunctuation(S[Offs]) then
begin
if WhiteSpaceLength = 0 then
exit;
State := rvcsWord;
end
else
exit;
rvcsWord:
begin
Result := RvIsLetterOrDigit(S[Offs]);
exit;
end;
end;
dec(Offs);
end
else
begin
if not FinishItem then
exit;
dec(ItemNo);
if not StartItem(True) then
exit;
end;
end;
end;
procedure InsertReplacedChar(const Ch1, Ch2: TRVUnicodeChar; rve: TCustomRichViewEdit);
var
ItemNo, Offs: Integer;
begin
rve := rve.TopLevelEditor;
ItemNo := rve.CurItemNo;
Offs := rve.OffsetInCurItem;
rve.InsertTextW(Ch1);
rve.BeginUndoGroup(rvutInsert);
rve.SetUndoGroupMode(True);
rve.SetSelectionBounds(ItemNo, Offs, rve.CurItemNo, rve.OffsetInCurItem);
rve.DeleteSelection;
rve.InsertTextW(Ch2);
rve.SetUndoGroupMode(False);
end;
function CapitalizeWord(rve: TCustomRichViewEdit; var Key: Char;
CodePage: Cardinal; CapitalizeFirstCellChar, CapitalizeLists: Boolean): Boolean;
var
S: TRVUnicodeString;
begin
Result := False;
S := RVU_AnsiToUnicode(CodePage, Key);
if Length(S) <> 1 then
exit;
if RvIsLower(S[1]) and ShouldCapitalizeWord(rve, True, True) then
begin
InsertReplacedChar(S[1], RVToUpper(S[1]), rve);
Key := #0;
Result := True;
end;
end;