You've already forked lazarus-ccr
jvcllaz: Add TJvSpellChecker incl demo and sample dictionaries
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6237 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<UseDefaultCompilerOptions Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="JvSpellCheckerDemo"/>
|
||||
<Scaled Value="True"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<XPManifest>
|
||||
<DpiAware Value="True"/>
|
||||
</XPManifest>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
<Modes Count="0"/>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="JvCmpR"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item2>
|
||||
</RequiredPackages>
|
||||
<Units Count="3">
|
||||
<Unit0>
|
||||
<Filename Value="JvSpellCheckerDemo.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="JvSpellCheckerForm.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<HasResources Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="MainFrm.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="frmMain"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit2>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="..\..\bin\JvSpellCheckerDemo"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
@@ -0,0 +1,16 @@
|
||||
program JvSpellCheckerDemo;
|
||||
|
||||
uses
|
||||
Forms, Interfaces,
|
||||
MainFrm in 'MainFrm.pas' {frmMain},
|
||||
JvSpellCheckerForm in 'JvSpellCheckerForm.pas' {frmSpellChecker};
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Scaled := True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TfrmMain, frmMain);
|
||||
Application.CreateForm(TfrmSpellChecker, frmSpellChecker);
|
||||
Application.Run;
|
||||
end.
|
@@ -0,0 +1,193 @@
|
||||
object frmSpellChecker: TfrmSpellChecker
|
||||
Left = 338
|
||||
Top = 177
|
||||
BorderStyle = bsDialog
|
||||
Caption = 'Spell check document'
|
||||
ClientHeight = 334
|
||||
ClientWidth = 384
|
||||
Color = clBtnFace
|
||||
DefaultMonitor = dmDesktop
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'MS Shell Dlg 2'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = False
|
||||
Position = poMainFormCenter
|
||||
Scaled = False
|
||||
OnCreate = FormCreate
|
||||
OnShow = FormShow
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object Label1: TLabel
|
||||
Left = 16
|
||||
Top = 16
|
||||
Width = 72
|
||||
Height = 13
|
||||
Caption = 'Not in wordlist:'
|
||||
end
|
||||
object Label2: TLabel
|
||||
Left = 16
|
||||
Top = 102
|
||||
Width = 62
|
||||
Height = 13
|
||||
Caption = 'Suggestions:'
|
||||
end
|
||||
object lblNoSuggestions: TLabel
|
||||
Left = 179
|
||||
Top = 101
|
||||
Width = 93
|
||||
Height = 13
|
||||
Caption = '(nothing to display)'
|
||||
Visible = False
|
||||
end
|
||||
object Label3: TLabel
|
||||
Left = 16
|
||||
Top = 56
|
||||
Width = 65
|
||||
Height = 13
|
||||
Caption = 'Replace with:'
|
||||
end
|
||||
object edNewWord: TEdit
|
||||
Left = 16
|
||||
Top = 72
|
||||
Width = 254
|
||||
Height = 21
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
TabOrder = 1
|
||||
end
|
||||
object lbSuggestions: TListBox
|
||||
Left = 16
|
||||
Top = 120
|
||||
Width = 254
|
||||
Height = 82
|
||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||
ItemHeight = 13
|
||||
TabOrder = 2
|
||||
OnClick = lbSuggestionsClick
|
||||
end
|
||||
object btnIgnore: TButton
|
||||
Left = 294
|
||||
Top = 32
|
||||
Width = 75
|
||||
Height = 25
|
||||
Action = acIgnore
|
||||
Anchors = [akTop, akRight]
|
||||
TabOrder = 3
|
||||
end
|
||||
object btnIgnoreAll: TButton
|
||||
Left = 294
|
||||
Top = 61
|
||||
Width = 75
|
||||
Height = 25
|
||||
Action = acIgnoreAll
|
||||
Anchors = [akTop, akRight]
|
||||
TabOrder = 4
|
||||
end
|
||||
object btnChange: TButton
|
||||
Left = 294
|
||||
Top = 120
|
||||
Width = 75
|
||||
Height = 25
|
||||
Action = acChange
|
||||
Anchors = [akTop, akRight]
|
||||
TabOrder = 5
|
||||
end
|
||||
object btnClose: TButton
|
||||
Left = 294
|
||||
Top = 286
|
||||
Width = 75
|
||||
Height = 25
|
||||
Action = acClose
|
||||
Anchors = [akRight, akBottom]
|
||||
Cancel = True
|
||||
TabOrder = 8
|
||||
end
|
||||
object btnAdd: TButton
|
||||
Left = 294
|
||||
Top = 149
|
||||
Width = 75
|
||||
Height = 25
|
||||
Action = acAdd
|
||||
Anchors = [akTop, akRight]
|
||||
TabOrder = 6
|
||||
end
|
||||
object GroupBox1: TGroupBox
|
||||
Left = 16
|
||||
Top = 209
|
||||
Width = 257
|
||||
Height = 105
|
||||
Anchors = [akLeft, akRight, akBottom]
|
||||
Caption = ' Ignore: '
|
||||
TabOrder = 7
|
||||
object chkUpperCase: TCheckBox
|
||||
Left = 24
|
||||
Top = 23
|
||||
Width = 207
|
||||
Height = 17
|
||||
Caption = '&UPPERCASE words'
|
||||
TabOrder = 0
|
||||
end
|
||||
object chkNumber: TCheckBox
|
||||
Left = 24
|
||||
Top = 39
|
||||
Width = 207
|
||||
Height = 17
|
||||
Caption = 'Words with &numbers'
|
||||
TabOrder = 1
|
||||
end
|
||||
object chkURL: TCheckBox
|
||||
Left = 24
|
||||
Top = 55
|
||||
Width = 207
|
||||
Height = 17
|
||||
Caption = 'Internet and file &paths'
|
||||
TabOrder = 2
|
||||
end
|
||||
object chkHTML: TCheckBox
|
||||
Left = 24
|
||||
Top = 71
|
||||
Width = 207
|
||||
Height = 17
|
||||
Caption = 'HT&ML code'
|
||||
TabOrder = 3
|
||||
end
|
||||
end
|
||||
object edBadWord: TEdit
|
||||
Left = 16
|
||||
Top = 32
|
||||
Width = 254
|
||||
Height = 21
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Color = clBtnFace
|
||||
ReadOnly = True
|
||||
TabOrder = 0
|
||||
end
|
||||
object alSpell: TActionList
|
||||
OnUpdate = alSpellUpdate
|
||||
Left = 296
|
||||
Top = 224
|
||||
object acIgnore: TAction
|
||||
Caption = '&Ignore'
|
||||
OnExecute = acIgnoreExecute
|
||||
end
|
||||
object acIgnoreAll: TAction
|
||||
Caption = 'Ignore &All'
|
||||
OnExecute = acIgnoreAllExecute
|
||||
end
|
||||
object acChange: TAction
|
||||
Caption = 'C&hange'
|
||||
OnExecute = acChangeExecute
|
||||
end
|
||||
object acAdd: TAction
|
||||
Caption = 'A&dd'
|
||||
OnExecute = acAddExecute
|
||||
end
|
||||
object acClose: TAction
|
||||
Caption = '&Close'
|
||||
ShortCut = 27
|
||||
OnExecute = acCloseExecute
|
||||
end
|
||||
end
|
||||
end
|
@@ -0,0 +1,329 @@
|
||||
{******************************************************************
|
||||
|
||||
JEDI-VCL Demo
|
||||
|
||||
Copyright (C) 2002 Project JEDI
|
||||
|
||||
Original author:
|
||||
|
||||
Contributor(s):
|
||||
|
||||
You may retrieve the latest version of this file at the JEDI-JVCL
|
||||
home page, located at http://jvcl.delphi-jedi.org
|
||||
|
||||
The contents of this file are used with permission, 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_1Final.html
|
||||
|
||||
Software distributed under the License is distributed on an
|
||||
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
******************************************************************}
|
||||
|
||||
unit JvSpellCheckerForm;
|
||||
|
||||
interface
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
//{$I jvcl.inc}
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls, JvSpellChecker, ActnList;
|
||||
|
||||
type
|
||||
{ This is an example form with code that shows how to implement a spell check form
|
||||
that can be displayed to the end user. The TJvSpellChecker is created dynamically
|
||||
so you don't need to install it to run the demo: just make sure the JvSpellChecker and
|
||||
JvSpellIntf units are somewhere in your path.
|
||||
|
||||
The main tasks of this form is to:
|
||||
* Scan for the next misspelled word (GetNextWord)
|
||||
* Display the misspelled word along with suggested replacements
|
||||
* Call an event handler to highlight the text in the original control
|
||||
* Call an event handler when the user wants to replace the word
|
||||
* Add a word to the user dictionary (btnAdd)
|
||||
* Add a word to the ignore list (btnIgnoreAll)
|
||||
|
||||
This form doesn't implement everything needed for a professional looking form (i.e only
|
||||
enable buttons as needed) but it can serve as a base for a more complete implementation.
|
||||
}
|
||||
|
||||
TJvReplaceTextEvent = procedure(Sender: TObject; StartIndex, ALength: integer; const NewText: string) of object;
|
||||
TJvSelectTextEvent = procedure(Sender: TObject; StartIndex, ALength: integer) of object;
|
||||
TfrmSpellChecker = class(TForm)
|
||||
Label1: TLabel;
|
||||
edNewWord: TEdit;
|
||||
Label2: TLabel;
|
||||
lbSuggestions: TListBox;
|
||||
btnIgnore: TButton;
|
||||
btnIgnoreAll: TButton;
|
||||
btnChange: TButton;
|
||||
btnClose: TButton;
|
||||
btnAdd: TButton;
|
||||
GroupBox1: TGroupBox;
|
||||
chkUpperCase: TCheckBox;
|
||||
chkNumber: TCheckBox;
|
||||
chkURL: TCheckBox;
|
||||
chkHTML: TCheckBox;
|
||||
lblNoSuggestions: TLabel;
|
||||
Label3: TLabel;
|
||||
edBadWord: TEdit;
|
||||
alSpell: TActionList;
|
||||
acIgnore: TAction;
|
||||
acIgnoreAll: TAction;
|
||||
acChange: TAction;
|
||||
acAdd: TAction;
|
||||
acClose: TAction;
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure acIgnoreExecute(Sender: TObject);
|
||||
procedure acIgnoreAllExecute(Sender: TObject);
|
||||
procedure acChangeExecute(Sender: TObject);
|
||||
procedure acAddExecute(Sender: TObject);
|
||||
procedure acCloseExecute(Sender: TObject);
|
||||
procedure alSpellUpdate(AAction: TBasicAction; var Handled: Boolean);
|
||||
procedure lbSuggestionsClick(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
FStartIndex, FLength: integer;
|
||||
ASpellChecker: TJvSpellChecker;
|
||||
FOnReplaceText: TJvReplaceTextEvent;
|
||||
FOnSelectText: TJvSelectTextEvent;
|
||||
procedure CloseAndReport(ReportSuccess: boolean);
|
||||
function GetNextWord: boolean;
|
||||
procedure DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
|
||||
procedure DoSelectText(Sender: TObject; StartIndex, ALength: integer);
|
||||
function GetSpellText: string;
|
||||
procedure SetSpellText(const Value: string);
|
||||
procedure DoCanIgnore(Sender: TObject; const Value: string; var CanIgnore: boolean);
|
||||
procedure CheckSuggestions;
|
||||
public
|
||||
{ Public declarations }
|
||||
property SpellText: string read GetSpellText write SetSpellText;
|
||||
property OnReplaceText: TJvReplaceTextEvent read FOnReplaceText write FOnReplaceText;
|
||||
property OnSelectText: TJvSelectTextEvent read FOnSelectText write FOnSelectText;
|
||||
end;
|
||||
|
||||
var
|
||||
frmSpellChecker: TfrmSpellChecker;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
procedure TfrmSpellChecker.FormCreate(Sender: TObject);
|
||||
var S:string;
|
||||
begin
|
||||
ASpellChecker := TJvSpellChecker.Create(self);
|
||||
// Dictionaries are plain text files, one word per row, preferably sorted.
|
||||
// If you don't load a dictionary, all words are misspelled and you won't get any suggestions
|
||||
S := ExtractFilePath(Application.ExeName) + 'english.dic';
|
||||
if not FileExists(S) then
|
||||
S := '..\Dict\english.dic';
|
||||
if FileExists(S) then
|
||||
ASpellChecker.Dictionary := S
|
||||
else
|
||||
ShowMessage('Dictionary file not found: make sure you have an english.dic file in the exe folder!');
|
||||
// ASpellChecker.UserDictionary.LoadFromFile(Application.ExeName + 'custom.dic'); // you need to create this
|
||||
// set up a custom ignore filter:
|
||||
ASpellChecker.OnCanIgnore := @DoCanIgnore;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
|
||||
begin
|
||||
// this events calls back to the main form where the content of the rich edit is updated
|
||||
if Assigned(FOnReplaceText) then
|
||||
FOnReplaceText(self, StartIndex, ALength, NewText);
|
||||
end;
|
||||
|
||||
function TfrmSpellChecker.GetSpellText: string;
|
||||
begin
|
||||
Result := ASpellChecker.Text;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.SetSpellText(const Value: string);
|
||||
begin
|
||||
ASpellChecker.Text := Value;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.CheckSuggestions;
|
||||
begin
|
||||
if lbSuggestions.Items.Count = 0 then
|
||||
begin
|
||||
lblNoSuggestions.Parent := lbSuggestions;
|
||||
lblNoSuggestions.Top := 4;
|
||||
lblNoSuggestions.Left := (lbSuggestions.ClientWidth - lblNoSuggestions.Width) div 2;
|
||||
lblNoSuggestions.Visible := true;
|
||||
end
|
||||
else
|
||||
lblNoSuggestions.Visible := false;
|
||||
end;
|
||||
|
||||
function TfrmSpellChecker.GetNextWord: boolean;
|
||||
begin
|
||||
// scan for the next misspelled word. Returns false if no more misspelled words are found
|
||||
Result := false;
|
||||
while ASpellChecker.SpellChecker.Next(FStartIndex, FLength) do
|
||||
begin
|
||||
edBadWord.Text := '';
|
||||
edNewWord.Text := '';
|
||||
Result := FLength > 0;
|
||||
if Result then
|
||||
begin
|
||||
edBadWord.Text := Copy(ASpellChecker.Text, FStartIndex, FLength);
|
||||
lbSuggestions.Items := ASpellChecker.SpellChecker.Suggestions;
|
||||
if lbSuggestions.Items.Count > 0 then
|
||||
begin
|
||||
edNewWord.Text := lbSuggestions.Items[0];
|
||||
lbSuggestions.ItemIndex := 0;
|
||||
end
|
||||
else
|
||||
edNewWord.Text := edBadWord.Text;
|
||||
edNewWord.SetFocus;
|
||||
end;
|
||||
CheckSuggestions;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.FormShow(Sender: TObject);
|
||||
begin
|
||||
if GetNextWord then
|
||||
DoSelectText(self, FStartIndex, FLength)
|
||||
else
|
||||
CloseAndReport(false);
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.DoSelectText(Sender: TObject; StartIndex,
|
||||
ALength: integer);
|
||||
begin
|
||||
// this events calls back to the main form where the selection in the rich edit is updated
|
||||
if Assigned(FOnSelectText) then FOnSelectText(self, StartIndex, ALength);
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.DoCanIgnore(Sender: TObject; const Value: string;
|
||||
var CanIgnore: boolean);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
// custom event to manage some of the options in the dialog
|
||||
|
||||
// always ignore words shorter than four letter
|
||||
if Length(Value) < 4 then
|
||||
begin
|
||||
CanIgnore := true;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// make some additional checks on the current word to determine if we need to spellcheck it
|
||||
if chkUpperCase.Checked and (AnsiUpperCase(Value) = Value) then // ignore all UPPERCASE words
|
||||
begin
|
||||
CanIgnore := true;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if chkNumber.Checked then // ignore words that contains numbers
|
||||
for i := 1 to Length(Value) do
|
||||
if {$IFDEF RTL200_UP}CharInSet(Value[i], ['0'..'9', '#', '%']){$ELSE}(Value[i] in ['0'..'9', '#', '%']){$ENDIF RTL200_UP} then
|
||||
begin
|
||||
CanIgnore := true;
|
||||
Exit;
|
||||
end;
|
||||
if chkURL.Checked then // ignore URL's and file paths (this code is in no way 100% effective...)
|
||||
for i := 1 to Length(Value) do
|
||||
if {$IFDEF RTL200_UP}CharInSet(Value[i], [':', '/', '\']){$ELSE}(Value[i] in [':', '/', '\']){$ENDIF RTL200_UP} then
|
||||
begin
|
||||
CanIgnore := true;
|
||||
Exit;
|
||||
end;
|
||||
if chkHTML.Checked then // ignore HTML tags (this code is in no way 100% effective...)
|
||||
CanIgnore := (Length(Value) < 2) or ((Value[1] = '<') or (Value[Length(Value)] = '>')) or
|
||||
((Value[1] = '&') and (Value[Length(Value)] = ';'));
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.CloseAndReport(ReportSuccess: boolean);
|
||||
var
|
||||
S: string;
|
||||
begin
|
||||
if ReportSuccess then
|
||||
S := 'Spell check completed!'
|
||||
else
|
||||
S := 'There is nothing to spell check';
|
||||
ShowMessage(S);
|
||||
// delay since we might have been called from the OnShow event (can't close in OnShow)
|
||||
PostMessage(Handle, WM_CLOSE, 0, 0);
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.acIgnoreExecute(Sender: TObject);
|
||||
begin
|
||||
// ignore = skip to next word but don't remember the word we just saw
|
||||
if GetNextWord then
|
||||
DoSelectText(self, FStartIndex, FLength)
|
||||
else
|
||||
CloseAndReport(true)
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.acIgnoreAllExecute(Sender: TObject);
|
||||
begin
|
||||
// ignore all = add to ignore list so it will be skipped in the future as well
|
||||
ASpellChecker.SpellChecker.Ignores.Add(AnsiLowerCase(edBadWord.Text));
|
||||
if GetNextWord then
|
||||
DoSelectText(self, FStartIndex, FLength)
|
||||
else
|
||||
CloseAndReport(true);
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.acChangeExecute(Sender: TObject);
|
||||
begin
|
||||
// replace the current selection with the word in the edit
|
||||
DoReplaceText(self, FStartIndex, FLength, edNewWord.Text);
|
||||
if GetNextWord then
|
||||
DoSelectText(self, FStartIndex, FLength)
|
||||
else
|
||||
CloseAndReport(true)
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.acAddExecute(Sender: TObject);
|
||||
begin
|
||||
// Add the misspelled word to the user dictionary. To persist, you must add code to call
|
||||
// UserDictionary.SaveToFile() at close down as well as UserDictionary.LoadFromFile() at start up.
|
||||
ASpellChecker.SpellChecker.UserDictionary.Add(edBadWord.Text);
|
||||
edNewWord.Text := edBadWord.Text;
|
||||
// change the word as well
|
||||
if not acChange.Execute then
|
||||
begin
|
||||
// move on
|
||||
if GetNextWord then
|
||||
DoSelectText(self, FStartIndex, FLength)
|
||||
else
|
||||
CloseAndReport(true);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.acCloseExecute(Sender: TObject);
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.alSpellUpdate(AAction: TBasicAction;
|
||||
var Handled: Boolean);
|
||||
begin
|
||||
acIgnore.Enabled := edBadWord.Text <> '';
|
||||
acIgnoreAll.Enabled := acIgnore.Enabled;
|
||||
acChange.Enabled := not AnsiSameText(edBadWord.Text, edNewWord.Text);
|
||||
acAdd.Enabled := (edBadWord.Text <> '') and (ASpellChecker.UserDictionary.IndexOf(edBadWord.Text) < 0);
|
||||
end;
|
||||
|
||||
procedure TfrmSpellChecker.lbSuggestionsClick(Sender: TObject);
|
||||
begin
|
||||
with lbSuggestions do
|
||||
if ItemIndex > -1 then
|
||||
edNewWord.Text := Items[ItemIndex];
|
||||
end;
|
||||
|
||||
end.
|
93
components/jvcllaz/examples/JvSpellChecker/MainFrm.lfm
Normal file
93
components/jvcllaz/examples/JvSpellChecker/MainFrm.lfm
Normal file
@@ -0,0 +1,93 @@
|
||||
object frmMain: TfrmMain
|
||||
Left = 353
|
||||
Height = 398
|
||||
Top = 156
|
||||
Width = 535
|
||||
Caption = 'JvSpellChecker Demo'
|
||||
ClientHeight = 378
|
||||
ClientWidth = 535
|
||||
Color = clBtnFace
|
||||
Constraints.MinHeight = 200
|
||||
Constraints.MinWidth = 320
|
||||
DefaultMonitor = dmDesktop
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'MS Shell Dlg 2'
|
||||
Menu = mmMain
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '1.9.0.0'
|
||||
Scaled = False
|
||||
object reText: TMemo
|
||||
Left = 0
|
||||
Height = 355
|
||||
Top = 0
|
||||
Width = 535
|
||||
Align = alClient
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'MS Shell Dlg 2'
|
||||
HideSelection = False
|
||||
ParentFont = False
|
||||
ScrollBars = ssBoth
|
||||
TabOrder = 0
|
||||
WantTabs = True
|
||||
WordWrap = False
|
||||
end
|
||||
object StatusBar1: TStatusBar
|
||||
Left = 0
|
||||
Height = 23
|
||||
Top = 355
|
||||
Width = 535
|
||||
Panels = <
|
||||
item
|
||||
Width = 50
|
||||
end>
|
||||
SimplePanel = False
|
||||
end
|
||||
object mmMain: TMainMenu
|
||||
left = 120
|
||||
top = 64
|
||||
object File1: TMenuItem
|
||||
Caption = 'File'
|
||||
object Open1: TMenuItem
|
||||
Caption = 'Open...'
|
||||
ShortCut = 16463
|
||||
OnClick = Open1Click
|
||||
end
|
||||
object N1: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object Close1: TMenuItem
|
||||
Caption = 'Close'
|
||||
ShortCut = 32883
|
||||
OnClick = Close1Click
|
||||
end
|
||||
end
|
||||
object Edit1: TMenuItem
|
||||
Caption = 'Edit'
|
||||
object SpellCheck1: TMenuItem
|
||||
Caption = 'Spell Check...'
|
||||
ShortCut = 118
|
||||
OnClick = SpellCheck1Click
|
||||
end
|
||||
object N2: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object Saveasimage1: TMenuItem
|
||||
Caption = 'Save as image...'
|
||||
OnClick = Saveasimage1Click
|
||||
end
|
||||
end
|
||||
end
|
||||
object OpenDialog1: TOpenDialog
|
||||
Filter = 'Text files|*.txt|RTF files|*.rtf|All files|*.*'
|
||||
left = 168
|
||||
top = 160
|
||||
end
|
||||
object SaveDialog1: TSaveDialog
|
||||
FileName = 'new.bmp'
|
||||
Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]
|
||||
left = 272
|
||||
top = 192
|
||||
end
|
||||
end
|
142
components/jvcllaz/examples/JvSpellChecker/MainFrm.pas
Normal file
142
components/jvcllaz/examples/JvSpellChecker/MainFrm.pas
Normal file
@@ -0,0 +1,142 @@
|
||||
{******************************************************************
|
||||
|
||||
JEDI-VCL Demo
|
||||
|
||||
Copyright (C) 2002 Project JEDI
|
||||
|
||||
Original author:
|
||||
|
||||
Contributor(s):
|
||||
|
||||
You may retrieve the latest version of this file at the JEDI-JVCL
|
||||
home page, located at http://jvcl.delphi-jedi.org
|
||||
|
||||
The contents of this file are used with permission, 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_1Final.html
|
||||
|
||||
Software distributed under the License is distributed on an
|
||||
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
******************************************************************}
|
||||
|
||||
unit MainFrm;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls, Menus, ComCtrls, JvComponent;
|
||||
|
||||
type
|
||||
TfrmMain = class(TForm)
|
||||
reText: TMemo;
|
||||
mmMain: TMainMenu;
|
||||
File1: TMenuItem;
|
||||
Edit1: TMenuItem;
|
||||
SpellCheck1: TMenuItem;
|
||||
Open1: TMenuItem;
|
||||
N1: TMenuItem;
|
||||
Close1: TMenuItem;
|
||||
StatusBar1: TStatusBar;
|
||||
OpenDialog1: TOpenDialog;
|
||||
N2: TMenuItem;
|
||||
Saveasimage1: TMenuItem;
|
||||
SaveDialog1: TSaveDialog;
|
||||
procedure Open1Click(Sender: TObject);
|
||||
procedure Close1Click(Sender: TObject);
|
||||
procedure SpellCheck1Click(Sender: TObject);
|
||||
procedure Saveasimage1Click(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
// FOffset is used to adjust the insert point in the rich edit when the replaced word
|
||||
// has a different length than the original word
|
||||
FOffset: integer;
|
||||
// called when a word should be replaced
|
||||
procedure DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
|
||||
// called when a word needs to be highlighted. NB: set HideSelection := false or you
|
||||
// won't see the selection in the edit!
|
||||
procedure DoSelectText(Sender: TObject; StartIndex, ALength: integer);
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
frmMain: TfrmMain;
|
||||
|
||||
implementation
|
||||
uses
|
||||
JvSpellCheckerForm;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
procedure TfrmMain.Open1Click(Sender: TObject);
|
||||
begin
|
||||
if OpenDialog1.Execute then
|
||||
begin
|
||||
reText.Lines.LoadFromFile(OpenDialog1.Filename);
|
||||
StatusBar1.Panels[0].Text := ' ' + OpenDialog1.Filename;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.Close1Click(Sender: TObject);
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.SpellCheck1Click(Sender: TObject);
|
||||
begin
|
||||
// set up the spell-checker form
|
||||
if not frmSpellChecker.Visible then
|
||||
begin
|
||||
// StartIndex is 1-based, SelStart is 0-based, so we set intial FOffset to 1
|
||||
FOffset := 1;
|
||||
// the original text to spell check
|
||||
frmSpellChecker.SpellText := reText.Lines.Text;
|
||||
// event handler for when a word is to be replaced
|
||||
frmSpellChecker.OnReplaceText := @DoReplaceText;
|
||||
// event handler for when a word needs to be selected
|
||||
frmSpellChecker.OnSelectText := @DoSelectText;
|
||||
frmSpellChecker.Show; // ShowModal also works
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.DoSelectText(Sender: TObject; StartIndex, ALength: integer);
|
||||
begin
|
||||
// just select the text in the rich edit so the user can see were he is
|
||||
reText.SelStart := StartIndex - FOffset;
|
||||
reText.SelLength := ALength;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.DoReplaceText(Sender: TObject; StartIndex,
|
||||
ALength: integer; const NewText: string);
|
||||
begin
|
||||
reText.SelStart := StartIndex - FOffset;
|
||||
reText.SelLength := ALength;
|
||||
// replace the selected text
|
||||
reText.SelText := NewText;
|
||||
// adjust offset for next round
|
||||
Inc(FOffset, ALength - Length(NewText));
|
||||
end;
|
||||
|
||||
procedure TfrmMain.Saveasimage1Click(Sender: TObject);
|
||||
var Picture:TPicture;
|
||||
begin
|
||||
if SaveDialog1.Execute then
|
||||
begin
|
||||
Picture := TPicture.Create;
|
||||
try
|
||||
// reText.SaveToImage(Picture);
|
||||
// Picture.SaveToFile(SaveDialog1.Filename);
|
||||
finally
|
||||
Picture.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
@@ -4,9 +4,6 @@
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<UseDefaultCompilerOptions Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="SimpleTLTest1"/>
|
||||
@@ -64,7 +61,7 @@
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="SimpleTLTest1"/>
|
||||
<Filename Value="..\..\bin\SimpleTLTest1"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
|
Reference in New Issue
Block a user