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

unit ecSyntCEreg;

interface

procedure Register;

implementation

uses Windows, Classes, Controls, Forms, SysUtils, ComCtrls,
{$IFDEF EC_DOTNET}
     Borland.Vcl.Design.DesignEditors, Borland.Vcl.Design.DesignIntf,
     Borland.Vcl.Design.VCLEditors,
{$ELSE}
     ToolsApi,
  {$IFDEF EC_VCL6_UP}
     DesignEditors, DesignIntf, VCLEditors,
  {$ELSE}
     DsgnIntf,
  {$ENDIF}
{$ENDIF}
     ecSyntAnal, ecSyntMemo, ecKeyMap, ecCustEditDlg, ecActns, ecLinesEditor,
     ecPopupCtrl, ecCodeTemplListDlg, ecAutoReplace, ecAutoReplDlg, ecMacroRec,
     ecPropManager, ecPropListDlg, ecSpell, ecPrint, ecMultRepl,
     ecSysUtils, ecsnStyleEdit, TypInfo;

type

  TSyntAnalyzerEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntManagerEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntMemoEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntStylesEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TTemplatePopupEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntStyleProperty = class(TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
  end;

  TBlockNameProperty = class(TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
  end;

  TSyntKeyMapEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TecMultiReplaceEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntActionCommandProperty = class(TOrdinalProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    function GetValue: string; override;
    procedure GetValues(Proc: TGetStrProc); override;
    procedure SetValue(const Value: string); override;
  end;

  TSyntLinesProperty = class(TClassProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure Edit; override;
  end;

  TSyntAutoReplaceEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TPropsManagerEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntPrinterEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TMacroRecorderEditor = class(TComponentEditor)
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

  TSyntaxFormatProperty = class(TClassProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure Edit; override;
  end;

  TPopupControlCtlEditor = class(TComponentProperty)
  private
  {$IFDEF EC_VCL5}
    function GetComponentReference: TComponent;
  public
    procedure GetProperties(Proc: TGetPropEditProc); override;
  {$ENDIF}
  public
    procedure Edit; override;
    function GetAttributes: TPropertyAttributes; override;
    function GetValue: string; override;
    procedure GetValues(Proc: TGetStrProc); override;
    procedure SetValue(const Value: string); override;
  end;

function EditMemoText(Memo: TCustomSyntaxMemo): Boolean;
var Dlg: TSyntEditMain;
begin
  Dlg := TSyntEditMain.Create(nil);
  try
    Dlg.SyntaxMemo1.Lines := Memo.Lines;
    Dlg.SyntaxMemo1.UserStyles := Memo.UserStyles;
    Dlg.SyntaxMemo1.KeyMapping := Memo.KeyMapping;
    Dlg.SyntaxMemo1.SyntaxAnalyzer := Memo.SyntaxAnalyzer;
    Dlg.SyntaxMemo1.UserRanges := Memo.UserRanges;
    Dlg.SyntaxMemo1.Modified := False;
    Dlg.SyntaxMemo1.TabMode := Memo.TabMode;
    Dlg.Caption := Memo.Name;
    Result := Dlg.ShowModal = mrOk;
    if Result then
     begin
       Memo.Lines := Dlg.SyntaxMemo1.Lines;
       Memo.UserRanges := Dlg.SyntaxMemo1.UserRanges;
     end;
  finally
    Dlg.Free;
  end;
end;

{ TSyntAnalyzerEditor }

procedure TSyntAnalyzerEditor.ExecuteVerb(Index: Integer);
begin
  case Index of
    0: if (Component as TSyntAnalyzer).CustomizeLexer  then
          Designer.Modified;
    1: if (Component as TSyntAnalyzer).Customize  then
          Designer.Modified;
  end;
end;

function TSyntAnalyzerEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := 'Lexer proprties ...';
    1: Result := 'Styles ...';
  end;
end;

function TSyntAnalyzerEditor.GetVerbCount: Integer;
begin
  Result := 2;
end;

{ TSyntManagerEditor }

procedure TSyntManagerEditor.ExecuteVerb(Index: Integer);
begin
  if (Component as TSyntaxManager).Customize then
   Designer.Modified;
end;

function TSyntManagerEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Customize...';
end;

function TSyntManagerEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TSyntMemoEditor }

procedure TSyntMemoEditor.ExecuteVerb(Index: Integer);
begin
  case Index of
    0: if CustomizeSyntaxMemo(Component as TCustomSyntaxMemo) then
         Designer.Modified;
    1: if EditMemoText(Component as TCustomSyntaxMemo) then
         Designer.Modified;
  end;
end;

function TSyntMemoEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := 'Customize...';
    1: Result := 'Edit text...';
  end;
end;

function TSyntMemoEditor.GetVerbCount: Integer;
begin
  Result := 2;
end;

{ TSyntStylesEditor }

procedure TSyntStylesEditor.ExecuteVerb(Index: Integer);
begin
  if (Component as TSyntStyles).Customize then
   Designer.Modified;
end;

function TSyntStylesEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Customize...';
end;

function TSyntStylesEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TTemplatePopupEditor }

procedure TTemplatePopupEditor.ExecuteVerb(Index: Integer);
var Lexer: TSyntAnalyzer;
begin
  with Component as TTemplatePopup do
   begin
    if SyntMemo <> nil then
     Lexer := SyntMemo.SyntaxAnalyzer
    else
     Lexer := nil;
    EditTemplates(Templates, Lexer);
   end;
end;

function TTemplatePopupEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Edit templates...';
end;

function TTemplatePopupEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TSyntStyleProperty }

function TSyntStyleProperty.GetAttributes: TPropertyAttributes;
begin
  Result := inherited GetAttributes;
  Include(Result, paValueList);
end;

procedure TSyntStyleProperty.GetValues(Proc: TGetStrProc);
var obj: TPersistent;
    FSynt: TSyntAnalyzer;
    i: integer;
begin
  obj := GetComponent(0);
  if obj is TSyntAnalyzer then
    FSynt := obj as TSyntAnalyzer
  else
  if obj is TRuleCollectionItem then
   FSynt := ((obj as TRuleCollectionItem).Collection as TSyntCollection).SyntOwner
  else
   Exit;

  for i := 0 to FSynt.Formats.Count - 1 do
    Proc(FSynt.Formats[i].DisplayName);
end;

{ TBlockNameProperty }

function TBlockNameProperty.GetAttributes: TPropertyAttributes;
begin
  Result := inherited GetAttributes;
  Include(Result, paValueList);
end;

procedure TBlockNameProperty.GetValues(Proc: TGetStrProc);
var obj: TPersistent;
    FSynt: TSyntAnalyzer;
    i: integer;
begin
  obj := GetComponent(0);
  if obj is TRuleCollectionItem then
   FSynt := ((obj as TRuleCollectionItem).Collection as TSyntCollection).SyntOwner
  else
   Exit;

  for i := 0 to FSynt.BlockRules.Count - 1 do
    Proc(FSynt.BlockRules[i].DisplayName);
end;

{ TSyntKeyMapEditor }

procedure TSyntKeyMapEditor.ExecuteVerb(Index: Integer);
begin
  case Index of
    0: if (Component as TSyntKeyMapping).Customize then
         Designer.Modified;
    else
      begin
         (Component as TSyntKeyMapping).Items.Clear;
         InitDefaultKeyMapping((Component as TSyntKeyMapping));
         Designer.Modified;
       end;
  end;
end;

function TSyntKeyMapEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0:   Result := 'Customize...';
    else Result := 'Load Default';
  end;
end;

function TSyntKeyMapEditor.GetVerbCount: Integer;
begin
  Result := 2;
end;

{ TSyntActionCommandProperty }

function TSyntActionCommandProperty.GetAttributes: TPropertyAttributes;
begin
  Result := [paMultiSelect, paValueList, paRevertable];
end;

function TSyntActionCommandProperty.GetValue: string;
var cmd: TecCommandItem;
    L: Longint;
begin
  L := GetOrdValue;
  cmd := DefaultKeyMapping.CommandByID(L);
  if cmd <> nil then Result := RemoveAmpersand(cmd.Caption)
    else Result := '<= Not assigned =>';
end;

procedure TSyntActionCommandProperty.GetValues(Proc: TGetStrProc);
var i: integer;
begin
  with DefaultKeyMapping.Items do
  for i := 0 to Count - 1 do
   if Items[i].Caption <> '' then
    Proc(RemoveAmpersand(Items[i].Caption));
end;

procedure TSyntActionCommandProperty.SetValue(const Value: string);
var i, j: integer;
begin
  // for integer input
  try
    i := StrToInt(Value);
    if (GetOrdValue <> i) and (DefaultKeyMapping.CommandByID(i) <> nil) then
      for j := 0 to PropCount - 1 do
       (GetComponent(j) as TecCustomCommandAction).SetCommand(i);
    Exit;
  except
  end;
  // for selecting string
  with DefaultKeyMapping.Items do
  for i := 0 to Count - 1 do
   if RemoveAmpersand(Items[i].Caption) = Value then
    begin
     if GetOrdValue <> Items[i].Command then
      for j := 0 to PropCount - 1 do
       (GetComponent(j) as TecCustomCommandAction).SetCommand(Items[i].Command);
     Exit;
    end;
end;

{ TSyntLinesProperty }

procedure TSyntLinesProperty.Edit;
var cmp: TComponent;
begin
  cmp := TComponent(GetComponent(0));
  if (cmp is TCustomSyntaxMemo) and EditMemoText(cmp as TCustomSyntaxMemo) then
    Designer.Modified;
end;

function TSyntLinesProperty.GetAttributes: TPropertyAttributes;
begin
  Result := inherited GetAttributes + [paDialog] - [paSubProperties];
end;

{ TSyntAutoReplaceEditor }

procedure TSyntAutoReplaceEditor.ExecuteVerb(Index: Integer);
begin
  if CustomizeAutoReplace(Component as TSyntAutoReplace) then
   Designer.Modified;
end;

function TSyntAutoReplaceEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Customize...';
end;

function TSyntAutoReplaceEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TPropsManagerEditor }

procedure TPropsManagerEditor.ExecuteVerb(Index: Integer);
begin
  with Component as TPropsManager do
    if EditPropertyList(Properties, Owner, Template) then
     Designer.Modified;
end;

function TPropsManagerEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Edit property list';
end;

function TPropsManagerEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TSyntPrinterEditor }

procedure TSyntPrinterEditor.ExecuteVerb(Index: Integer);
begin
  if TecCustomPrinter(Component).PageSetup then
    Designer.Modified;
end;

function TSyntPrinterEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Page Setup ...';
end;

function TSyntPrinterEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TMacroRecorderEditor }

procedure TMacroRecorderEditor.ExecuteVerb(Index: Integer);
begin
  if TecMacroRecorder(Component).Customize then
    Designer.Modified;
end;

function TMacroRecorderEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Edit Macros ...';
end;

function TMacroRecorderEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TecMultiReplaceEditor }

procedure TecMultiReplaceEditor.ExecuteVerb(Index: Integer);
begin
  if TecMultiReplace(Component).Customize then
    Designer.Modified;
end;

function TecMultiReplaceEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Edit...'
end;

function TecMultiReplaceEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

{ TSyntaxFormatProperty }

procedure TSyntaxFormatProperty.Edit;
var obj: TSyntaxFormat;
    frm: TSyntStyleFrame;
    i: integer;
begin
  Obj := TSyntaxFormat.Create(nil);
  try
    {$IFDEF EC_DOTNET}
    Obj.Assign(TPersistent(GetObjValueAt(0)));
    frm := TSyntStyleFrame.Create(nil);
    frm.Style := Obj;
    if ShowDialogFromFrame(frm, 'Property ' + GetName) = mrOK then
      for i := 0 to PropCount - 1 do
        TPersistent(GetObjValueAt(0)).Assign(Obj);
    {$ELSE}
    Obj.Assign(TPersistent(GetOrdValueAt(0)));
    frm := TSyntStyleFrame.Create(nil);
    frm.Style := Obj;
    if ShowDialogFromFrame(frm, 'Property ' + GetName) = mrOK then
      for i := 0 to PropCount - 1 do
        TPersistent(GetOrdValueAt(0)).Assign(Obj);
    {$ENDIF}
  finally
    Obj.Free;
  end;
end;

function TSyntaxFormatProperty.GetAttributes: TPropertyAttributes;
begin
  Result := (inherited GetAttributes) + [paDialog];
end;

{ TPopupControlCtlEditor }

procedure TPopupControlCtlEditor.Edit;
begin
end;

function TPopupControlCtlEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paMultiSelect, paValueList{, paSortList}];
  if {$IFNDEF EC_VCL5}GReferenceExpandable and {$ENDIF}(GetComponentReference <> nil) and AllEqual then
    Result := Result + [paSubProperties{$IFNDEF EC_VCL5}, paVolatileSubProperties{$ENDIF}];
end;

{$IFDEF EC_VCL5}
function TPopupControlCtlEditor.GetComponentReference: TComponent;
begin
  Result := TComponent(GetOrdValue);
end;

procedure TPopupControlCtlEditor.GetProperties(Proc: TGetPropEditProc);
var
  Sel: TDesignerSelectionList;
begin
  if GetComponentReference <> nil then
  begin
    Sel := TDesignerSelectionList.Create;
    Sel.Add(GetComponentReference);
    GetComponentProperties(Sel, tkProperties, Designer, Proc);
    Sel.Free;
  end;
end;
{$ENDIF}

function TPopupControlCtlEditor.GetValue: string;
begin
  if GetComponentReference <> nil then
    Result := GetComponentReference.ClassName
  else
    Result := '[None]';
end;

procedure TPopupControlCtlEditor.GetValues(Proc: TGetStrProc);
var i: integer;
begin
  Proc('[None]');
  if Assigned(PopupControlClasses) then
    for i := 0 to PopupControlClasses.Count - 1 do
      Proc(TControlClass(PopupControlClasses[i]).ClassName);
end;

procedure TPopupControlCtlEditor.SetValue(const Value: string);
var i: integer;
begin
  if not SameText(Value, GetValue) then
    begin
      for i := PropCount - 1 downto 0 do
        (GetComponent(i) as TecControlItem).ControlClass := Value;
      Designer.Modified;
    end;
end;

procedure Register;
begin
  RegisterComponentEditor(TSyntaxMemo, TSyntMemoEditor);
  RegisterComponentEditor(TSyntAnalyzer, TSyntAnalyzerEditor);
  RegisterComponentEditor(TSyntaxManager, TSyntManagerEditor);
  RegisterComponentEditor(TSyntKeyMapping, TSyntKeyMapEditor);
  RegisterComponentEditor(TSyntStyles, TSyntStylesEditor);
  RegisterComponentEditor(TTemplatePopup, TTemplatePopupEditor);
  RegisterComponentEditor(TSyntAutoReplace, TSyntAutoReplaceEditor);
  RegisterComponentEditor(TPropsManager, TPropsManagerEditor);
  RegisterComponentEditor(TecCustomPrinter, TSyntPrinterEditor);
  RegisterComponentEditor(TecMacroRecorder, TMacroRecorderEditor);
  RegisterComponentEditor(TecMultiReplace, TecMultiReplaceEditor);
  RegisterPropertyEditor(TypeInfo(string), TSyntAnalyzer, 'MarkedBlockStyle', TSyntStyleProperty);
  RegisterPropertyEditor(TypeInfo(string), TRuleCollectionItem, 'StyleName', TSyntStyleProperty);
  RegisterPropertyEditor(TypeInfo(string), TRuleCollectionItem, 'BlockName', TBlockNameProperty);
  RegisterPropertyEditor(TypeInfo(string), TTagBlockCondition, 'BlockEnd', TBlockNameProperty);
  RegisterPropertyEditor(TypeInfo(integer), TecCustomCommandAction, 'Command', TSyntActionCommandProperty);
  RegisterPropertyEditor(TypeInfo(TStrings), TCustomSyntaxMemo, 'Lines', TSyntLinesProperty);
  RegisterPropertyEditor(TypeInfo(TShortCut), TSyntMemoPopup, 'ShortCut', TShortCutProperty);
  RegisterPropertyEditor(TypeInfo(TSyntaxFormat), nil, '', TSyntaxFormatProperty);
  RegisterPropertyEditor(TypeInfo(string), TSyntKeyMapping, 'AsString', nil);
  RegisterPropertyEditor(TypeInfo(string), TecControlItem, 'ControlClass', nil);
  RegisterPropertyEditor(TypeInfo(TControl), TecControlItem, 'Control', TPopupControlCtlEditor);
end;

end.
