⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 synautocorrect.pas

📁 用delphi写的delphi源代码 用delphi写的delphi源代码 用delphi写的delphi源代码 用delphi写的delphi源代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{-------------------------------------------------------------------------------
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/

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.

The Original Code is: SynAutoCorrect.pas, released 2001-10-05.
Author of this file is Aaron Chan. All Rights Reserved.

Contributors to the SynEdit and mwEdit projects are listed in the
Contributors.txt file.

Alternatively, the contents of this file may be used under the terms of the
GNU General Public License Version 2 or later (the "GPL"), in which case
the provisions of the GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms
of the GPL and not to allow others to use your version of this file
under the MPL, indicate your decision by deleting the provisions above and
replace them with the notice and other provisions required by the GPL.
If you do not delete the provisions above, a recipient may use your version
of this file under either the MPL or the GPL.

$Id: SynAutoCorrect.pas,v 1.13 2004/05/06 19:16:42 markonjezic Exp $

You may retrieve the latest version of this file at the SynEdit home page,
located at http://SynEdit.SourceForge.net

-------------------------------------------------------------------------------}

{*******************************************************}
{                                                       }
{       Aerodynamica Components                         }
{       SynAutoCorrect 2.x                              }
{                                                       }
{       Copyright (c) 1996-2003, Aerodynamica Software  }
{                                                       }
{       Author: Aaron Chan                              }
{       Portions by Greg Nixon and Jan Fiala            }
{                                                       }
{*******************************************************}

{
  @author: Aaron Chan
  @url: http://aerodynamica.idz.net
  @comp-url: http://aerodynamica.idz.net/products.asp?id=SynAC_2
  @email: aerodynamica@idz.net
  @last-updated: 12/04/03
  @history:

    ! comment     * changed     + added
    - removed     @ bug-fixed   # todo

    12/04/2003
      - removed integrated sound support.
      * changed keyboard and mouse handling to use SynEdit plugin system.

    11/04/04 - Release 2.21:
      @ Fixed support for correction after delimiters.
      * SOUND_SUPPORT undefined by default.

    24/03/03 - Release 2.2:
      @ Fixed "Stack Overflow" bug and memory leak (fixed by Danail Traichev).

    30/09/02 - Release 2.1:
      @ Fixed bug when user KeyDown and MouseDown events weren't fired.
      + Added INI_FILES and REGISTRY compiler defines (to minimize code size
        if you don't need these features).
      * Further tidy-up of code.
      * Quite a few minor bug-fixes and tweaks.
      * Items editor enhanced.
      * Improved demo.
      * Registry and INI file entries are saved in a new and improved way, which
        overcomes some limitations set by the old method. If you still want to
        use the old method, define OLD_SAVE_METHOD.

    31/07/02 - Revision 2.01:
      @ Fixed bug which occured when undefining SOUND_SUPPORT (reported by
        Stefan Ascher).

    30/07/02 - First public release of version 2.0:
      @ MANY bugs fixed and small tweaks everywhere in the code (some
        courtesy of Jan Fiala).
      + Ability to play an optional WAVE file (or beep) on correction.
      + Options set.
      * New demo.
}

{$IFNDEF QSYNAUTOCORRECT}
unit SynAutoCorrect;
{$ENDIF}

{$I SynEdit.inc}

interface

uses
{$IFDEF SYN_WIN32} //Borland translation of Qt doesn't include Char handling
  Windows,
{$ELSE}
  Libc,
{$ENDIF}
{$IFDEF SYN_CLX}
  QGraphics,
  QControls,
  QForms,
  QDialogs,
  Types,
  QSynEditMiscProcs,
  QSynEditTypes,
  QSynEditKeyCmds,
  QSynEdit,
{$ELSE}
  Registry,
  Messages,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  SynEditMiscProcs,
  SynEditTypes,
  SynEditKeyCmds,
  SynEdit,
  SynEditMiscClasses,   //TBetterRegistry
{$ENDIF}
  Classes,
  SysUtils,
  IniFiles;

type
  TAsSynAutoCorrectOption = (ascoCorrectOnMouseDown, ascoIgnoreCase,
    ascoMaintainCase);
  TAsSynAutoCorrectOptions = set of TAsSynAutoCorrectOption;

  TAutoCorrectAction = (aaCorrect, aaAbort);
  TAutoCorrectEvent = procedure(Sender: TObject;
    const AOriginal, ACorrection: string; Line, Column: Integer;
    var Action: TAutoCorrectAction) of object;

  TCustomSynAutoCorrect = class(TComponent)
  private
    { Private declarations }

    { Published properties and events. }
    FEditor: TCustomSynEdit;
    FEnabled: Boolean;
    FItems: TStrings;
    FItemSepChar: Char;
    FOptions: TAsSynAutoCorrectOptions;
    fEditors: TList;

    FOnAutoCorrect: TAutoCorrectEvent;
    FOnCorrected: TNotifyEvent;

    { Private variables and methods. }
//    FPrevLine: Integer;

    function CorrectItemStart(EditLine, SearchString: string; StartPos: LongInt;
      MatchCase, WholeWord: Boolean): LongInt;
    function FindAndCorrect(Editor: TCustomSynEdit; var EditLine: string;
      Original, Correction: string; var CurrentX: Integer): Boolean;
    function PreviousToken(Editor: TCustomSynEdit): string;

    { Accessor methods. }
    function GetItems: TStrings;
    procedure SetItems(const Value: TStrings);
  protected
    { Protected declarations }
    procedure KeyboardHandler(Sender: TObject; AfterProcessing: boolean;
      var Handled: boolean; var Command: TSynEditorCommand; var AChar: char;
      Data: pointer; HandlerData: pointer); virtual;
    procedure MouseDownHandler(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer); virtual;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure SetEditor(Value: TCustomSynEdit);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    //mod Add
    procedure AddEditor(AEditor: TCustomSynEdit);
    //mod Add
    function RemoveEditor(AEditor: TCustomSynEdit): boolean;

    procedure Add(AOriginal, ACorrection: string);
    function AutoCorrectAll(Editor: TCustomSynEdit): Boolean;
    procedure Delete(AIndex: Integer);
    procedure Edit(AIndex: Integer; ANewOriginal, ANewCorrection: string);

    // mod 把选项也保存进去
    procedure LoadFromINI(Reg : TCustomIniFile; ASection: string);
    procedure SaveToINI(Reg : TCustomIniFile; ASection: string);

{$IFNDEF SYN_CLX}
    // mod 把选项也保存进去
    procedure LoadFromRegistry(ARoot: DWORD; AKey: string);
    procedure SaveToRegistry(ARoot: DWORD; AKey: string);
{$ENDIF}

    function LoadFromList(AFileName: string): Boolean;
    procedure SaveToList(AFileName: string);

    { Utility functions. }
    function HalfString(Str: string; GetFirstHalf: Boolean): string;
  public
    { Published declarations }
    property Enabled: Boolean read FEnabled write FEnabled default True;
    property Editor: TCustomSynEdit read FEditor write SetEditor;
    property Items: TStrings read GetItems write SetItems;
    property ItemSepChar: Char read FItemSepChar write FItemSepChar default #9;
    property Options: TAsSynAutoCorrectOptions read FOptions write FOptions
      default [ascoIgnoreCase, ascoMaintainCase];

    property OnAutoCorrect: TAutoCorrectEvent read FOnAutoCorrect
      write FOnAutoCorrect;
    property OnCorrected: TNotifyEvent read FOnCorrected write FOnCorrected;
  end;

  TSynAutoCorrect = class(TCustomSynAutoCorrect)
  published
    { Published declarations }
    property Enabled;
    property Editor;
    property Items;
    property ItemSepChar;
    property Options;

    property OnAutoCorrect;
    property OnCorrected;
  end;

var
  AC_IdentChars: set of char;

implementation

const
  FStrSepChar = '|';

{ TCustomSynAutoCorrect }

constructor TCustomSynAutoCorrect.Create(AOwner: TComponent);
var
  i: char;

begin
  inherited Create(AOwner);

{$IFDEF SYN_WIN32}
  for i := #33 to #255 do if IsCharAlphaNumeric(i) then Include(AC_IdentChars, i);
{$ELSE}
  for i := #33 to #255 do if isalpha(Ord(i)) <> 0 then Include(AC_IdentChars, i);
{$ENDIF}

  FEnabled := True;
  FItems := TStringList.Create;
  FItemSepChar := #9;
  FOptions := [ascoIgnoreCase, ascoMaintainCase];
//  FPrevLine := -1;
//  FEditor := nil; initialized by Delphi
  FEditors := TList.Create;
end;

destructor TCustomSynAutoCorrect.Destroy;
begin
  Editor := nil;
  inherited;
  FItems.Free;
  FEditors.Free;
end;

{ Utilities. }
function TCustomSynAutoCorrect.HalfString(Str: string;
  GetFirstHalf: Boolean): string;
var
  i: Integer;

begin
  i := LastDelimiter(FItemSepChar, Str);
  if i = 0 then i := Pred(MaxInt);

  if GetFirstHalf then
    Result := Copy(Str, 1, Pred(i))
  else
    Result := Copy(Str, Succ(i), MaxInt);
end;

procedure TCustomSynAutoCorrect.LoadFromIni(Reg: TCustomIniFile;
   ASection: string);
var
  i: Integer;
  Original, Correction: string;
//  Reg: TIniFile;
  Option :TAsSynAutoCorrectOption;
  OptionStr : string;
  Link : string;
  FileItem : TStrings;
begin
//  Reg := TIniFile.Create(AFileName);
//  try
    FItems.Clear;
    with Reg do
    begin
      Link := ReadString(ASection, 'Link', '');
      if Link <> '' then Link := ExpandFile(Link);
      if FileExists(Link) then
      begin
        FileItem := TStringList.Create;
        try
          FileItem.LoadFromFile(Link);
          FItems.AddStrings(FileItem);
        finally
          FileItem.Free;
        end;
      end
      else if ReadInteger(ASection, 'Count', 0) > 0 then
      begin
        for i := 0 to Pred(ReadInteger(ASection, 'Count', 0)) do
        begin
          Original := ReadString(ASection, 'Original' + IntToStr(i), '');
          Correction := ReadString(ASection, 'Correction' + IntToStr(i), '');
          if not ((Original = '') and (Correction = '')) then
            FItems.Add(Original + FItemSepChar + Correction);
        end;
      end;

      Enabled := ReadBool(ASection, 'Enabled', Enabled);
      ItemSepChar := Char(ReadInteger(ASection, 'ItemSepChar', Ord(ItemSepChar)));
      for Option := ascoCorrectOnMouseDown to ascoMaintainCase do
        OptionStr := OptionStr + IntToStr(Integer(Option in Options));
      OptionStr := ReadString(ASection, 'Options', OptionStr);
      for I := 1 to Length(OptionStr) do
        if (OptionStr[i] = '1') then
          FOptions := FOptions + [TAsSynAutoCorrectOption(I-1)];
    end;
//  finally
//    Reg.Free;
//  end;
end;

procedure TCustomSynAutoCorrect.SaveToIni(Reg : TCustomIniFile; ASection: string);
var
  i: Integer;
//  Reg: TIniFile;
  Option :TAsSynAutoCorrectOption;
  OptionStr : string;
  Link : string;
begin
//  Reg := TIniFile.Create(AFileName);
//  try
    with Reg do
    begin
      Link := ReadString(ASection, 'Link', '');
      if Link <> '' then Link := ExpandFile(Link);
      if FileExists(Link) then
      begin
        FItems.SaveToFile(Link);
      end
      else begin
        WriteInteger(ASection, 'Count', FItems.Count);
        for i := 0 to Pred(FItems.Count) do
        begin
          WriteString(ASection, 'Original' + IntToStr(i),
            HalfString(FItems[i], True));
          WriteString(ASection, 'Correction' + IntToStr(i),
            HalfString(FItems[i], False));
        end;
        WriteBool(ASection, 'Enabled', Enabled);
        WriteInteger(ASection, 'ItemSepChar', Ord(ItemSepChar));
        for Option := ascoCorrectOnMouseDown to ascoMaintainCase do
          OptionStr := OptionStr + IntToStr(Integer(Option in Options));
        WriteString(ASection, 'Options', OptionStr);
      end;
    end;
//  finally
//    Reg.Free;
//  end;
end;

function TCustomSynAutoCorrect.LoadFromList(AFileName: string): Boolean;
begin
  Result := False;
  if FileExists(AFileName) then
  begin
    FItems.LoadFromFile(AFileName);
    Result := True;
  end;
end;

procedure TCustomSynAutoCorrect.SaveToList(AFileName: string);
begin
  FItems.SaveToFile(AFileName);
end;

{$IFNDEF SYN_CLX}
procedure TCustomSynAutoCorrect.LoadFromRegistry(ARoot: DWORD; AKey: string);
var
  i: Integer;
  Original, Correction: string;
  Reg: TRegIniFile;
  Option :TAsSynAutoCorrectOption;
  OptionStr : string;
  Link : string;
  FileItem : TStrings;
begin
  Reg := TRegIniFile.Create('');
  try
    with Reg do
    begin
      RootKey := ARoot;
      TBetterRegistry(Reg).OpenKeyReadOnly(AKey);
      FItems.Clear;
      for i := 0 to Pred(ReadInteger('', 'Count', 0)) do
      begin
        Original := ReadString('', 'Original' + IntToStr(i), '');
        Correction := ReadString('', 'Correction' + IntToStr(i), '');
        if not ((Original = '') and (Correction = '')) then
          FItems.Add(Original + FItemSepChar + Correction);
      end;

      Link := ReadString('', 'Link', '');
      if Link <> '' then
      begin
        Link := ExpandFile(Link);
        if FileExists(Link) then
        begin
          FileItem := TStringList.Create;
          try
            FileItem.LoadFromFile(Link);
            FItems.AddStrings(FileItem);
          finally
            FileItem.Free;
          end;
        end;
      end;     

      Enabled := ReadBool('', 'Enabled', Enabled);
      ItemSepChar := Char(ReadInteger('', 'ItemSepChar', Ord(ItemSepChar)));
      for Option := ascoCorrectOnMouseDown to ascoMaintainCase do
        OptionStr := OptionStr + IntToStr(Integer(Option in Options));
      OptionStr := ReadString('', 'Options', OptionStr);
      for I := 1 to Length(OptionStr) do
        if (OptionStr[i] = '1') then
          FOptions := FOptions + [TAsSynAutoCorrectOption(I-1)];
    end;
  finally
    Reg.Free;
  end;
end;

procedure TCustomSynAutoCorrect.SaveToRegistry(ARoot: DWORD; AKey: string);
var
  i: Integer;
  Reg: TRegIniFile;
  Option :TAsSynAutoCorrectOption;
  OptionStr : string;
begin
  Reg := TRegIniFile.Create('');
  try
    with Reg do
    begin
      RootKey := ARoot;
      OpenKey(AKey, True);
      WriteInteger('', 'Count', FItems.Count);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -