{ *************************************************************************** }
{                                                                             }
{ EControl Syntax Editor SDK                                                  }
{                                                                             }
{ Copyright (c) 2004 - 2008 EControl Ltd., Zaharov Michael                    }
{     www.econtrol.ru                                                         }
{     support@econtrol.ru                                                     }
{                                                                             }
{ *************************************************************************** }
{$I ecSyntEdit.INC}

unit ecActns;

interface

uses
   Windows, Classes, ActnList, StdActns, StdCtrls, Dialogs, Controls, ecSyntMemo,
   ecSyntDlg, ecSyntAnal, ecPrint, ecExports, ecKeyMap, ecSyntTree, ecAutoReplace,
   ecAutoReplDlg, ecMultRepl;

const
  DL_KeyMappingSync = 10000;

type

  TecExecuteTargetEvent = procedure(Sender: TObject; Target: TCustomSyntaxMemo) of object;

  TecBaseAction = class(TCustomAction)
  private
    FAfterExecute: TNotifyEvent;
    FBeforeExecute: TNotifyEvent;
    FOnExecuteOK: TNotifyEvent;
    FLinkComponent: TComponent;
    procedure SetLinkComponent(const Value: TComponent);
  protected
    procedure SetEnabled(Value: boolean);
    procedure SetChecked(Value: boolean);
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    property LinkComponent: TComponent read FLinkComponent write SetLinkComponent;
    procedure BeginDoAfterExecute;
    procedure DoExecute; virtual;
    property OnExecuteOK: TNotifyEvent read FOnExecuteOK write FOnExecuteOK;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Caption;
    property HelpContext;
    {$IFDEF EC_VCL6_UP}
    property HelpKeyword;
    property HelpType;
    property SecondaryShortCuts;
    {$ENDIF}
    property Hint;
    property ImageIndex;
    property ShortCut;
    property Visible;
    property OnHint;
    property AfterExecute: TNotifyEvent read FAfterExecute write FAfterExecute;
    property BeforeExecute: TNotifyEvent read FBeforeExecute write FBeforeExecute;
//    property AutoCheck;
//    property Checked;
//    property Enabled;
//    property GroupIndex;
//    property OnExecute;
//    property OnUpdate;
  end;

  TecBaseCompAction = class(TecBaseAction)
  public
    function Update: Boolean; override;
    function Execute: Boolean; override;
  end;

  TecBaseMemoAction = class(TecBaseAction)
  private
    FSyntMemo: TCustomSyntaxMemo;
    FKeyMappingSync: Boolean;
    FLastSync: Cardinal;
    procedure SetSyntMemo(const Value: TCustomSyntaxMemo);
    procedure IntExecute;
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    function GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent; virtual;
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); virtual;
    function NeedTarget: Boolean; virtual;

    function GetCommand: integer; virtual;
    property KeyMappingSync: Boolean read FKeyMappingSync write FKeyMappingSync default False;
  public
    function  HandlesTarget(Target: TObject): Boolean; override;
    procedure UpdateTarget(Target: TObject); override;
    procedure ExecuteTarget(Target: TObject); override;
    function Update: Boolean; override;
    function Execute: Boolean; override;
  published
    property SyntMemo: TCustomSyntaxMemo read FSyntMemo write SetSyntMemo;
    property OnExecuteOK;
  end;

  TecCustomCommandAction = class(TecBaseMemoAction)
  private
    FCommand: integer;
    procedure SetCommandProp(const Value: integer);
  protected
    property Command: integer read FCommand write SetCommandProp;
    procedure DoExecute; override;
    function GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent; override;
    function GetCommand: integer; override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetCommand(const Value: integer);
    function Update: Boolean; override;
  published
    property KeyMappingSync;
  end;

  TecCommandAction = class(TecCustomCommandAction)
  published
    property Command;
  end;

  // Edit Actions (it's uses ExecCommand, whereas drived from
  //               TEditAction call corresponding methods (Copy, Cut ...))

  TecCopy = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecCopyAsRTF = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecCut = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecPaste = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecClear = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSelectAll = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecUndo = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecRedo = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // Block Actions

  TecIndent = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecUnindent = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecLowerCase = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecUpperCase = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecToggleCase = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // Collapse Actions

  TecToggleCollapse = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecToggleCollapseNearest = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecFullCollapse = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecFullExpand = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecIncrementalSearch = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // Search & Replace Actions

  TecBaseSearchAction = class(TecCustomCommandAction)
  private
    procedure SetDialog(const Value: TSyntFindDialog);
    function GetDialog: TSyntFindDialog;
  protected
    function DlgClass: TComponentClass;
    procedure DoExecute; override;
    function DialogExecute: Boolean; virtual; abstract;
    function NeedTarget: Boolean; override;
  published
    property Dialog: TSyntFindDialog read GetDialog write SetDialog;
  end;

  TecSearch = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchAgain = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchNext = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchPrior = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchAll = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchFirst = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSearchLast = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecFindCurrentWordNextAction = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecFindCurrentWordPriorAction = class(TecBaseSearchAction)
  protected
    function DialogExecute: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplace = class(TecSearch)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplaceAgain = class(TecSearchAgain)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplaceNext = class(TecSearchNext)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplacePrior = class(TecSearchPrior)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplaceAll = class(TecSearchAll)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplaceFirst = class(TecSearchFirst)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecReplaceLast = class(TecSearchLast)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // User ranges actions

  TecUserRangeBaseAction = class(TecBaseMemoAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  end;

  TecUserRangeDelete = class(TecUserRangeBaseAction)
  protected
    procedure DoExecute; override;
  end;

  TecUserRangeBaseProp = class(TecUserRangeBaseAction)
  private
    FAllowCreate: Boolean;
  protected
    procedure SetRangeProps(Range: TUserRange); virtual; abstract;
    function IsChecked(Range: TUserRange): Boolean; virtual; abstract;
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property AllowCreate: Boolean read FAllowCreate write FAllowCreate default True;
  end;

  TecUserRangeCollapsable = class(TecUserRangeBaseProp)
  protected
    procedure SetRangeProps(Range: TUserRange); override;
    function IsChecked(Range: TUserRange): Boolean; override;
  end;

  TecUserRangeTopLine = class(TecUserRangeBaseProp)
  protected
    function IsChecked(Range: TUserRange): Boolean; override;
    procedure SetRangeProps(Range: TUserRange); override;
  end;

  TecUserRangeBottomLine = class(TecUserRangeBaseProp)
  protected
    function IsChecked(Range: TUserRange): Boolean; override;
    procedure SetRangeProps(Range: TUserRange); override;
  end;

  TecUserRangeLineHighlight = class(TecUserRangeBaseProp)
  protected
    function IsChecked(Range: TUserRange): Boolean; override;
    procedure SetRangeProps(Range: TUserRange); override;
  end;

  // Print actions
  TGetPrinterEvent = procedure(Sender: TObject; var Prn: TecCustomPrinter) of object;

  TecBasePrintAction = class(TecCommandAction)
  private
    FAllowCreate: Boolean;
    FOnGetPrinter: TGetPrinterEvent;
    procedure SetSyntPrinter(const Value: TecCustomPrinter);
    function GetSyntPrinter: TecCustomPrinter;
  protected
    function GetPrinter: TecCustomPrinter; dynamic;
    procedure DoExecute; override;
    function DialogExecute(APrinter: TecCustomPrinter): Boolean; virtual; abstract;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property SyntPrinter: TecCustomPrinter read GetSyntPrinter write SetSyntPrinter;
    property OnGetPrinter: TGetPrinterEvent read FOnGetPrinter write FOnGetPrinter;
  end;

  TecPrintAction = class(TecBasePrintAction)
  private
    FPrintDialog: TPrintDialog;
    procedure SetPrintDialog(const Value: TPrintDialog);
  protected
    function DialogExecute(APrinter: TecCustomPrinter): Boolean; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property PrintDialog: TPrintDialog read FPrintDialog write SetPrintDialog;
  end;

  TecPreviewAction = class(TecBasePrintAction)
  protected
    function DialogExecute(APrinter: TecCustomPrinter): Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecPageSetupAction = class(TecBasePrintAction)
  protected
    function DialogExecute(APrinter: TecCustomPrinter): Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // Bookmark actions

  TecBaseBookmarkAction = class(TecBaseMemoAction)
  private
    fBaseCaption: string;
    fLineColumnFormat: string;
    fBookmarkNr: Integer;
  protected
    procedure AssignTo(Dest: TPersistent); override;
    procedure SetBookmarkNr(Value: Integer);
    procedure SetBaseCaption(Value: string);
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
    //  published
    property BookmarkNr: Integer read fBookmarkNr write SetBookmarkNr;
    property BaseCaption: string read fBaseCaption write SetBaseCaption;
    property LineColumnFormat: string read fLineColumnFormat write
      fLineColumnFormat;
  end;

  TecBookmarkClearAllAction = class(TecBaseBookmarkAction)
  protected
    procedure DoExecute; override;
  end;

  TecBookmarkSetAction = class(TecBaseBookmarkAction)
  protected
    procedure DoExecute; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property BookmarkNr;
    property BaseCaption;
    property LineColumnFormat;
    property KeyMappingSync;
  end;

  TecBookmarkGotoAction = class(TecBaseBookmarkAction)
  protected
    procedure DoExecute; override;
    function GetCommand: Integer; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property BookmarkNr;
    property BaseCaption;
    property LineColumnFormat;
    property KeyMappingSync;
  end;

  TecBookmarkToggleAction = class(TecBaseBookmarkAction)
  protected
    procedure DoExecute; override;
    function GetCommand: Integer; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property BookmarkNr;
    property BaseCaption;
    property LineColumnFormat;
    property KeyMappingSync;
  end;

  TecBookmarkClearAction = class(TecBaseBookmarkAction)
  protected
    procedure DoExecute; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property BookmarkNr;
    property BaseCaption;
    property LineColumnFormat;
    property KeyMappingSync;
  end;

  TecBaseExportAction = class(TecBaseMemoAction)
  private
    FDefaultExt: string;
    FExportType: TExportType;
    FFilter: string;
    FInitialDir: string;
    FOptions: TOpenOptions;
    FUseCaseFormatting: Boolean;
    {$IFDEF EC_VCL6_UP}
    FOptionsEx: TOpenOptionsEx;
    {$ENDIF}
  protected
    function CreateExportClass: TPlainTextSyntExport; virtual; abstract;
    procedure DoExecute; override;
  public
    constructor Create(AOwner : TComponent); override;
  published
    property DefaultExt: string read FDefaultExt write FDefaultExt;
    property ExportType: TExportType read FExportType write FExportType default etAllText;
    property Filter: string read FFilter write FFilter;
    property InitialDir: string read FInitialDir write fInitialDir;
    property Options: TOpenOptions read FOptions write FOptions;
    property UseCaseFormatting: Boolean read FUseCaseFormatting write FUseCaseFormatting default False;
    {$IFDEF EC_VCL6_UP}
    property OptionsEx: TOpenOptionsEx read FOptionsEx write FOptionsEx;
    {$ENDIF}
  end;

  TecExportRTFAction = class(TecBaseExportAction)
  protected
    function CreateExportClass: TPlainTextSyntExport; override;
  public
    constructor Create(AOwner : TComponent); override;
  end;

  TecExportHTMLAction = class(TecBaseExportAction)
  protected
    function CreateExportClass: TPlainTextSyntExport; override;
  public
    constructor Create(AOwner : TComponent); override;
  end;

  TecToggleNonPrinted = class(TecCustomCommandAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecToggleWordWrap = class(TecCustomCommandAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSyncEditMode = class(TecBaseMemoAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecToggleFolding = class(TecCustomCommandAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;
// =============================================================================
//   Customize actions
// =============================================================================

  TecBaseLexerCustomize = class(TecBaseMemoAction)
  private
    procedure SetSyntAnalyzer(const Value: TSyntAnalyzer);
    function GetSyntAnalyzer: TSyntAnalyzer;
  protected
    function GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent; override;
  published
    property SyntAnalyzer: TSyntAnalyzer read GetSyntAnalyzer write SetSyntAnalyzer;
  end;

  TecBaseKeyMappingCustomize = class(TecBaseMemoAction)
  private
    procedure SetKeyMapping(const Value: TSyntKeyMapping);
    function GetKeyMapping: TSyntKeyMapping;
  protected
    function GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent; override;
  published
    property KeyMapping: TSyntKeyMapping read GetKeyMapping write SetKeyMapping;
  end;

  TecBaseUserStylesCustomize = class(TecBaseMemoAction)
  private
    procedure SetUserStyles(const Value: TSyntStyles);
    function GetUserStyles: TSyntStyles;
  protected
    function GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent; override;
  published
    property UserStyles: TSyntStyles read GetUserStyles write SetUserStyles;
  end;

  TecCustomizeEditorOptionsAction = class(TecBaseMemoAction)
  protected
    procedure DoExecute; override;
  end;

  TecCustomizeSyntaxHighlightingAction = class(TecBaseLexerCustomize)
  protected
    procedure DoExecute; override;
  end;

  TecCustomizeLexerPropertiesAction = class(TecBaseLexerCustomize)
  protected
    procedure DoExecute; override;
  end;

  TecCustomizeKeyMappingAction = class(TecBaseKeyMappingCustomize)
  protected
    procedure DoExecute; override;
  end;

  TecCustomizeUserStylesAction = class(TecBaseUserStylesCustomize)
  protected
    procedure DoExecute; override;
  end;

  TecCustomizeLexerLib = class(TecBaseCompAction)
  private
    procedure SetSyntaxManager(const Value: TSyntaxManager);
    function GetSyntaxManager: TSyntaxManager;
  protected
    procedure DoExecute; override;
  published
    property SyntaxManager: TSyntaxManager read GetSyntaxManager write SetSyntaxManager;
  end;

  TecCustomizeAutoReplace = class(TecBaseCompAction)
  private
    function GetAutoReplace: TSyntAutoReplace;
    procedure SetAutoReplace(const Value: TSyntAutoReplace);
  protected
    procedure DoExecute; override;
  published
    property AutoReplace: TSyntAutoReplace read GetAutoReplace write SetAutoReplace;
  end;

  TecToggleSyntTreeSync = class(TecBaseCompAction)
  private
    function GetSyntaxTree: TSyntaxTreeView;
    procedure SetSyntaxTree(const Value: TSyntaxTreeView);
  protected
    procedure DoExecute; override;
  public
    function Update: Boolean; override;
  published
    property SyntaxTree: TSyntaxTreeView read GetSyntaxTree write SetSyntaxTree;
  end;

  TecCommentLines = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecUnCommentLines = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecInSelCollapse = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecInSelExpand = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecMacroRecord = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecMacroStop = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecMacroCancel = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecMacroPlay = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSortAscending = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSortDescending = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecGotoLine = class(TecCustomCommandAction)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecSyntMemoAction = class(TecBaseMemoAction)
  private
    FMustBeSelected: Boolean;
    FOnExecuteTarget: TecExecuteTargetEvent;
  protected
    procedure DoExecute; override;
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    property OnExecuteOK;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property MustBeSelected: Boolean read FMustBeSelected write FMustBeSelected default False;
    property OnExecuteTarget: TecExecuteTargetEvent read FOnExecuteTarget write FOnExecuteTarget;
  end;

  TecToggleLineNumbersVisible = class(TecCustomCommandAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TecBaseMultiReplaceAction = class(TecBaseMemoAction)
  private
    FMultiReplace: TecMultiReplace;
    procedure SetMultiReplace(const Value: TecMultiReplace); virtual;
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  published
    property MultiReplace: TecMultiReplace read FMultiReplace write SetMultiReplace;
  end;

  TecMultiReplaceItemAction = class(TecBaseMultiReplaceAction)
  private
    FItemIndex: Integer;
    procedure SetItemIndex(const Value: Integer);
    procedure SetMultiReplace(const Value: TecMultiReplace); override;
  protected
    procedure DoExecute; override;
    procedure SetCaptionHint;
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ItemIndex: Integer read FItemIndex write SetItemIndex;
  end;

  TecMultiReplaceCustomizeAction = class(TecBaseMultiReplaceAction)
  protected
    procedure DoExecute; override;
  end;

  TecMultiReplaceSelectExecuteAction = class(TecBaseMultiReplaceAction)
  protected
    procedure DoExecute; override;
  end;

// =============================================================================
//   Custom formatting actions
// =============================================================================
  TecEnableFormattingAction = class(TecBaseMemoAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecBaseFormattingAction = class(TecBaseMemoAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
  end;

  TecFormattingBold = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingItalic = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingUnderline = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingStrikeout = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingReadOnly = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingHidden = class(TecBaseFormattingAction)
  protected
    procedure UpdateMemo(Memo: TCustomSyntaxMemo); override;
    procedure DoExecute; override;
  end;

  TecFormattingClearSel = class(TecBaseFormattingAction)
  protected
    procedure DoExecute; override;
  end;

  TecFormattingClearAll = class(TecBaseFormattingAction)
  protected
    procedure DoExecute; override;
  end;

function RemoveAmpersand(S: string): string;

implementation

uses ecCmdConst, SysUtils, ecPreviewFm, {$IFDEF EC_VCL6_UP}Types,{$ENDIF}
     ecCustEditDlg, Printers{$IFDEF EC_VCL6_UP}, StrUtils{$ENDIF};


var
  GlobalFindDialog: TSyntFindDialog = nil;
  GlobalReplaceDialog: TSyntReplaceDialog = nil;
  GlobalPrintDialog: TecCustomPrinter = nil;


function RemoveAmpersand(S: string): string;
var i: integer;
begin
  Result := S;
  for i := Length(Result) downto 1 do
   if Result[i] = '&' then Delete(Result, i, 1);
end;

constructor TecBaseAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAfterExecute := nil;
  FBeforeExecute := nil;
  FOnExecuteOK := nil;
  FLinkComponent := nil;
end;

{ TecBaseAction }

procedure TecBaseAction.DoExecute;
begin
  if Assigned(FOnExecuteOK) then FOnExecuteOK(Self);
end;

procedure TecBaseAction.SetEnabled(Value: boolean);
begin
  if Enabled <> Value then
    Enabled := Value;
end;

procedure TecBaseAction.SetChecked(Value: boolean);
begin
  if Checked <> Value then
    Checked := Value;
end;

procedure TecBaseAction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FLinkComponent) then
    FLinkComponent := nil;
end;

procedure TecBaseAction.SetLinkComponent(const Value: TComponent);
begin
  if FLinkComponent <> Value then
  begin
    FLinkComponent := Value;
    if Assigned(FLinkComponent) then
      FLinkComponent.FreeNotification(Self);
  end;
end;

destructor TecBaseAction.Destroy;
begin
  {$IFDEF EC_VCL6_UP}
  ActionComponent := nil;
  {$ENDIF}
  inherited;
end;

{ TecBaseCompAction }

procedure TecBaseAction.BeginDoAfterExecute;
begin
  if Assigned(BeforeExecute) then
    BeforeExecute(Self);
  DoExecute;
  if Assigned(AfterExecute) then
    AfterExecute (Self);
end;

function TecBaseCompAction.Execute: Boolean;
begin
  Result := True;
  BeginDoAfterExecute;
end;

function TecBaseCompAction.Update: Boolean;
begin
  Result := True;
  SetEnabled (Assigned(LinkComponent));
end;

{ TecBaseMemoAction }

procedure TecBaseMemoAction.IntExecute;
begin
  if Not Assigned(FLinkComponent) then
    try
      FLinkComponent := GetLinkComponent(FSyntMemo);
      if Assigned(FLinkComponent) then
        begin
          if FLinkComponent = FSyntMemo then
            FLinkComponent := nil;
          BeginDoAfterExecute;
        end;
    finally
      FLinkComponent := nil;
    end
  else
    BeginDoAfterExecute;
end;

function TecBaseMemoAction.Execute: Boolean;
begin
  if NeedTarget then
    Result := inherited Execute
  else
    begin
      IntExecute;
      Result := True;
    end;
end;

procedure TecBaseMemoAction.ExecuteTarget(Target: TObject);
begin
  if not Assigned(FSyntMemo) and Assigned(Target) and (Target is TCustomSyntaxMemo) then
   begin
     FSyntMemo := TCustomSyntaxMemo(Target);
     try
       IntExecute;
     finally
       FSyntMemo := nil;
     end;
   end
end;

function TecBaseMemoAction.GetCommand: integer;
begin
  Result := -1;
end;

function TecBaseMemoAction.GetLinkComponent(Memo: TCustomSyntaxMemo): TComponent;
begin
  Result := Memo;
end;

function TecBaseMemoAction.HandlesTarget(Target: TObject): Boolean;
begin
  Result := NeedTarget and Assigned(Target) and
            (Target is TCustomSyntaxMemo){ and
            (Target as TCustomSyntaxMemo).Focused};
end;

function TecBaseMemoAction.NeedTarget: Boolean;
begin
  Result := not Assigned(FSyntMemo) and not Assigned(FLinkComponent);
end;

procedure TecBaseMemoAction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FSyntMemo) then
    FSyntMemo := nil;
end;

procedure TecBaseMemoAction.SetSyntMemo(const Value: TCustomSyntaxMemo);
begin
  if FSyntMemo <> Value then
  begin
    FSyntMemo := Value;
    if Assigned(FSyntMemo) then
      FSyntMemo.FreeNotification(Self);
  end;
end;

function TecBaseMemoAction.Update: Boolean;
begin
  Result := Assigned(LinkComponent) or Assigned(FSyntMemo);
  if not Result then
  begin
    Result := inherited Update;
    if not Result then
      SetEnabled (False);
  end
  else
    if Assigned(FSyntMemo) then
      UpdateMemo(FSyntMemo)
    else
      SetEnabled (Assigned(LinkComponent));
end;

procedure TecBaseMemoAction.UpdateMemo(Memo: TCustomSyntaxMemo);
var ovr: TecCommandItem;
    Key: TShortCut;
begin
  SetEnabled (Assigned(GetLinkComponent(Memo)));
  if FKeyMappingSync and (GetCommand <> -1) and (GetTickCount - FLastSync > DL_KeyMappingSync) then
  begin
    FLastSync := GetTickCount;
    if Assigned(Memo.KeyMapping) then
      ovr := Memo.KeyMapping.CommandByID(GetCommand)
    else
      ovr := DefaultKeyMapping.CommandByID(GetCommand);

    if Assigned(ovr) then Key := ovr.MenuShortCut
                     else Key := 0;

    if ShortCut <> Key then ShortCut := Key;
  end;
end;

procedure TecBaseMemoAction.UpdateTarget(Target: TObject);
begin
  UpdateMemo(TCustomSyntaxMemo(Target));
end;

{ TecCustomCommandAction }

constructor TecCustomCommandAction.Create(AOwner: TComponent);
begin
  inherited;
  FKeyMappingSync := False;
  FCommand := 0;
end;

procedure TecCustomCommandAction.DoExecute;
begin
  {TCustomSyntaxMemo(LinkComponent)}FSyntMemo.ExecCommand(FCommand, nil);
  inherited;
end;

procedure TecCustomCommandAction.SetCommand(const Value: integer);
var cmd: TecCommandItem;
begin
  if FCommand <> Value then
   begin
     FCommand := Value;
     if csDesigning in ComponentState then
       begin
         cmd := DefaultKeyMapping.CommandByID(Value);
         if Assigned(Cmd) then
           begin
             Caption := cmd.Caption;
             Hint := RemoveAmpersand(cmd.Caption) + '|' + cmd.DisplayName;
             ShortCut := cmd.MenuShortCut;
           end;
       end;
   end;
end;

procedure TecCustomCommandAction.SetCommandProp(const Value: integer);
//var cmd: TecCommand;
begin
//  cmd := ecCommands.FindCommand(Value);
//  if cmd <> nil then
     FCommand := Value;
end;

function TecCustomCommandAction.Update: Boolean;
begin
  if FCommand <> 0 then Result := inherited Update
   else
    begin
      SetEnabled (False);
      Result := True;
    end;
end;

function TecCustomCommandAction.GetLinkComponent(
  Memo: TCustomSyntaxMemo): TComponent;
begin
  if Memo.IsCommandEnabled(FCommand)
   then Result := inherited GetLinkComponent(Memo)
   else Result := nil;
end;

function TecCustomCommandAction.GetCommand: integer;
begin
  Result := FCommand;
end;

{ TecCopy }

constructor TecCopy.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smCopy);
end;

{ TecCopyAsRTF }

constructor TecCopyAsRTF.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smCopyAsRTF);
end;

{ TecCut }

constructor TecCut.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smCut);
end;

{ TecPaste }

constructor TecPaste.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smPaste);
end;

{ TecClear }

constructor TecClear.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smClearSelection);
end;

{ TecSelectAll }

constructor TecSelectAll.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smSelectAll);
end;

{ TecUndo }

constructor TecUndo.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smUndo);
end;

{ TecRedo }

constructor TecRedo.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smRedo);
end;

{ TecIndent }

constructor TecIndent.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smBlockIndent);
end;

{ TecUnindent }

constructor TecUnindent.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smBlockUnindent);
end;

{ TecLowerCase }

constructor TecLowerCase.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smLowerCaseBlock);
end;

{ TecUpperCase }

constructor TecUpperCase.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smUpperCaseBlock);
end;

{ TecToggleCase }

constructor TecToggleCase.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smToggleCaseBlock);
end;

{ TecToggleCollapse }

constructor TecToggleCollapse.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smToggleCollapse);
end;

{ TecToggleCollapseNearest }

constructor TecToggleCollapseNearest.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smToggleCollapseNearest);
end;

{ TecFullCollapse }

constructor TecFullCollapse.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFullCollapse);
end;

{ TecFullExpand }

constructor TecFullExpand.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFullExpand);
end;

{ TecIncrementalSearch }

constructor TecIncrementalSearch.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smIncrementalSearch);
end;

{ TecBaseSearchAction }

function TecBaseSearchAction.GetDialog: TSyntFindDialog;
begin
  if Assigned(LinkComponent) and (LinkComponent is TSyntFindDialog) then
    Result := TSyntFindDialog(LinkComponent)
  else
    Result := nil;
end;

function TecBaseSearchAction.DlgClass: TComponentClass;
begin
  if ClassType.ClassParent <> TecBaseSearchAction then
    Result := TSyntReplaceDialog
  else
    Result := TSyntFindDialog;
end;

procedure TecBaseSearchAction.SetDialog(const Value: TSyntFindDialog);
begin
  if GetDialog <> Value then
   begin
    if Assigned(Value) and (Value.ClassType <> DlgClass) then
      raise Exception.CreateFmt('You have to assign %s', [DlgClass.ClassName]);
    LinkComponent := Value;
   end;
end;

procedure TecBaseSearchAction.DoExecute;
begin
  // executing selected dialog
  if Assigned(LinkComponent) and (LinkComponent.ClassType = DlgClass) then
    begin
      if Assigned(SyntMemo) then
        Dialog.Control := SyntMemo;
      if DialogExecute then
        if Assigned(FOnExecuteOK) then FOnExecuteOK(Self);
    end else
  // Executing command
  if SyntMemo.ClientOfType(DlgClass) <> nil then
    inherited else
  if not Assigned(LinkComponent) then
    begin // executing global dialog
      if DlgClass = TSyntFindDialog then
        begin
          if not Assigned(GlobalFindDialog) then
            GlobalFindDialog := TSyntFindDialog.Create(nil);
          FLinkComponent := GlobalFindDialog;
        end else
      if DlgClass = TSyntReplaceDialog then
        begin
          if not Assigned(GlobalReplaceDialog) then
            GlobalReplaceDialog := TSyntReplaceDialog.Create(nil);
          FLinkComponent := GlobalReplaceDialog;
        end;
      try
        if Assigned(SyntMemo) then
          TSyntFindDialog(LinkComponent).Control := SyntMemo;
        if DialogExecute then
          if Assigned(FOnExecuteOK) then FOnExecuteOK(Self);
      finally
        FLinkComponent := nil;
      end;
    end;
end;

function TecBaseSearchAction.NeedTarget: Boolean;
begin
  if Assigned(Dialog) and not Assigned(Dialog.Control) then
    Result := True
  else
    Result := inherited NeedTarget;
end;

{ TecSearch }

constructor TecSearch.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindDialog);
end;

function TecSearch.DialogExecute: Boolean;
begin
  Result := Dialog.Execute;
end;

{ TecSearchAgain }

constructor TecSearchAgain.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smSearchAgain);
end;

function TecSearchAgain.DialogExecute: Boolean;
begin
  Result := Dialog.SearchAgain;
end;

{ TecSearchNext }

constructor TecSearchNext.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindNext);
end;

function TecSearchNext.DialogExecute: Boolean;
begin
  Result := Dialog.FindNext;
end;

{ TecSearchPrior }

constructor TecSearchPrior.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindPrev);
end;

function TecSearchPrior.DialogExecute: Boolean;
begin
  Result := Dialog.FindPrev;
end;

{ TecSearchAll }

constructor TecSearchAll.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindAll);
end;

function TecSearchAll.DialogExecute: Boolean;
begin
  Result := Dialog.FindAll;
end;

{ TecSearchFirst }

constructor TecSearchFirst.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindFirst);
end;

function TecSearchFirst.DialogExecute: Boolean;
begin
  Result := Dialog.FindFirst;
end;

{ TecSearchLast }

constructor TecSearchLast.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindLast);
end;

function TecSearchLast.DialogExecute: Boolean;
begin
  Result := Dialog.FindLast;
end;

{ TecFindCurrentWordNextAction }

constructor TecFindCurrentWordNextAction.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindCurrentWordNext);
end;

function TecFindCurrentWordNextAction.DialogExecute: Boolean;
var wStart, wEnd : Integer;
    Memo : TCustomSyntaxMemo;
begin
  Memo := TCustomSyntaxMemo(Dialog.Control);
  Result := Assigned(Memo);
  if Result then
    begin
      Memo.WordRangeAtPos(Memo.CaretPos, wStart, wEnd);
      Result := wEnd > wStart;
      If Result then
      Begin
        Dialog.FindText := Memo.WordAtPos(Memo.CaretPos);
        Memo.CaretStrPos := wEnd;
        Result := Dialog.FindNext;
      end;
    end;
end;

{ TecFindCurrentWordPriorAction }

constructor TecFindCurrentWordPriorAction.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smFindCurrentWordPrior);
end;

function TecFindCurrentWordPriorAction.DialogExecute: Boolean;
var wStart, wEnd : Integer;
    Memo : TCustomSyntaxMemo;
begin
  Memo := TCustomSyntaxMemo(Dialog.Control);
  Result := Assigned(Memo);
  if Result then
    begin
      Memo.WordRangeAtPos(Memo.CaretPos, wStart, wEnd);
      Result := wEnd > wStart;
      if Result then
        begin
          Dialog.FindText := Memo.WordAtPos(Memo.CaretPos);
          Memo.CaretStrPos := wStart;
          Result := Dialog.FindPrev;
        end;
    end;
end;

{ TecReplace }

constructor TecReplace.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceDialog);
end;

{ TecReplaceAgain }

constructor TecReplaceAgain.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceAgain);
end;

{ TecReplaceNext }

constructor TecReplaceNext.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceNext);
end;

{ TecReplacePrior }

constructor TecReplacePrior.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplacePrev);
end;

{ TecReplaceAll }

constructor TecReplaceAll.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceAll);
end;

{ TecReplaceFirst }

constructor TecReplaceFirst.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceFirst);
end;

{ TecReplaceLast }

constructor TecReplaceLast.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smReplaceLast);
end;

{ TecUserRangeBaseAction }

procedure TecUserRangeBaseAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled (Memo.CurrentUserRange <> nil);
end;

{ TecUserRangeDelete }

procedure TecUserRangeDelete.DoExecute;
var ur: TUserRange;
begin
  ur := SyntMemo.CurrentUserRange;
  if ur <> nil then
   begin
    ur.Free;
    SyntMemo.Invalidate;
   end;
  inherited;
end;

{ TecUserRangeBaseProp }

constructor TecUserRangeBaseProp.Create(AOwner: TComponent);
begin
  inherited;
  FAllowCreate := True;
  {$IFDEF EC_VCL6_UP}
  AutoCheck := True;
  {$ENDIF}
end;

procedure TecUserRangeBaseProp.DoExecute;
var ur: TUserRange;
begin
  with SyntMemo do
   begin
    ur := CurrentUserRange;
    if ur = nil then
     begin
       if (not FAllowCreate) or (SelLength = 0) then Exit;
       ur := UserRanges.Add;
       ur.StartPos := SelStart;
       ur.EndPos := SelStart + SelLength;
     end;
    SetRangeProps(ur);
    Invalidate;
   end;
  inherited;
end;

procedure TecUserRangeBaseProp.UpdateMemo(Memo: TCustomSyntaxMemo);
var ur: TUserRange;
begin
  ur := Memo.CurrentUserRange;
  SetEnabled ((ur <> nil) or
             FAllowCreate and (Memo.SelLength > 0));
  if not Enabled and Checked then
    SetChecked (False)
  else
    SetChecked ((ur <> nil) and IsChecked(ur));
end;

{ TecUserRangeCollapsable }

function TecUserRangeCollapsable.IsChecked(Range: TUserRange): Boolean;
begin
  Result := Range.Collapsable;
end;

procedure TecUserRangeCollapsable.SetRangeProps(Range: TUserRange);
begin
  Range.Collapsable := not Range.Collapsable;
end;

{ TecUserRangeTopLine }

function TecUserRangeTopLine.IsChecked(Range: TUserRange): Boolean;
begin
  Result := lbTop in Range.LineBreaks;
end;

procedure TecUserRangeTopLine.SetRangeProps(Range: TUserRange);
begin
  with Range do
    if lbTop in LineBreaks then LineBreaks := LineBreaks - [lbTop]
                           else LineBreaks := LineBreaks + [lbTop];
end;

{ TecUserRangeBottomLine }

function TecUserRangeBottomLine.IsChecked(Range: TUserRange): Boolean;
begin
  Result := lbBottom in Range.LineBreaks;
end;

procedure TecUserRangeBottomLine.SetRangeProps(Range: TUserRange);
begin
  with Range do
    if lbBottom in LineBreaks then LineBreaks := LineBreaks - [lbBottom]
                              else LineBreaks := LineBreaks + [lbBottom];
end;

{ TecUserRangeLineHighlight }

function TecUserRangeLineHighlight.IsChecked(Range: TUserRange): Boolean;
begin
  Result := Range.HighlightLines;
end;

procedure TecUserRangeLineHighlight.SetRangeProps(Range: TUserRange);
begin
  Range.HighlightLines := not Range.HighlightLines;
end;

{ TecBasePrintAction }

procedure TecBasePrintAction.SetSyntPrinter(const Value: TecCustomPrinter);
begin
  LinkComponent := Value;
end;

function TecBasePrintAction.GetSyntPrinter: TecCustomPrinter;
begin
  Result := TecCustomPrinter(LinkComponent);
end;

function TecBasePrintAction.GetPrinter: TecCustomPrinter;
begin
  if Assigned(LinkComponent) and (LinkComponent is TecCustomPrinter) then
    Result := TecCustomPrinter(LinkComponent)
  else
    Result := nil;
  if Assigned(FOnGetPrinter) then
    FOnGetPrinter(Self, Result);
  if not Assigned(Result) and FAllowCreate then
    begin
      if not Assigned(GlobalPrintDialog) then
        GlobalPrintDialog := TecSyntPrinter.Create(nil);
      Result := GetSyntPrinter;
    end;
  if Assigned(Result) and Assigned(SyntMemo) and (Result is TecSyntPrinter) then
    TecSyntPrinter(Result).SyntMemo := SyntMemo;
end;

constructor TecBasePrintAction.Create(AOwner: TComponent);
begin
  inherited;
  FAllowCreate := True;
end;

constructor TecPrintAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetCommand(smPrint);
end;

procedure TecBasePrintAction.DoExecute;
var prn: TecCustomPrinter;
begin
  if Assigned(SyntMemo) and (SyntMemo.ClientOfType(TecSyntPrinter) <> nil) then
    inherited else
    begin
      prn := GetPrinter;
      if prn <> nil then
        begin
          if DialogExecute(prn) then
            if Assigned(FOnExecuteOK) then FOnExecuteOK(Self);
        end;
    end;
end;

{ TecPrintAction }

function TecPrintAction.DialogExecute(APrinter: TecCustomPrinter): Boolean;
var i : Integer;
    fIntDialog : TPrintDialog;
    PrevPrinter: integer;
begin
  if not Assigned(PrintDialog) then
   begin
    fIntDialog := TPrintDialog.Create(self);
    fIntDialog.Options := [poPageNums, poWarning];
   end
  else
    fIntDialog := PrintDialog;
  try
    APrinter.UpdatePages;
    fIntDialog.MinPage := 1;
    fIntDialog.FromPage := 1;
    fIntDialog.MaxPage := SyntPrinter.PageCount;
    fIntDialog.ToPage := fIntDialog.MaxPage;
    PrevPrinter := Printer.PrinterIndex;
    Result := fIntDialog.Execute;
    if Result then
     begin
      if Printer.PrinterIndex <> PrevPrinter then
       APrinter.UpdatePages;
      for i := 1 to fIntDialog.Copies do
        APrinter.PrintPages(fIntDialog.FromPage, fIntDialog.ToPage);
      if Assigned(FOnExecuteOK) then FOnExecuteOK(Self);
     end;
  finally
    if not Assigned(PrintDialog) then fIntDialog.Free;
  end;
end;

procedure TecPrintAction.SetPrintDialog(const Value: TPrintDialog);
begin
  if FPrintDialog <> Value then
  begin
    FPrintDialog := Value;
    if FPrintDialog <> nil then
      FPrintDialog.FreeNotification(Self);
  end;
end;

procedure TecPrintAction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited;
  if (AComponent = FPrintDialog) and (Operation = opRemove) then
   FPrintDialog := nil;
end;

{ TecPreviewAction }

constructor TecPreviewAction.Create(AOwner: TComponent);
begin
  inherited;
  SetCommand(smPrintPreview);
end;

function TecPreviewAction.DialogExecute(APrinter: TecCustomPrinter): Boolean;
begin
  Preview(APrinter);
  Result := True;
end;

{ TecPageSetupAction }

constructor TecPageSetupAction.Create(AOwner: TComponent);
begin
  inherited;
  FAllowCreate := False;
  SetCommand(smPageSetup);
end;

function TecPageSetupAction.DialogExecute(
  APrinter: TecCustomPrinter): Boolean;
begin
  Result := APrinter.PageSetup;
end;

{ TecBaseBookmarkAction }

constructor TecBaseBookmarkAction.Create(AOwner: TComponent);
begin
  inherited;
  BaseCaption := 'Bookmark &%d';
  BookmarkNr := 1;
  LineColumnFormat := '(L:%d)';
end;

procedure TecBaseBookmarkAction.SetBookmarkNr(Value: Integer);
begin
  if Value <> fBookmarkNr then
  begin
    if (Caption = Format(BaseCaption, [fBookmarkNr])) or (Caption = '') then
      Caption := Format(BaseCaption, [Value]);
    fBookmarkNr := Value;
  end;
end;

procedure TecBaseBookmarkAction.SetBaseCaption(Value: string);
begin
  if Value <> fBaseCaption then
  begin
    if (Caption = Format(fBaseCaption, [fBookmarkNr])) or (Caption = '') then
      Caption := Format(Value, [fBookmarkNr]);
    fBaseCaption := Value;
  end;
end;

procedure TecBaseBookmarkAction.AssignTo(Dest: TPersistent);
begin
  if Dest is TecBaseBookmarkAction then
    with TecBaseBookmarkAction(Dest) do
    begin
      BaseCaption := Self.BaseCaption;
      BookmarkNr := Self.BookmarkNr;
    end;
  inherited AssignTo(Dest);
end;

procedure TecBaseBookmarkAction.UpdateMemo(Memo: TCustomSyntaxMemo);
var
  b: Boolean;
  s : String;
  p : TPoint;
begin
  b := Memo.Bookmarks[fBookmarkNr] <> -1;
  if (Self is TecBookmarkGotoAction) or (Self is TecBookmarkClearAction) then
    SetEnabled (b)
  else
    SetEnabled (true);
  if not (csDesigning in ComponentState) then
    if LineColumnFormat <> '' then
    BEGIN
       if b then
       begin
         p := Memo.Lines.StrToCaret(Memo.Bookmarks[fBookmarkNr]);
         {$IFDEF EC_VCL7_UP}
         if PosEx('%d', LineColumnFormat, Pos('%d', LineColumnFormat)+1)  >0  then
           s := Format(BaseCaption, [fBookmarkNr]) + ' ' +
             Format(LineColumnFormat, [p.y+1, p.x+1])
         else
         {$ENDIF}
           s := Format(BaseCaption, [fBookmarkNr]) + ' ' +
             Format(LineColumnFormat, [p.y+1]);
       end
       else
        s := Format(BaseCaption, [fBookmarkNr]);
      IF s <> Caption THEN
        Caption := s;
    END;
end;

{ TecBookmarkGotoAction }

constructor TecBookmarkGotoAction.Create(AOwner: TComponent);
begin
  inherited;
  BaseCaption := 'Goto Bookmark &%d';
end;

procedure TecBookmarkGotoAction.DoExecute;
begin
  SyntMemo.GotoBookmark(BookmarkNr);
  inherited;
end;

function TecBookmarkGotoAction.GetCommand: Integer;
begin
  if (BookmarkNr >= 0) and  (BookmarkNr <= 9) then
    Result := smGotoBookmark0 + BookmarkNr
  else
    Result := -1;
end;

{ TecBookmarkSetAction }

constructor TecBookmarkSetAction.Create(AOwner: TComponent);
begin
  inherited;
  BaseCaption := 'Set Bookmark &%d';
end;

procedure TecBookmarkSetAction.DoExecute;
begin
  SyntMemo.Bookmarks[BookmarkNr] := SyntMemo.CaretStrPos;
  inherited;
end;

{ TecBookmarkToggleAction }

constructor TecBookmarkToggleAction.Create(AOwner: TComponent);
begin
  inherited;
  BaseCaption := 'Toggle Bookmark &%d';
end;

procedure TecBookmarkToggleAction.DoExecute;
begin
  SyntMemo.ToggleBookmark(BookmarkNr);
  inherited;
end;

function TecBookmarkToggleAction.GetCommand: Integer;
begin
  if (BookmarkNr >= 0) and  (BookmarkNr <= 9) then
    Result := smSetBookmark0 + BookmarkNr
  else
    Result := -1;
end;

{ TecBookmarkClearAction }

constructor TecBookmarkClearAction.Create(AOwner: TComponent);
begin
  inherited;
  BaseCaption := 'Clear Bookmark &%d';
end;

procedure TecBookmarkClearAction.DoExecute;
begin
  SyntMemo.Bookmarks[BookmarkNr] := -1;
  inherited;
end;

{ TecBookmarkClearAllAction }

procedure TecBookmarkClearAllAction.DoExecute;
begin
  SyntMemo.ClearBookmarks;
  inherited;
end;

{ TecBaseExportAction }
constructor TecBaseExportAction.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FExportType := etAllText;
  FOptions:= [ofHideReadOnly, ofEnableSizing];
  {$IFDEF EC_VCL6_UP}
  FOptionsEx:= [];
  {$ENDIF}
  FDefaultExt:= '';
  FFilter:= '';
  FInitialDir:= '';
end;

procedure TecBaseExportAction.DoExecute;
var
  SyntExport: TPlainTextSyntExport;
  SaveDialog: TSaveDialog;
begin
  SyntExport:= CreateExportClass;
  if SyntExport is TBaseFormattedExport then
    TBaseFormattedExport(SyntExport).UseCaseFormatting := UseCaseFormatting;
  SaveDialog:= TSaveDialog.Create(self);
  try
    SaveDialog.DefaultExt:= DefaultExt;
    SaveDialog.Filter:= Filter;
    SaveDialog.InitialDir:= InitialDir;
    SaveDialog.Options:= Options;
    {$IFDEF EC_VCL6_UP}
    SaveDialog.OptionsEx:= OptionsEx;
    {$ENDIF}
    SyntExport.ExportType := ExportType;
    SyntExport.SyntMemo := SyntMemo;
    if SaveDialog.Execute then
     begin
      SyntExport.SaveToFile(SaveDialog.FileName);
      inherited;
     end;
  finally
    SyntExport.Free;
    SaveDialog.Free;
  end;
end;

{ TecExportRTFAction }
constructor TecExportRTFAction.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  DefaultExt := '.RTF';
  Filter := 'Rich text files (*.rtf)|*.rtf|All files (*.*)|*.*';
end;

function TecExportRTFAction.CreateExportClass: TPlainTextSyntExport;
begin
  Result := TPlainTextSyntExport(TRTFSyntExport.Create(self));
end;

{ TecExportHTMLAction }
constructor TecExportHTMLAction.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  DefaultExt := '.HTML';
  Filter := 'HTML files (*.htm, *.html)|*.htm;*.html|All files (*.*)|*.*';
end;

function TecExportHTMLAction.CreateExportClass: TPlainTextSyntExport;
begin
  Result := TPlainTextSyntExport(THTMLSyntExport.Create(self));
end;


{ TecToggleNonPrinted }

constructor TecToggleNonPrinted.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smToggleNonPrinted;
end;

procedure TecToggleNonPrinted.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  Checked := Memo.NonPrinted.Visible;
end;

{ TecToggleWordWrap }

constructor TecToggleWordWrap.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smToggleWordWrap;
end;


procedure TecToggleWordWrap.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  Checked := Memo.WordWrap;
end;

{ TecBaseLexerCustomize }

function TecBaseLexerCustomize.GetLinkComponent(
  Memo: TCustomSyntaxMemo): TComponent;
begin
  if Assigned(Memo) and Assigned(Memo.SyntObj) then
    Result := Memo.SyntObj.Owner
  else
    Result := nil;
end;

function TecBaseLexerCustomize.GetSyntAnalyzer: TSyntAnalyzer;
begin
  Result := TSyntAnalyzer(LinkComponent);
end;

procedure TecBaseLexerCustomize.SetSyntAnalyzer(
  const Value: TSyntAnalyzer);
begin
  LinkComponent := Value;
end;

{ TecBaseKeyMappingCustomize }

function TecBaseKeyMappingCustomize.GetKeyMapping: TSyntKeyMapping;
begin
  Result := TSyntKeyMapping(LinkComponent);
end;

function TecBaseKeyMappingCustomize.GetLinkComponent(
  Memo: TCustomSyntaxMemo): TComponent;
begin
  if Assigned(Memo) then
    Result := Memo.KeyMapping
  else
    Result := nil;
end;

procedure TecBaseKeyMappingCustomize.SetKeyMapping(
  const Value: TSyntKeyMapping);
begin
  LinkComponent := Value;
end;

{ TecBaseUserStylesCustomize }

function TecBaseUserStylesCustomize.GetLinkComponent(
  Memo: TCustomSyntaxMemo): TComponent;
begin
  if Assigned(Memo) then
    Result := Memo.UserStyles
  else
    Result := nil;
end;

function TecBaseUserStylesCustomize.GetUserStyles: TSyntStyles;
begin
  Result := TSyntStyles(FLinkComponent);
end;

procedure TecBaseUserStylesCustomize.SetUserStyles(
  const Value: TSyntStyles);
begin
  LinkComponent := Value;
end;

{ TecCustomizeEditorOptionsAction }
procedure TecCustomizeEditorOptionsAction.DoExecute;
begin
  if CustomizeSyntaxMemo(FSyntMemo) then inherited;
end;

{ TecCustomizeSyntaxHighlightingAction }

procedure TecCustomizeSyntaxHighlightingAction.DoExecute;
begin
  if Assigned(SyntAnalyzer) and SyntAnalyzer.Customize then inherited;
end;

{ TecCustomizeLexerPropertiesAction }

procedure TecCustomizeLexerPropertiesAction.DoExecute;
begin
  if Assigned(SyntAnalyzer) and SyntAnalyzer.CustomizeLexer then inherited;
end;

{ TecCustomizeKeyMappingAction }
procedure TecCustomizeKeyMappingAction.DoExecute;
begin
  if Assigned(KeyMapping) and KeyMapping.Customize then inherited;
end;

{ TecCustomizeUserStylesAction }

procedure TecCustomizeUserStylesAction.DoExecute;
begin
  if Assigned(UserStyles) and UserStyles.Customize then inherited;
end;

{ TecLexerLibCustomize }

procedure TecCustomizeLexerLib.DoExecute;
begin
  if Assigned(SyntaxManager) and SyntaxManager.Customize then inherited;
end;

function TecCustomizeLexerLib.GetSyntaxManager: TSyntaxManager;
begin
  Result := TSyntaxManager(LinkComponent);
end;

procedure TecCustomizeLexerLib.SetSyntaxManager(
  const Value: TSyntaxManager);
begin
  LinkComponent := Value;
end;

{ TecToggleSyntTreeSync }

procedure TecToggleSyntTreeSync.DoExecute;
begin
  SyntaxTree.AutoSynchronize := not SyntaxTree.AutoSynchronize;
  inherited;
end;

function TecToggleSyntTreeSync.GetSyntaxTree: TSyntaxTreeView;
begin
  Result := TSyntaxTreeView(LinkComponent);
end;

procedure TecToggleSyntTreeSync.SetSyntaxTree(
  const Value: TSyntaxTreeView);
begin
  LinkComponent := Value;
end;

function TecToggleSyntTreeSync.Update: Boolean;
begin
  Result := inherited Update;
  Checked := Enabled and SyntaxTree.AutoSynchronize;
end;

{ TecCustomizeAuotReplace }

procedure TecCustomizeAutoReplace.DoExecute;
begin
  if Assigned(AutoReplace) and CustomizeAutoReplace(AutoReplace) then inherited;
end;

function TecCustomizeAutoReplace.GetAutoReplace: TSyntAutoReplace;
begin
  Result := TSyntAutoReplace(LinkComponent)
end;

procedure TecCustomizeAutoReplace.SetAutoReplace(
  const Value: TSyntAutoReplace);
begin
  LinkComponent := Value;
end;

{ TecSyncEditMode }

procedure TecSyncEditMode.DoExecute;
var idx: integer;
begin
  inherited;
  with SyntMemo do
    if SelLength > 0 then SyncEditing.AddCurSelection else
     begin
       idx := SyncEditing.SyncRangeAt(CaretStrPos);
       if idx <> -1 then
         SyncEditing.Delete(idx);
     end;
end;

procedure TecSyncEditMode.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  with Memo do
    Self.SetEnabled(SyncEditing.Enabled and
      ((SelLength > 0) or (SyncEditing.SyncRangeAt(CaretStrPos) <> -1)));
  Checked := Enabled and (Memo.SelLength = 0);
end;

{ TecUnCommentLines }

constructor TecUnCommentLines.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smUncommentLines;
end;

{ TecCommentLines }

constructor TecCommentLines.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smCommentLines;
end;

{ TecInSelCollapse }

constructor TecInSelCollapse.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smInSelCollapse;
end;

{ TecInSelExpand }

constructor TecInSelExpand.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smInSelExpand;
end;

{ TecMacroStop }

constructor TecToggleFolding.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smToggleFolding;
end;

procedure TecToggleFolding.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  Checked := not Memo.DisableFolding;
end;

{ TecMacroPlay }

constructor TecMacroPlay.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smMacroPlay;
end;

{ TecMacroRecord }

constructor TecMacroRecord.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smMacroRecStart;
end;

{ TecMacroStop }

constructor TecMacroStop.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smMacroRecStop;
end;

{ TecMacroCancel }

constructor TecMacroCancel.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smMacroRecCancel;
end;

{ TecSortAscending }

constructor TecSortAscending.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smSortAscending;
end;

{ TecSortDescending }

constructor TecSortDescending.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smSortDescending;
end;

{ TecGotoLine }

constructor TecGotoLine.Create(AOwner: TComponent);
begin
  inherited;
  FCommand := smGotoLine;
end;

constructor TecSyntMemoAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMustBeSelected := False;
end;

{ TecSyntMemoAction }

procedure TecSyntMemoAction.DoExecute;
begin
  if Assigned(FOnExecuteTarget) then FOnExecuteTarget(Self, FSyntMemo);
end;

procedure TecSyntMemoAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled(Assigned(GetLinkComponent(Memo)) and (not MustBeSelected or Memo.HaveSelection));
end;

{ TecMacroStop }

constructor TecToggleLineNumbersVisible.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCommand := smToggleLineNumbersVisible;
end;

procedure TecToggleLineNumbersVisible.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  Checked := Memo.LineNumbers.Visible;
end;

{ TecBaseMultiReplaceAction }

procedure TecBaseMultiReplaceAction.Notification(AComponent: TComponent;
    Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FMultiReplace) then
    FMultiReplace:= nil;
end;

procedure TecBaseMultiReplaceAction.SetMultiReplace(const Value:
    TecMultiReplace);
begin
  if FMultiReplace <> Value then
   begin
    FMultiReplace := Value;
    if FMultiReplace <> nil then
     FMultiReplace.FreeNotification(Self);
   end;
end;

procedure TecBaseMultiReplaceAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled(Assigned(Memo) and Assigned(MultiReplace));
end;

{ TecMacroStop }

constructor TecMultiReplaceItemAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FItemIndex := -1;
end;

{ TecMultiReplaceItemAction }

procedure TecMultiReplaceItemAction.DoExecute;
begin
  if Assigned(SyntMemo) and Assigned(MultiReplace) and
     (ItemIndex >= 0) and (ItemIndex < MultiReplace.Items.Count)  then
    MultiReplace.Items[ItemIndex].Execute(SyntMemo);
end;

procedure TecMultiReplaceItemAction.SetCaptionHint;
begin
  if Assigned(MultiReplace) and
     (ItemIndex >= 0) and (ItemIndex < MultiReplace.Items.Count)  then
  begin
    Caption := MultiReplace.Items[ItemIndex].DisplayName;
    ShortCut := MultiReplace.Items[ItemIndex].ShortCut;
    Hint := MultiReplace.Items[ItemIndex].Notes.Text;
  end
  else
  begin
    Caption := '';
    Hint := '';
    ShortCut := 0;
  end;
end;

procedure TecMultiReplaceItemAction.SetItemIndex(const Value: Integer);
begin
  FItemIndex := Value;
  SetCaptionHint;
end;

procedure TecMultiReplaceItemAction.SetMultiReplace(const Value:
    TecMultiReplace);
begin
  Inherited SetMultiReplace(Value);
  SetCaptionHint;
end;

procedure TecMultiReplaceItemAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled(Assigned(Memo) and Assigned(MultiReplace) and
    (ItemIndex >= 0) and (ItemIndex < MultiReplace.Items.Count) and
    MultiReplace.Items[ItemIndex].IsEnabled(Memo));
end;

{ TecMultiReplaceCustomizeAction }

procedure TecMultiReplaceCustomizeAction.DoExecute;
begin
  if Assigned(MultiReplace) then
    MultiReplace.Customize;
end;

{ TecMultiReplaceSelectExecuteAction }

procedure TecMultiReplaceSelectExecuteAction.DoExecute;
begin
  if Assigned(MultiReplace) and Assigned(SyntMemo) then
    MultiReplace.SelectExecute(SyntMemo);
end;

{ TecBaseFormattingAction }

procedure TecBaseFormattingAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled(Assigned(Memo) and Memo.SelAttributes.CanFormat);
  if Enabled then
    inherited;
end;

{ TecFormattingBold }

procedure TecFormattingBold.DoExecute;
begin
  SyntMemo.SelAttributes.Bold := not SyntMemo.SelAttributes.Bold;
  inherited;
end;

procedure TecFormattingBold.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.Bold;
end;

{ TecFormattingItalic }

procedure TecFormattingItalic.DoExecute;
begin
  SyntMemo.SelAttributes.Italic := not SyntMemo.SelAttributes.Italic;
  inherited;
end;

procedure TecFormattingItalic.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.Italic;
end;

{ TecFormattingUnderline }

procedure TecFormattingUnderline.DoExecute;
begin
  SyntMemo.SelAttributes.Underline := not SyntMemo.SelAttributes.Underline;
  inherited;
end;

procedure TecFormattingUnderline.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.Underline;
end;

{ TecFormattingStrikeout }

procedure TecFormattingStrikeout.DoExecute;
begin
  SyntMemo.SelAttributes.StrikeOut := not SyntMemo.SelAttributes.StrikeOut;
  inherited;
end;

procedure TecFormattingStrikeout.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.StrikeOut;
end;

{ TecFormattingClearSel }

procedure TecFormattingClearSel.DoExecute;
begin
  SyntMemo.SelAttributes.ClearSelFormat;
  inherited;
end;

{ TecFormattingClearAll }

procedure TecFormattingClearAll.DoExecute;
begin
  SyntMemo.SelAttributes.ClearFormat;
  inherited;
end;

{ TecFormattingHidden }

procedure TecFormattingHidden.DoExecute;
begin
  SyntMemo.SelAttributes.Hidden := not SyntMemo.SelAttributes.Hidden;
  inherited;
end;

procedure TecFormattingHidden.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.Hidden;
end;

{ TecFormattingReadOnly }

procedure TecFormattingReadOnly.DoExecute;
begin
  SyntMemo.SelAttributes.ReadOnly := not SyntMemo.SelAttributes.ReadOnly;
  inherited;
end;

procedure TecFormattingReadOnly.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  inherited;
  if Enabled then
    Checked := Memo.SelAttributes.ReadOnly;
end;

{ TecEnableFormattingAction }

procedure TecEnableFormattingAction.DoExecute;
begin
  SyntMemo.SelAttributes.Enabled := not SyntMemo.SelAttributes.Enabled;
  inherited;
end;

procedure TecEnableFormattingAction.UpdateMemo(Memo: TCustomSyntaxMemo);
begin
  SetEnabled(Assigned(Memo));
  if Enabled then
    begin
      SetChecked(Memo.SelAttributes.Enabled);
      inherited;
    end;
end;

initialization

finalization
  FreeAndNil(GlobalFindDialog);
  FreeAndNil(GlobalReplaceDialog);
  FreeAndNil(GlobalPrintDialog);

end.
